Compare commits

..

9 Commits

Author SHA1 Message Date
github-actions[bot]
6a01bdbcc9 chore: update versions (6-next) (#2231)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2021-05-07 07:41:38 +02:00
Leonardo Metzger
5ddfa5264c fix: fix the exact search phrase (#2225)
* fix: Fix the exact search phrase

* fix: Add changeset to fix of exact search phrase

Co-authored-by: Juan Picado <juanpicado19@gmail.com>
2021-05-07 06:43:29 +02:00
Vitaly Baev
1cc00cf2ab Fixed broken link (#2232) 2021-05-06 18:34:17 +02:00
github-actions[bot]
086c4a7c3c chore: update versions (6-next) (#2229)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2021-05-06 08:37:13 +02:00
Omri Bar-Zik
babe5c3f6c docs: Fix README.md install command (#2230) 2021-05-06 08:37:00 +02:00
Juan Picado
0da7031e77 feat: allow disable login on ui (#2228) 2021-05-05 23:23:03 +02:00
Juan Picado
393125baa1 chore: remove snapshots 2021-05-05 22:51:49 +02:00
github-actions[bot]
7fb5c45243 chore: update versions (6-next) (#2227)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2021-05-05 21:16:22 +02:00
Juan Picado
aecbd226de feat: allow ui hide package managers on sidebar (#2226)
* feat: allow ui hide package managers on sidebar

* add test

* add changeset

* chore: remove snapshot

* chore: update config
2021-05-04 21:15:07 +02:00
77 changed files with 747 additions and 1553 deletions

View File

@@ -0,0 +1,15 @@
---
'@verdaccio/types': minor
'@verdaccio/ui-theme': minor
'@verdaccio/web': minor
---
allow disable login on ui and endpoints
To be able disable the login, set `login: false`, anything else would enable login. This flag will disable access via UI and web endpoints.
```yml
web:
title: verdaccio
login: false
```

View File

@@ -43,6 +43,7 @@
"@verdaccio/fastify-migration": "6.0.0-6-next.9"
},
"changesets": [
"afraid-mice-obey",
"big-lobsters-sin",
"few-cooks-destroy",
"fifty-jars-rest",
@@ -61,11 +62,13 @@
"plenty-spiders-melt",
"plenty-tables-refuse",
"pretty-hounds-tap",
"red-chefs-float",
"shiny-chefs-heal",
"smart-apricots-kneel",
"spicy-frogs-press",
"tender-bags-call",
"three-pots-sit",
"two-dolls-check"
"two-dolls-check",
"wild-jokes-beam"
]
}

View File

@@ -0,0 +1,12 @@
---
'@verdaccio/store': patch
'@verdaccio/web': patch
---
Fix the search by exact name of the package
Full package name queries was not finding anithing. It was happening
becouse of stemmer of [lunr.js](https://lunrjs.com/).
To fix this, the stemmer of [lunr.js](https://lunrjs.com/) was removed from search pipeline.

View File

@@ -0,0 +1,32 @@
---
'@verdaccio/types': minor
'@verdaccio/ui-theme': minor
'@verdaccio/web': minor
---
web: allow ui hide package managers on sidebar
If there is a package manager of preference over others, you can define the package managers to be displayed on the detail page and sidebar, just define in the `config.yaml` and web section the list of package managers to be displayed.
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
- pnpm
- yarn
# - npm
```
To disable all package managers, just define empty:
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
```
and the section would be hidden.

View File

@@ -32,7 +32,7 @@ Google Cloud Storage** or create your own plugin.
Install with npm:
```bash
npm install --global verdaccio@6-next --https://registry.verdaccio.org/
npm install --global verdaccio@6-next --registry https://registry.verdaccio.org/
```
> Published on a temporary registry while setup is ready to publish on npmjs

View File

@@ -2,4 +2,4 @@
> Before run examples, build the local image by running `pnpm docker`.
- [Docker + Nginx + Verdaccio](v5/reverse_proxy/nginx/README.md)
- [Docker + Nginx + Verdaccio](reverse_proxy/nginx/README.md)

View File

@@ -1,5 +1,12 @@
# @verdaccio/api
## 6.0.0-6-next.11
### Patch Changes
- Updated dependencies [5ddfa526]
- @verdaccio/store@6.0.0-6-next.9
## 6.0.0-6-next.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/api",
"version": "6.0.0-6-next.10",
"version": "6.0.0-6-next.11",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -45,7 +45,7 @@
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.9",
"@verdaccio/tarball": "workspace:11.0.0-6-next.5",
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
"cookies": "0.8.0",
@@ -56,8 +56,8 @@
"semver": "7.3.2"
},
"devDependencies": {
"@verdaccio/server": "workspace:6.0.0-6-next.12",
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/server": "workspace:6.0.0-6-next.15",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"body-parser": "1.19.0",
"lodash": "^4.17.20",
"supertest": "next"

View File

@@ -52,7 +52,7 @@
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,27 @@
# @verdaccio/cli
## 6.0.0-6-next.16
### Patch Changes
- @verdaccio/node-api@6.0.0-6-next.16
## 6.0.0-6-next.15
### Patch Changes
- @verdaccio/fastify-migration@6.0.0-6-next.9
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/node-api@6.0.0-6-next.15
## 6.0.0-6-next.14
### Patch Changes
- @verdaccio/fastify-migration@6.0.0-6-next.9
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/node-api@6.0.0-6-next.14
## 6.0.0-6-next.13
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/cli",
"version": "6.0.0-6-next.13",
"version": "6.0.0-6-next.16",
"author": {
"name": "Juan Picado",
"email": "juanpicado19@gmail.com"
@@ -45,7 +45,7 @@
"dependencies": {
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/node-api": "workspace:6.0.0-6-next.13",
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.9",
"commander": "6.2.0",
"clipanion": "3.0.0-rc.11",

View File

@@ -40,7 +40,7 @@
"lockfile": "1.0.4"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -43,7 +43,7 @@
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"mockdate": "^3.0.2"
},
"scripts": {

View File

@@ -47,7 +47,7 @@
},
"devDependencies": {
"@types/minimatch": "^3.0.3",
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"minimatch": "^3.0.4",
"rmdir-sync": "^1.0.1"
},

View File

@@ -45,7 +45,7 @@
"marked": "1.1.1"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -37,7 +37,7 @@
"fastify": "3.14.2"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -34,7 +34,7 @@
"access": "public"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -41,7 +41,7 @@
"@verdaccio/utils": "workspace:6.0.0-6-next.4"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"express": "^4.17.1",
"node-mocks-http": "^1.10.1"
},

View File

@@ -1,5 +1,50 @@
# Change Log
## 11.0.0-6-next.7
### Minor Changes
- 0da7031e: allow disable login on ui and endpoints
To be able disable the login, set `login: false`, anything else would enable login. This flag will disable access via UI and web endpoints.
```yml
web:
title: verdaccio
login: false
```
## 11.0.0-6-next.6
### Minor Changes
- aecbd226: web: allow ui hide package managers on sidebar
If there is a package manager of preference over others, you can define the package managers to be displayed on the detail page and sidebar, just define in the `config.yaml` and web section the list of package managers to be displayed.
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
- pnpm
- yarn
# - npm
```
To disable all package managers, just define empty:
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
```
and the section would be hidden.
## 11.0.0-6-next.5
### Patch Changes

View File

@@ -15,6 +15,51 @@ declare module '@verdaccio/types' {
url?: string;
}
type PackageManagers = 'pnpm' | 'yarn' | 'npm';
// FUTURE: WebConf and TemplateUIOptions should be merged .
type CommonWebConf = {
title?: string;
logo?: string;
favicon?: string;
gravatar?: boolean;
sort_packages?: string;
darkMode?: boolean;
url_prefix?: string;
language?: string;
login?: boolean;
scope?: string;
pkgManagers?: PackageManagers[];
};
/**
* Options are passed to the index.html
*/
export type TemplateUIOptions = {
uri?: string;
darkMode?: boolean;
protocol?: string;
host?: string;
base: string;
primaryColor?: string;
version?: string;
logoURI?: string;
} & CommonWebConf;
/**
* Options on config.yaml for web
*/
type WebConf = {
// FIXME: rename to primaryColor and move it to CommonWebConf
primary_color?: string;
enable?: boolean;
scriptsHead?: string[];
scriptsBodyAfter?: string[];
metaScripts?: string[];
bodyBefore?: string[];
bodyAfter?: string[];
} & CommonWebConf;
interface Dist {
integrity?: string;
shasum: string;
@@ -276,23 +321,6 @@ declare module '@verdaccio/types' {
interface ListenAddress {
[key: string]: string;
}
interface WebConf {
enable?: boolean;
title?: string;
logo?: string;
favicon?: string;
gravatar?: boolean;
sort_packages?: string;
scriptsHead?: string[];
scriptsBodyAfter?: string[];
metaScripts?: string[];
bodyBefore?: string[];
bodyAfter?: string[];
darkMode?: boolean;
primary_color?: string;
}
interface HttpsConfKeyCert {
key: string;
cert: string;

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/types",
"version": "11.0.0-6-next.5",
"version": "11.0.0-6-next.7",
"description": "verdaccio types definitions",
"keywords": [
"private",

View File

@@ -41,7 +41,7 @@
},
"devDependencies": {
"node-mocks-http": "^1.10.1",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -41,7 +41,7 @@
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"nock": "^13.0.4"
},
"scripts": {

View File

@@ -21,7 +21,7 @@
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"homepage": "https://verdaccio.org",
"keywords": [

View File

@@ -46,7 +46,7 @@
},
"devDependencies": {
"@types/pino": "^6.3.3",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"funding": {
"type": "opencollective",

View File

@@ -49,7 +49,7 @@
"supertest": "^4.0.2"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,25 @@
# @verdaccio/node-api
## 6.0.0-6-next.16
### Patch Changes
- @verdaccio/server@6.0.0-6-next.15
## 6.0.0-6-next.15
### Patch Changes
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/server@6.0.0-6-next.14
## 6.0.0-6-next.14
### Patch Changes
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/server@6.0.0-6-next.13
## 6.0.0-6-next.13
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/node-api",
"version": "6.0.0-6-next.13",
"version": "6.0.0-6-next.16",
"description": "node API",
"main": "build/index.js",
"types": "build/index.d.ts",
@@ -41,7 +41,7 @@
"dependencies": {
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/server": "workspace:6.0.0-6-next.12",
"@verdaccio/server": "workspace:6.0.0-6-next.15",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"core-js": "^3.6.5",
"debug": "^4.2.0",
@@ -49,7 +49,7 @@
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"jest-mock-process": "^1.4.0",
"selfsigned": "1.10.7",
"supertest": "^6.1.3"

View File

@@ -39,7 +39,7 @@
},
"devDependencies": {
"@types/activedirectory2": "^1.2.1",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -36,7 +36,7 @@
"node-fetch": "^2.6.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"body-parser": "^1.19.0",
"nock": "^12.0.3",
"supertest": "^4.0.2"

View File

@@ -35,7 +35,7 @@
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -36,7 +36,7 @@
"aws-sdk": "^2.607.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"recursive-readdir": "2.2.2"
},
"scripts": {

View File

@@ -37,7 +37,7 @@
"@verdaccio/streams": "workspace:11.0.0-alpha.3"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"memory-fs": "0.5.0"
},
"optionalDependencies": {

View File

@@ -38,7 +38,7 @@
"memfs": "3.2.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"scripts": {
"clean": "rimraf ./build",

View File

@@ -1,5 +1,50 @@
# @verdaccio/ui-theme
## 6.0.0-6-next.8
### Minor Changes
- 0da7031e: allow disable login on ui and endpoints
To be able disable the login, set `login: false`, anything else would enable login. This flag will disable access via UI and web endpoints.
```yml
web:
title: verdaccio
login: false
```
## 6.0.0-6-next.7
### Minor Changes
- aecbd226: web: allow ui hide package managers on sidebar
If there is a package manager of preference over others, you can define the package managers to be displayed on the detail page and sidebar, just define in the `config.yaml` and web section the list of package managers to be displayed.
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
- pnpm
- yarn
# - npm
```
To disable all package managers, just define empty:
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
```
and the section would be hidden.
## 6.0.0-6-next.6
### Patch Changes

View File

@@ -15,6 +15,7 @@ global.__VERDACCIO_BASENAME_UI_OPTIONS = {
darkMode: false,
language: 'en-US',
uri: 'http://localhost:4873',
pkgManagers: ['pnpm', 'yarn', 'npm'],
title: 'Verdaccio Dev UI',
scope: '',
version: 'v1.0.0',

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/ui-theme",
"version": "6.0.0-6-next.6",
"version": "6.0.0-6-next.8",
"description": "Verdaccio User Interface",
"author": {
"name": "Verdaccio Core Team",
@@ -29,7 +29,7 @@
"@testing-library/dom": "^7.29.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "10.4.9",
"@verdaccio/node-api": "workspace:6.0.0-6-next.13",
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
"autosuggest-highlight": "3.1.1",
"babel-loader": "^8.2.2",
"babel-plugin-dynamic-import-node": "^2.3.3",

View File

@@ -5,6 +5,7 @@ import {
render,
fireEvent,
waitFor,
screen,
waitForElementToBeRemoved,
} from 'verdaccio-ui/utils/test-react-testing-library';
@@ -23,7 +24,7 @@ const props = {
/* eslint-disable react/jsx-no-bind*/
describe('<Header /> component with logged in state', () => {
test('should load the component in logged out state', () => {
const { container, queryByTestId, getByText } = render(
render(
<Router>
<AppContextProvider>
<Header />
@@ -31,13 +32,13 @@ describe('<Header /> component with logged in state', () => {
</Router>
);
expect(container.firstChild).toMatchSnapshot();
expect(queryByTestId('header--menu-accountcircle')).toBeNull();
expect(getByText('Login')).toBeTruthy();
expect(screen.queryByTestId('header--menu-accountcircle')).toBeNull();
expect(screen.getByText('Login')).toBeTruthy();
expect(screen.queryByTestId('header--button-login')).toBeInTheDocument();
});
test('should load the component in logged in state', () => {
const { container, getByTestId, queryByText } = render(
const { getByTestId, queryByText } = render(
<Router>
<AppContextProvider user={props.user}>
<Header />
@@ -45,7 +46,6 @@ describe('<Header /> component with logged in state', () => {
</Router>
);
expect(container.firstChild).toMatchSnapshot();
expect(getByTestId('header--menu-accountcircle')).toBeTruthy();
expect(queryByText('Login')).toBeNull();
});
@@ -137,5 +137,22 @@ describe('<Header /> component with logged in state', () => {
expect(hasRegistrationInfoModalBeenRemoved).not.toBeDefined();
});
test('should hide login if is disabled', () => {
// @ts-expect-error
window.__VERDACCIO_BASENAME_UI_OPTIONS = {
base: 'foo',
login: false,
};
render(
<Router>
<AppContextProvider user={props.user}>
<Header />
</AppContextProvider>
</Router>
);
expect(screen.queryByTestId('header--button-login')).not.toBeInTheDocument();
});
test.todo('autocompletion should display suggestions according to the type value');
});

View File

@@ -49,6 +49,7 @@ const Header: React.FC<Props> = ({ withoutSearch }) => {
<InnerNavBar>
<HeaderLeft />
<HeaderRight
hasLogin={configOptions?.login}
onLogout={handleLogout}
onOpenRegistryInfoDialog={() => setOpenInfoDialog(true)}
onToggleLogin={() => setShowLoginModal(!showLoginModal)}

View File

@@ -12,6 +12,7 @@ import { RightSide } from './styles';
interface Props {
withoutSearch?: boolean;
username?: string | null;
hasLogin?: boolean;
onToggleLogin: () => void;
onOpenRegistryInfoDialog: () => void;
onToggleMobileNav: () => void;
@@ -22,6 +23,7 @@ const HeaderRight: React.FC<Props> = ({
withoutSearch = false,
username,
onToggleLogin,
hasLogin,
onLogout,
onToggleMobileNav,
onOpenRegistryInfoDialog,
@@ -29,6 +31,7 @@ const HeaderRight: React.FC<Props> = ({
const themeContext = useContext(ThemeContext);
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
const hideLoginSection = hasLogin === false;
const { t } = useTranslation();
@@ -90,19 +93,23 @@ const HeaderRight: React.FC<Props> = ({
tooltipIconType={themeContext.isDarkMode ? 'dark-mode' : 'light-mode'}
/>
{username ? (
<HeaderMenu
anchorEl={anchorEl}
isMenuOpen={isMenuOpen}
onLoggedInMenu={handleLoggedInMenu}
onLoggedInMenuClose={handleLoggedInMenuClose}
onLogout={onLogout}
username={username}
/>
) : (
<Button color="inherit" data-testid="header--button-login" onClick={handleToggleLogin}>
{t('button.login')}
</Button>
{!hideLoginSection && (
<>
{username ? (
<HeaderMenu
anchorEl={anchorEl}
isMenuOpen={isMenuOpen}
onLoggedInMenu={handleLoggedInMenu}
onLoggedInMenuClose={handleLoggedInMenuClose}
onLogout={onLogout}
username={username}
/>
) : (
<Button color="inherit" data-testid="header--button-login" onClick={handleToggleLogin}>
{t('button.login')}
</Button>
)}
</>
)}
</RightSide>
);

View File

@@ -34,7 +34,7 @@ const ActionBar: React.FC = () => {
}
return (
<Box alignItems="center" display="flex" marginBottom="8px">
<Box alignItems="center" display="flex" marginBottom="14px">
{actions.map((action) => (
<ActionBarAction key={action.link} {...action} />
))}

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { render } from 'verdaccio-ui/utils/test-react-testing-library';
import { render, screen } from 'verdaccio-ui/utils/test-react-testing-library';
import { DetailContext } from '../../context';
import { DetailContextProps } from '../../version-config';
@@ -22,11 +22,14 @@ const ComponentToBeRendered: React.FC = () => (
/* eslint-disable react/jsx-no-bind*/
describe('<Install />', () => {
test('renders correctly', () => {
const { container } = render(<ComponentToBeRendered />);
expect(container.firstChild).toMatchSnapshot();
render(<ComponentToBeRendered />);
expect(screen.getByText('pnpm install foo')).toBeInTheDocument();
expect(screen.getByText('yarn add foo')).toBeInTheDocument();
expect(screen.getByText('npm install foo')).toBeInTheDocument();
});
test('should have 3 children', () => {
window.__VERDACCIO_BASENAME_UI_OPTIONS.pkgManagers = ['yarn', 'pnpm', 'npm'];
const { getByTestId } = render(<ComponentToBeRendered />);
const installListItems = getByTestId('installList');
// installitems + subHeader = 4
@@ -34,13 +37,17 @@ describe('<Install />', () => {
});
test('should have the element NPM', () => {
window.__VERDACCIO_BASENAME_UI_OPTIONS.pkgManagers = ['npm'];
const { getByTestId, queryByText } = render(<ComponentToBeRendered />);
expect(getByTestId('installListItem-npm')).toBeTruthy();
expect(queryByText(`npm install ${detailContextValue.packageName}`)).toBeTruthy();
expect(queryByText('Install using npm')).toBeTruthy();
expect(screen.queryByText('pnpm install foo')).not.toBeInTheDocument();
expect(screen.queryByText('yarn add foo')).not.toBeInTheDocument();
});
test('should have the element YARN', () => {
window.__VERDACCIO_BASENAME_UI_OPTIONS.pkgManagers = ['yarn'];
const { getByTestId, queryByText } = render(<ComponentToBeRendered />);
expect(getByTestId('installListItem-yarn')).toBeTruthy();
expect(queryByText(`yarn add ${detailContextValue.packageName}`)).toBeTruthy();
@@ -48,6 +55,7 @@ describe('<Install />', () => {
});
test('should have the element PNPM', () => {
window.__VERDACCIO_BASENAME_UI_OPTIONS.pkgManagers = ['pnpm'];
const { getByTestId, queryByText } = render(<ComponentToBeRendered />);
expect(getByTestId('installListItem-pnpm')).toBeTruthy();
expect(queryByText(`pnpm install ${detailContextValue.packageName}`)).toBeTruthy();

View File

@@ -5,18 +5,20 @@ import { useTranslation } from 'react-i18next';
import List from 'verdaccio-ui/components/List';
import Text from 'verdaccio-ui/components/Text';
import { Theme } from 'verdaccio-ui/design-tokens/theme';
import { useConfig } from 'verdaccio-ui/providers/config';
import { DetailContext } from '../..';
import InstallListItem, { DependencyManager } from './InstallListItem';
const StyledText = styled(Text)<{ theme?: Theme }>((props) => ({
fontWeight: props.theme && props.theme.fontWeight.bold,
fontWeight: props.theme?.fontWeight.bold,
textTransform: 'capitalize',
}));
const Install: React.FC = () => {
const { t } = useTranslation();
const { configOptions } = useConfig();
const detailContext = useContext(DetailContext);
const { packageMeta, packageName } = detailContext;
@@ -25,15 +27,26 @@ const Install: React.FC = () => {
return null;
}
return (
const hasNpm = configOptions?.pkgManagers?.includes('npm');
const hasYarn = configOptions?.pkgManagers?.includes('yarn');
const hasPnpm = configOptions?.pkgManagers?.includes('pnpm') ?? true;
const hasPkgManagers = hasNpm | hasPnpm | hasYarn;
return hasPkgManagers ? (
<List
data-testid={'installList'}
subheader={<StyledText variant={'subtitle1'}>{t('sidebar.installation.title')}</StyledText>}>
<InstallListItem dependencyManager={DependencyManager.NPM} packageName={packageName} />
<InstallListItem dependencyManager={DependencyManager.YARN} packageName={packageName} />
<InstallListItem dependencyManager={DependencyManager.PNPM} packageName={packageName} />
{hasNpm && (
<InstallListItem dependencyManager={DependencyManager.NPM} packageName={packageName} />
)}
{hasYarn && (
<InstallListItem dependencyManager={DependencyManager.YARN} packageName={packageName} />
)}
{hasPnpm && (
<InstallListItem dependencyManager={DependencyManager.PNPM} packageName={packageName} />
)}
</List>
);
) : null;
};
export default Install;

View File

@@ -1,266 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Install /> renders correctly 1`] = `
.emotion-0 {
font-weight: 700;
text-transform: capitalize;
}
.emotion-2 {
padding: 0;
}
.emotion-2:hover {
background-color: transparent;
}
.emotion-4 {
border-radius: 0px;
padding: 0;
}
.emotion-4 img {
background-color: transparent;
}
.emotion-6 {
padding: 0 10px;
margin: 0;
}
.emotion-8 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.emotion-10 {
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 21px;
font-size: 1rem;
}
<ul
class="MuiList-root MuiList-padding MuiList-subheader"
data-testid="installList"
>
<span
class="MuiTypography-root emotion-0 emotion-1 MuiTypography-subtitle1"
>
Installation
</span>
<div
aria-disabled="false"
class="MuiButtonBase-root MuiListItem-root emotion-2 emotion-3 MuiListItem-gutters MuiListItem-button"
data-testid="installListItem-npm"
role="button"
tabindex="0"
>
<div
class="MuiAvatar-root MuiAvatar-circle emotion-4 emotion-5"
>
<img
alt="npm"
class="MuiAvatar-img"
src="[object Object]"
/>
</div>
<div
class="MuiListItemText-root emotion-6 emotion-7 MuiListItemText-multiline"
>
<span
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
>
<div
class="emotion-8 emotion-9"
>
<span
class="emotion-10 emotion-11"
>
npm install foo
</span>
<button
class="MuiButtonBase-root MuiIconButton-root"
data-testid="copy-icon"
tabindex="0"
title="Copy to clipboard"
type="button"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</span>
<p
class="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
>
Install using npm
</p>
</div>
<span
class="MuiTouchRipple-root"
/>
</div>
<div
aria-disabled="false"
class="MuiButtonBase-root MuiListItem-root emotion-2 emotion-3 MuiListItem-gutters MuiListItem-button"
data-testid="installListItem-yarn"
role="button"
tabindex="0"
>
<div
class="MuiAvatar-root MuiAvatar-circle emotion-4 emotion-5"
>
<img
alt="yarn"
class="MuiAvatar-img"
src="[object Object]"
/>
</div>
<div
class="MuiListItemText-root emotion-6 emotion-7 MuiListItemText-multiline"
>
<span
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
>
<div
class="emotion-8 emotion-9"
>
<span
class="emotion-10 emotion-11"
>
yarn add foo
</span>
<button
class="MuiButtonBase-root MuiIconButton-root"
data-testid="copy-icon"
tabindex="0"
title="Copy to clipboard"
type="button"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</span>
<p
class="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
>
Install using yarn
</p>
</div>
<span
class="MuiTouchRipple-root"
/>
</div>
<div
aria-disabled="false"
class="MuiButtonBase-root MuiListItem-root emotion-2 emotion-3 MuiListItem-gutters MuiListItem-button"
data-testid="installListItem-pnpm"
role="button"
tabindex="0"
>
<div
class="MuiAvatar-root MuiAvatar-circle emotion-4 emotion-5"
>
<img
alt="pnpm"
class="MuiAvatar-img"
src="[object Object]"
/>
</div>
<div
class="MuiListItemText-root emotion-6 emotion-7 MuiListItemText-multiline"
>
<span
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
>
<div
class="emotion-8 emotion-9"
>
<span
class="emotion-10 emotion-11"
>
pnpm install foo
</span>
<button
class="MuiButtonBase-root MuiIconButton-root"
data-testid="copy-icon"
tabindex="0"
title="Copy to clipboard"
type="button"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</span>
<p
class="MuiTypography-root MuiListItemText-secondary MuiTypography-body2 MuiTypography-colorTextSecondary MuiTypography-displayBlock"
>
Install using pnpm
</p>
</div>
<span
class="MuiTouchRipple-root"
/>
</div>
</ul>
`;

View File

@@ -1,26 +1,12 @@
import { TemplateUIOptions } from '@verdaccio/types';
import isEmpty from 'lodash/isEmpty';
import isNil from 'lodash/isNil';
import React, { createContext, FunctionComponent, useContext, useMemo, useState } from 'react';
import { PRIMARY_COLOR } from 'verdaccio-ui/utils/colors';
export type VerdaccioOptions = {
url_prefix: string;
base: string;
scope: string;
title: string;
primaryColor: string;
darkMode: boolean;
uri?: string;
language?: string;
version?: string;
protocol?: string;
host?: string;
logo?: string;
};
type ConfigProviderProps = {
configOptions: VerdaccioOptions;
configOptions: TemplateUIOptions;
setConfigOptions: Function;
};
@@ -28,8 +14,10 @@ const defaultValues: ConfigProviderProps = {
configOptions: {
primaryColor: PRIMARY_COLOR,
darkMode: false,
pkgManagers: ['yarn', 'pnpm', 'npm'],
scope: '',
base: '',
login: true,
url_prefix: '',
title: 'Verdaccio',
},
@@ -59,7 +47,6 @@ const AppConfigurationProvider: FunctionComponent = ({ children }) => {
[configOptions]
);
// @ts-ignore
return (
<AppConfigurationContext.Provider value={value}>{children}</AppConfigurationContext.Provider>
);

View File

@@ -2,6 +2,10 @@ web:
title: Verdaccio Local Dev
sort_packages: asc
primary_color: #CCC
login: true
pkgManagers:
- npm
- yarn
plugins: ../

View File

@@ -8,10 +8,11 @@ import config from './webpack.dev.config.babel';
const compiler = webpack(config);
const spinner = ora('Compiler is running...').start();
const port = 4873;
compiler.hooks.done.tap('Verdaccio Dev Server', () => {
if (!global.rebuild) {
spinner.stop();
console.log('Dev Server Listening at http://localhost:4873/');
console.log(`Dev Server Listening at http://localhost:${port}/`);
global.rebuild = true;
}
});
@@ -40,7 +41,7 @@ new WebpackDevServer(compiler, {
target: 'http://localhost:8000',
},
],
}).listen(4873, 'localhost', function (err) {
}).listen(port, 'localhost', function (err) {
if (err) {
return console.log(err);
}

View File

@@ -1,5 +1,8 @@
import fs from 'fs';
import FriendlyErrorsPlugin from 'friendly-errors-webpack-plugin';
import HTMLWebpackPlugin from 'html-webpack-plugin';
import yalm from 'js-yaml';
import StyleLintPlugin from 'stylelint-webpack-plugin';
import webpack from 'webpack';
@@ -8,6 +11,7 @@ import env from '../config/env';
import getPackageJson from './getPackageJson';
import baseConfig from './webpack.config';
const configJsonFormat = yalm.safeLoad(fs.readFileSync('./tools/_verdaccio.config.yaml', 'utf8'));
export default {
...baseConfig,
mode: 'development',
@@ -35,8 +39,7 @@ export default {
}),
new HTMLWebpackPlugin({
__UI_OPTIONS: JSON.stringify({
title: 'Verdaccio Dev UI',
scope: '',
...configJsonFormat.web,
filename: 'index.html',
verdaccioURL: '//localhost:4873',
base: new URL('/', 'http://localhost:4873'),

View File

@@ -1,13 +1,21 @@
// FIXME: this should comes from @verdaccio/types
type PackageManagers = 'pnpm' | 'yarn' | 'npm';
export interface VerdaccioOptions {
// @deprecated
url_prefix: string;
// @deprecated
base: string;
basePath: string;
basename: string;
scope: string;
title: string;
primaryColor: string;
darkMode: boolean;
uri?: string;
login?: boolean;
language?: string;
darkMode?: boolean;
version?: string;
protocol?: string;
host?: string;
logo?: string;
pkgManagers?: PackageManagers[];
}
declare global {

View File

@@ -50,7 +50,7 @@
"request": "2.87.0"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"funding": {
"type": "opencollective",

View File

@@ -1,5 +1,40 @@
# @verdaccio/server
## 6.0.0-6-next.15
### Patch Changes
- Updated dependencies [5ddfa526]
- @verdaccio/store@6.0.0-6-next.9
- @verdaccio/web@6.0.0-6-next.14
- @verdaccio/api@6.0.0-6-next.11
## 6.0.0-6-next.14
### Patch Changes
- Updated dependencies [0da7031e]
- @verdaccio/web@6.0.0-6-next.13
- @verdaccio/api@6.0.0-6-next.10
- @verdaccio/auth@6.0.0-6-next.8
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- verdaccio-audit@11.0.0-alpha.4
- @verdaccio/store@6.0.0-6-next.8
## 6.0.0-6-next.13
### Patch Changes
- Updated dependencies [aecbd226]
- @verdaccio/web@6.0.0-6-next.12
- @verdaccio/api@6.0.0-6-next.10
- @verdaccio/auth@6.0.0-6-next.8
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- verdaccio-audit@11.0.0-alpha.4
- @verdaccio/store@6.0.0-6-next.8
## 6.0.0-6-next.12
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/server",
"version": "6.0.0-6-next.12",
"version": "6.0.0-6-next.15",
"description": "server logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -30,16 +30,16 @@
"npm": ">=6"
},
"dependencies": {
"@verdaccio/api": "workspace:6.0.0-6-next.10",
"@verdaccio/api": "workspace:6.0.0-6-next.11",
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.9",
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
"@verdaccio/web": "workspace:6.0.0-6-next.11",
"@verdaccio/web": "workspace:6.0.0-6-next.14",
"verdaccio-audit": "workspace:11.0.0-alpha.4",
"compression": "1.7.4",
"cors": "2.8.5",

View File

@@ -123,6 +123,16 @@ describe('endpoint web unit test', () => {
});
describe('Search', () => {
test('should find @scope/pk1-test', (done) => {
request(app)
.get('/-/verdaccio/search/@scope%2fpk1-test')
.expect(HTTP_STATUS.OK)
.end(function (err, res) {
expect(res.body).toHaveLength(1);
done();
});
});
test('should not find forbidden-place', (done) => {
request(app)
.get('/-/verdaccio/search/forbidden-place')

View File

@@ -32,8 +32,8 @@
"homepage": "https://verdaccio.org",
"license": "MIT",
"devDependencies": {
"@verdaccio/cli": "workspace:6.0.0-6-next.13",
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.6",
"@verdaccio/cli": "workspace:6.0.0-6-next.16",
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.8",
"fs-extra": "9.0.1",
"webpack": "^5.11.1",
"webpack-cli": "^4.3.1",

View File

@@ -1,5 +1,16 @@
# @verdaccio/store
## 6.0.0-6-next.9
### Patch Changes
- 5ddfa526: Fix the search by exact name of the package
Full package name queries was not finding anithing. It was happening
becouse of stemmer of [lunr.js](https://lunrjs.com/).
To fix this, the stemmer of [lunr.js](https://lunrjs.com/) was removed from search pipeline.
## 6.0.0-6-next.8
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/store",
"version": "6.0.0-6-next.8",
"version": "6.0.0-6-next.9",
"description": "loaders logic",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -50,12 +50,13 @@
"async": "3.1.1",
"debug": "^4.1.1",
"lodash": "4.17.15",
"lunr": "2.3.9",
"lunr-mutable-indexes": "^2.3.2",
"semver": "7.1.2"
},
"devDependencies": {
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
"@verdaccio/types": "workspace:11.0.0-6-next.5"
"@verdaccio/types": "workspace:11.0.0-6-next.7"
},
"funding": {
"type": "opencollective",

View File

@@ -1,14 +1,20 @@
// eslint-disable no-invalid-this
import lunr from 'lunr';
import lunrMutable from 'lunr-mutable-indexes';
import { Version, IPluginStorage, Config } from '@verdaccio/types';
import { IStorageHandler, IStorage } from './storage';
export interface ISearchResult {
ref: string;
score: number;
}
export interface IWebSearch {
index: lunrMutable.index;
storage: IStorageHandler;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
query(query: string): any;
query(query: string): ISearchResult[];
add(pkg: Version): void;
remove(name: string): void;
reindex(): void;
@@ -42,6 +48,8 @@ class Search implements IWebSearch {
// @ts-ignore
this.field('readme');
});
this.index.builder.pipeline.remove(lunr.stemmer);
}
public init() {
@@ -55,7 +63,7 @@ class Search implements IWebSearch {
* @param {*} q the keyword
* @return {Array} list of results.
*/
public query(query: string): any[] {
public query(query: string): ISearchResult[] {
const localStorage = this.storage.localStorage as IStorage;
return query === '*'

View File

@@ -1,5 +1,37 @@
# verdaccio
## 6.0.0-6-next.17
### Patch Changes
- @verdaccio/node-api@6.0.0-6-next.16
- @verdaccio/cli@6.0.0-6-next.16
- @verdaccio/ui-theme@6.0.0-6-next.8
## 6.0.0-6-next.16
### Patch Changes
- Updated dependencies [0da7031e]
- @verdaccio/ui-theme@6.0.0-6-next.8
- @verdaccio/hooks@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/mock@6.0.0-6-next.6
- @verdaccio/node-api@6.0.0-6-next.15
- @verdaccio/cli@6.0.0-6-next.15
## 6.0.0-6-next.15
### Patch Changes
- Updated dependencies [aecbd226]
- @verdaccio/ui-theme@6.0.0-6-next.7
- @verdaccio/hooks@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/mock@6.0.0-6-next.6
- @verdaccio/node-api@6.0.0-6-next.14
- @verdaccio/cli@6.0.0-6-next.14
## 6.0.0-6-next.14
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "verdaccio",
"version": "6.0.0-6-next.14",
"version": "6.0.0-6-next.17",
"description": "A lightweight private npm proxy registry",
"main": "build/index.js",
"types": "build/index.d.ts",
@@ -36,12 +36,12 @@
},
"homepage": "https://verdaccio.org",
"dependencies": {
"@verdaccio/cli": "workspace:6.0.0-6-next.13",
"@verdaccio/cli": "workspace:6.0.0-6-next.16",
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
"@verdaccio/node-api": "workspace:6.0.0-6-next.13",
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.6",
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.8",
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
"verdaccio-audit": "11.0.0-alpha.4",
"verdaccio-htpasswd": "11.0.0-alpha.6"
@@ -50,7 +50,7 @@
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"@verdaccio/config": "workspace:6.0.0-6-next.6",
"@verdaccio/store": "workspace:6.0.0-6-next.8"
"@verdaccio/store": "workspace:6.0.0-6-next.9"
},
"keywords": [
"private",

View File

@@ -1,5 +1,84 @@
# @verdaccio/web
## 6.0.0-6-next.14
### Patch Changes
- 5ddfa526: Fix the search by exact name of the package
Full package name queries was not finding anithing. It was happening
becouse of stemmer of [lunr.js](https://lunrjs.com/).
To fix this, the stemmer of [lunr.js](https://lunrjs.com/) was removed from search pipeline.
- Updated dependencies [5ddfa526]
- @verdaccio/store@6.0.0-6-next.9
## 6.0.0-6-next.13
### Minor Changes
- 0da7031e: allow disable login on ui and endpoints
To be able disable the login, set `login: false`, anything else would enable login. This flag will disable access via UI and web endpoints.
```yml
web:
title: verdaccio
login: false
```
### Patch Changes
- @verdaccio/auth@6.0.0-6-next.8
- @verdaccio/readme@11.0.0-alpha.3
- @verdaccio/tarball@11.0.0-6-next.5
- @verdaccio/url@11.0.0-6-next.4
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/store@6.0.0-6-next.8
## 6.0.0-6-next.12
### Minor Changes
- aecbd226: web: allow ui hide package managers on sidebar
If there is a package manager of preference over others, you can define the package managers to be displayed on the detail page and sidebar, just define in the `config.yaml` and web section the list of package managers to be displayed.
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
- pnpm
- yarn
# - npm
```
To disable all package managers, just define empty:
```
web:
title: Verdaccio
sort_packages: asc
primary_color: #cccccc
pkgManagers:
```
and the section would be hidden.
### Patch Changes
- @verdaccio/auth@6.0.0-6-next.8
- @verdaccio/readme@11.0.0-alpha.3
- @verdaccio/tarball@11.0.0-6-next.5
- @verdaccio/url@11.0.0-6-next.4
- @verdaccio/loaders@6.0.0-6-next.4
- @verdaccio/logger@6.0.0-6-next.4
- @verdaccio/store@6.0.0-6-next.8
## 6.0.0-6-next.11
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/web",
"version": "6.0.0-6-next.11",
"version": "6.0.0-6-next.14",
"description": "web ui middleware",
"main": "./build/index.js",
"types": "build/index.d.ts",
@@ -32,7 +32,7 @@
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
"@verdaccio/middleware": "workspace:6.0.0-6-next.8",
"@verdaccio/readme": "workspace:11.0.0-alpha.3",
"@verdaccio/store": "workspace:6.0.0-6-next.8",
"@verdaccio/store": "workspace:6.0.0-6-next.9",
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
"@verdaccio/url": "workspace:11.0.0-6-next.4",
"@verdaccio/tarball": "workspace:11.0.0-6-next.5",
@@ -44,7 +44,7 @@
"lodash": "^4.17.20"
},
"devDependencies": {
"@verdaccio/types": "workspace:11.0.0-6-next.5",
"@verdaccio/types": "workspace:11.0.0-6-next.7",
"verdaccio-auth-memory": "workspace:11.0.0-alpha.3",
"verdaccio-memory": "workspace:11.0.0-6-next.4",
"supertest": "^6.1.3",

View File

@@ -29,11 +29,20 @@ function addPackageWebApi(
auth: IAuth,
config: Config
): void {
const isLoginEnabled = config?.web?.login === true ?? true;
const anonymousRemoteUser: RemoteUser = {
name: undefined,
real_groups: [],
groups: [],
};
debug('initialized package web api');
const checkAllow = (name: string, remoteUser: RemoteUser): Promise<boolean> =>
new Promise((resolve, reject): void => {
debug('is login disabled %o', isLoginEnabled);
const remoteUserAccess = !isLoginEnabled ? anonymousRemoteUser : remoteUser;
try {
auth.allow_access({ packageName: name }, remoteUser, (err, allowed): void => {
auth.allow_access({ packageName: name }, remoteUserAccess, (err, allowed): void => {
if (err) {
resolve(false);
}

View File

@@ -37,7 +37,7 @@ function addReadmeWebApi(route: Router, storage: IStorageHandler, auth: IAuth):
uplinksLook: true,
req,
callback: function (err, info): void {
debug('readme plg %o', info);
debug('readme plg %o', info?.name);
if (err) {
return next(err);
}

View File

@@ -28,6 +28,7 @@ function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth):
debug('is allowed %o', allowed);
if (err || !allowed) {
debug('deny access');
reject(err);
return;
}
debug('access succeed');
@@ -52,17 +53,17 @@ function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth):
res: $ResponseExtend,
next: $NextFunctionVer
): Promise<void> {
const results: string[] = SearchInstance.query(req.params.anything);
const results = SearchInstance.query(req.params.anything);
debug('search results %o', results);
if (results.length > 0) {
let packages: Package[] = [];
for (let pkgName of results) {
for (let result of results) {
try {
const pkg = await getPackageInfo(pkgName, req.remote_user);
debug('package found %o', pkgName);
const pkg = await getPackageInfo(result.ref, req.remote_user);
debug('package found %o', result.ref);
packages.push(pkg);
} catch (err) {
debug('search for %o failed err %o', pkgName, err?.message);
debug('search for %o failed err %o', result.ref, err?.message);
}
}
next(packages);

View File

@@ -11,6 +11,7 @@ import addPackageWebApi from '../api/package';
import addUserAuthApi from '../api/user';
import addReadmeWebApi from '../api/readme';
import addSidebarWebApi from '../api/sidebar';
import { hasLogin } from '../utils/web-utils';
import { setSecurityWebHeaders } from './security';
export function webAPI(config: Config, auth: IAuth, storage: IStorageHandler): Router {
@@ -33,7 +34,9 @@ export function webAPI(config: Config, auth: IAuth, storage: IStorageHandler): R
addReadmeWebApi(route, storage, auth);
addSidebarWebApi(route, config, storage, auth);
addSearchWebApi(route, storage, auth);
addUserAuthApi(route, auth, config);
if (hasLogin(config)) {
addUserAuthApi(route, auth, config);
}
// What are you looking for? logout? client side will remove token when user click logout,
// or it will auto expire after 24 hours.
// This token is different with the token send to npm client.

View File

@@ -5,7 +5,7 @@ import { HEADERS } from '@verdaccio/commons-api';
import { getPublicUrl } from '@verdaccio/url';
import { WEB_TITLE } from '@verdaccio/config';
import { validatePrimaryColor } from './utils/web-utils';
import { hasLogin, validatePrimaryColor } from './utils/web-utils';
import renderTemplate from './template';
const pkgJSON = require('../package.json');
@@ -26,9 +26,11 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
const language = config?.i18n?.web ?? DEFAULT_LANGUAGE;
const darkMode = config?.web?.darkMode ?? false;
const title = config?.web?.title ?? WEB_TITLE;
const login = hasLogin(config);
const scope = config?.web?.scope ?? '';
// FIXME: logo URI is incomplete
let logoURI = config?.web?.logo ?? '';
const pkgManagers = config?.web?.pkgManagers ?? ['yarn', 'pnpm', 'npm'];
const version = pkgJSON.version;
const primaryColor = validatePrimaryColor(config?.web?.primary_color) ?? '#4b5e40';
const { scriptsBodyAfter, metaScripts, scriptsbodyBefore } = Object.assign(
@@ -48,6 +50,8 @@ export default function renderHTML(config, manifest, manifestFiles, req, res) {
primaryColor,
version,
logoURI,
login,
pkgManagers,
title,
scope,
language,

View File

@@ -1,23 +1,9 @@
import buildDebug from 'debug';
import { TemplateUIOptions } from '@verdaccio/types';
import { getManifestValue, Manifest } from './utils/manifest';
const debug = buildDebug('verdaccio:web:render:template');
export type TemplateUIOptions = {
title?: string;
uri?: string;
darkMode?: boolean;
protocol?: string;
host?: string;
url_prefix?: string;
base: string;
primaryColor?: string;
version?: string;
logoURI?: string;
scope?: string;
language?: string;
};
export type Template = {
manifest: Manifest;
options: TemplateUIOptions;

View File

@@ -1,7 +1,7 @@
import _ from 'lodash';
import buildDebug from 'debug';
import { isObject } from '@verdaccio/utils';
import { Package, Author } from '@verdaccio/types';
import { Package, Author, ConfigYaml } from '@verdaccio/types';
import { normalizeContributors } from '@verdaccio/store';
import sanitizyReadme from '@verdaccio/readme';
@@ -109,3 +109,7 @@ export function sortByName(packages: any[], orderAscending: boolean | void = tru
return orderAscending ? (comparatorNames ? -1 : 1) : comparatorNames ? 1 : -1;
});
}
export function hasLogin(config: ConfigYaml) {
return _.isNil(config?.web?.login) || config?.web?.login === true;
}

View File

@@ -9,7 +9,10 @@ import { initializeServer } from './helper';
setup([]);
const mockManifest = jest.fn();
const mockQuery = jest.fn(() => ['pkg1', 'pk2']);
const mockQuery = jest.fn(() => [
{ ref: 'pkg1', score: 1 },
{ ref: 'pk2', score: 0.9 },
]);
jest.mock('@verdaccio/ui-theme', () => mockManifest());
jest.mock('@verdaccio/store', () => ({
@@ -74,7 +77,11 @@ describe('test web server', () => {
test('should fail search api', async () => {
mockQuery.mockImplementation(() => {
return ['aa', 'bb', 'cc'];
return [
{ ref: 'aa', score: 1 },
{ ref: 'bb', score: 0.8 },
{ ref: 'cc', score: 0.6 },
];
});
const response = await supertest(await initializeServer('default-test.yaml'))
.get('/-/verdaccio/search/notFound')

View File

@@ -62,6 +62,19 @@ describe('test web server', () => {
});
});
test('log in should be disabled', async () => {
return supertest(await initializeServer('login-disabled.yaml'))
.post('/-/verdaccio/login')
.send(
JSON.stringify({
username: 'test',
password: 'test',
})
)
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.expect(HTTP_STATUS.NOT_FOUND);
});
test.todo('should change password');
test.todo('should not change password if flag is disabled');
});

View File

@@ -0,0 +1,33 @@
store:
memory:
limit: 1000
auth:
auth-memory:
users:
test:
name: test
password: test
web:
title: verdaccio
login: false
publish:
allow_offline: false
uplinks:
logs: { type: stdout, format: pretty, level: trace }
packages:
'@*/*':
access: $anonymous
publish: $anonymous
'**':
access: $anonymous
publish: $anonymous
_debug: true
flags:
changePassword: true

113
pnpm-lock.yaml generated
View File

@@ -224,10 +224,10 @@ importers:
'@verdaccio/hooks': workspace:6.0.0-6-next.4
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/middleware': workspace:6.0.0-6-next.8
'@verdaccio/server': workspace:6.0.0-6-next.12
'@verdaccio/store': workspace:6.0.0-6-next.8
'@verdaccio/server': workspace:6.0.0-6-next.15
'@verdaccio/store': workspace:6.0.0-6-next.9
'@verdaccio/tarball': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/utils': workspace:6.0.0-6-next.4
body-parser: 1.19.0
cookies: 0.8.0
@@ -266,7 +266,7 @@ importers:
'@verdaccio/loaders': workspace:6.0.0-6-next.4
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/utils': workspace:6.0.0-6-next.4
debug: ^4.1.1
express: 4.17.1
@@ -293,7 +293,7 @@ importers:
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/fastify-migration': workspace:6.0.0-6-next.9
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/node-api': workspace:6.0.0-6-next.13
'@verdaccio/node-api': workspace:6.0.0-6-next.16
clipanion: 3.0.0-rc.11
commander: 6.2.0
envinfo: 7.4.0
@@ -343,7 +343,7 @@ importers:
packages/core/file-locking:
specifiers:
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
lockfile: 1.0.4
dependencies:
lockfile: 1.0.4
@@ -355,7 +355,7 @@ importers:
'@types/bcryptjs': ^2.4.2
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/file-locking': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
apache-md5: 1.1.2
bcryptjs: 2.4.3
http-errors: 1.8.0
@@ -379,7 +379,7 @@ importers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/file-locking': workspace:11.0.0-alpha.3
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
async: ^3.2.0
debug: ^4.1.1
lodash: ^4.17.20
@@ -402,7 +402,7 @@ importers:
packages/core/readme:
specifiers:
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
dompurify: 2.0.8
jsdom: 15.2.1
marked: 1.1.1
@@ -415,7 +415,7 @@ importers:
packages/core/server:
specifiers:
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
fastify: 3.14.2
dependencies:
fastify: 3.14.2
@@ -424,14 +424,14 @@ importers:
packages/core/streams:
specifiers:
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
devDependencies:
'@verdaccio/types': link:../types
packages/core/tarball:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/url': workspace:11.0.0-6-next.4
'@verdaccio/utils': workspace:6.0.0-6-next.4
debug: ^4.3.1
@@ -458,7 +458,7 @@ importers:
packages/core/url:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.3.1
lodash: ^4.17.21
node-mocks-http: ^1.10.1
@@ -478,7 +478,7 @@ importers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.2.0
handlebars: 4.5.3
nock: ^13.0.4
@@ -503,7 +503,7 @@ importers:
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.1.1
lodash: 4.17.15
dependencies:
@@ -520,7 +520,7 @@ importers:
specifiers:
'@types/pino': ^6.3.3
'@verdaccio/logger-prettify': workspace:6.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.2.0
lodash: ~4.17.20
pino: ^6.7.0
@@ -574,7 +574,7 @@ importers:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/utils': workspace:6.0.0-6-next.4
debug: ^4.2.0
fs-extra: ^8.1.0
@@ -599,8 +599,8 @@ importers:
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/server': workspace:6.0.0-6-next.12
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/server': workspace:6.0.0-6-next.15
'@verdaccio/types': workspace:11.0.0-6-next.7
core-js: ^3.6.5
debug: ^4.2.0
jest-mock-process: ^1.4.0
@@ -626,7 +626,7 @@ importers:
specifiers:
'@types/activedirectory2': ^1.2.1
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
activedirectory2: ^1.3.0
dependencies:
'@verdaccio/commons-api': link:../../core/commons-api
@@ -637,7 +637,7 @@ importers:
packages/plugins/audit:
specifiers:
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
body-parser: ^1.19.0
express: ^4.17.1
https-proxy-agent: ^5.0.0
@@ -657,7 +657,7 @@ importers:
packages/plugins/auth-memory:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.3.1
dependencies:
'@verdaccio/commons-api': link:../../core/commons-api
@@ -669,7 +669,7 @@ importers:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
aws-sdk: ^2.607.0
recursive-readdir: 2.2.2
dependencies:
@@ -686,7 +686,7 @@ importers:
'@google-cloud/storage': ^5.3.0
'@verdaccio/commons-api': ^11.0.0-alpha.3
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
fast-crc32c: 1.0.4
memory-fs: 0.5.0
dependencies:
@@ -704,7 +704,7 @@ importers:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
debug: ^4.3.1
memfs: 3.2.0
memory-fs: ^0.5.0
@@ -731,7 +731,7 @@ importers:
'@testing-library/dom': ^7.29.0
'@testing-library/jest-dom': ^5.11.6
'@testing-library/react': 10.4.9
'@verdaccio/node-api': workspace:6.0.0-6-next.13
'@verdaccio/node-api': workspace:6.0.0-6-next.16
autosuggest-highlight: 3.1.1
babel-loader: ^8.2.2
babel-plugin-dynamic-import-node: ^2.3.3
@@ -882,7 +882,7 @@ importers:
'@verdaccio/local-storage': workspace:11.0.0-6-next.6
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/utils': workspace:6.0.0-6-next.4
JSONStream: 1.3.5
lodash: ^4.17.20
@@ -902,7 +902,7 @@ importers:
packages/server:
specifiers:
'@verdaccio/api': workspace:6.0.0-6-next.10
'@verdaccio/api': workspace:6.0.0-6-next.11
'@verdaccio/auth': workspace:6.0.0-6-next.8
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/config': workspace:6.0.0-6-next.6
@@ -911,9 +911,9 @@ importers:
'@verdaccio/middleware': workspace:6.0.0-6-next.8
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/proxy': workspace:6.0.0-6-next.8
'@verdaccio/store': workspace:6.0.0-6-next.8
'@verdaccio/store': workspace:6.0.0-6-next.9
'@verdaccio/utils': workspace:6.0.0-6-next.4
'@verdaccio/web': workspace:6.0.0-6-next.11
'@verdaccio/web': workspace:6.0.0-6-next.14
compression: 1.7.4
cors: 2.8.5
express: 4.17.1
@@ -947,8 +947,8 @@ importers:
packages/standalone:
specifiers:
'@verdaccio/cli': workspace:6.0.0-6-next.13
'@verdaccio/ui-theme': workspace:6.0.0-6-next.6
'@verdaccio/cli': workspace:6.0.0-6-next.16
'@verdaccio/ui-theme': workspace:6.0.0-6-next.8
fs-extra: 9.0.1
webpack: ^5.11.1
webpack-bundle-analyzer: 3.8.0
@@ -973,11 +973,12 @@ importers:
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/proxy': workspace:6.0.0-6-next.8
'@verdaccio/streams': workspace:11.0.0-alpha.3
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/utils': workspace:6.0.0-6-next.4
async: 3.1.1
debug: ^4.1.1
lodash: 4.17.15
lunr: 2.3.9
lunr-mutable-indexes: ^2.3.2
semver: 7.1.2
dependencies:
@@ -992,6 +993,7 @@ importers:
async: 3.1.1
debug: 4.1.1
lodash: 4.17.15
lunr: 2.3.9
lunr-mutable-indexes: 2.3.2
semver: 7.1.2
devDependencies:
@@ -1018,15 +1020,15 @@ importers:
packages/verdaccio:
specifiers:
'@verdaccio/auth': workspace:6.0.0-6-next.8
'@verdaccio/cli': workspace:6.0.0-6-next.13
'@verdaccio/cli': workspace:6.0.0-6-next.16
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/config': workspace:6.0.0-6-next.6
'@verdaccio/hooks': workspace:6.0.0-6-next.4
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/mock': workspace:6.0.0-6-next.6
'@verdaccio/node-api': workspace:6.0.0-6-next.13
'@verdaccio/store': workspace:6.0.0-6-next.8
'@verdaccio/ui-theme': workspace:6.0.0-6-next.6
'@verdaccio/node-api': workspace:6.0.0-6-next.16
'@verdaccio/store': workspace:6.0.0-6-next.9
'@verdaccio/ui-theme': workspace:6.0.0-6-next.8
'@verdaccio/utils': workspace:6.0.0-6-next.4
verdaccio-audit: 11.0.0-alpha.4
verdaccio-htpasswd: 11.0.0-alpha.6
@@ -1055,9 +1057,9 @@ importers:
'@verdaccio/logger': workspace:6.0.0-6-next.4
'@verdaccio/middleware': workspace:6.0.0-6-next.8
'@verdaccio/readme': workspace:11.0.0-alpha.3
'@verdaccio/store': workspace:6.0.0-6-next.8
'@verdaccio/store': workspace:6.0.0-6-next.9
'@verdaccio/tarball': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.5
'@verdaccio/types': workspace:11.0.0-6-next.7
'@verdaccio/url': workspace:11.0.0-6-next.4
'@verdaccio/utils': workspace:6.0.0-6-next.4
body-parse: 0.1.0
@@ -1117,11 +1119,11 @@ importers:
test/e2e-ui:
specifiers:
'@verdaccio/commons-api': workspace:11.0.0-alpha.3
'@verdaccio/ui-theme': workspace:6.0.0-6-next.6
'@verdaccio/ui-theme': workspace:6.0.0-6-next.8
debug: 4.3.1
kleur: ^4.1.3
lodash: ^4.17.20
puppeteer: ^7.1.0
puppeteer: ^9.1.1
request: ^2.88.2
rimraf: ^3.0.2
devDependencies:
@@ -1130,7 +1132,7 @@ importers:
debug: 4.3.1
kleur: 4.1.3
lodash: 4.17.20
puppeteer: 7.1.0
puppeteer: 9.1.1
request: 2.88.2
rimraf: 3.0.2
@@ -7676,7 +7678,7 @@ packages:
/@types/yauzl/2.9.1:
resolution: {integrity: sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==}
dependencies:
'@types/node': 14.14.21
'@types/node': 14.14.41
dev: true
optional: true
@@ -12113,8 +12115,8 @@ packages:
tslib: 1.13.0
dev: false
/devtools-protocol/0.0.847576:
resolution: {integrity: sha512-0M8kobnSQE0Jmly7Mhbeq0W/PpZfnuK+WjN2ZRVPbGqYwCHCioAVp84H0TcLimgECcN5H976y5QiXMGBC9JKmg==}
/devtools-protocol/0.0.869402:
resolution: {integrity: sha512-VvlVYY+VDJe639yHs5PHISzdWTLL3Aw8rO4cvUtwvoxFd6FHbE4OpHHcde52M6096uYYazAmd4l0o5VuFRO2WA==}
dev: true
/diacritic/0.0.2:
@@ -22243,13 +22245,13 @@ packages:
escape-goat: 2.1.1
dev: true
/puppeteer/7.1.0:
resolution: {integrity: sha512-lqOLzqCKdh7yUAHvK6LxgOpQrL8Bv1/jvS8MLDXxcNms2rlM3E8p/Wlwc7efbRZ0twxTzUeqjN5EqrTwxOwc9g==}
/puppeteer/9.1.1:
resolution: {integrity: sha512-W+nOulP2tYd/ZG99WuZC/I5ljjQQ7EUw/jQGcIb9eu8mDlZxNY2SgcJXTLG9h5gRvqA3uJOe4hZXYsd3EqioMw==}
engines: {node: '>=10.18.1'}
requiresBuild: true
dependencies:
debug: 4.3.1
devtools-protocol: 0.0.847576
devtools-protocol: 0.0.869402
extract-zip: 2.0.1
https-proxy-agent: 5.0.0
node-fetch: 2.6.1
@@ -22259,7 +22261,7 @@ packages:
rimraf: 3.0.2
tar-fs: 2.1.0
unbzip2-stream: 1.4.3
ws: 7.4.2
ws: 7.4.4
transitivePeerDependencies:
- bufferutil
- supports-color
@@ -27412,19 +27414,6 @@ packages:
utf-8-validate:
optional: true
/ws/7.4.2:
resolution: {integrity: sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==}
engines: {node: '>=8.3.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
dev: true
/ws/7.4.4:
resolution: {integrity: sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==}
engines: {node: '>=8.3.0'}

View File

@@ -1,6 +1,7 @@
web:
enable: true
title: verdaccio-server-protected-e2e
login: true
store:
memory:
@@ -13,8 +14,7 @@ auth:
name: test
password: test
logs:
- { type: stdout, format: pretty, level: info }
logs: { type: stdout, format: pretty, level: info }
packages:
'protected-*':

View File

@@ -1,6 +1,7 @@
web:
enable: true
title: verdaccio-server-e2e
login: true
store:
memory:
@@ -13,8 +14,7 @@ auth:
name: test
password: test
logs:
- { type: stdout, format: pretty, level: info }
logs: { type: stdout, format: pretty, level: info }
packages:
'@*/*':

View File

@@ -40,7 +40,7 @@ describe('/ (Verdaccio Page)', () => {
expect(loginButton).toBeDefined();
await loginButton.focus();
await loginButton.click({ delay: 100 });
await page.waitFor(500);
await page.waitForTimeout(500);
};
beforeAll(async () => {
@@ -55,7 +55,7 @@ describe('/ (Verdaccio Page)', () => {
test('should display title', async () => {
const text = await page.title();
await page.waitFor(1000);
await page.waitForTimeout(1000);
expect(text).toContain('verdaccio-server-e2e');
});
@@ -87,29 +87,34 @@ describe('/ (Verdaccio Page)', () => {
test('should click on sign in button', async () => {
const signInButton = await page.$('button[data-testid="header--button-login"]');
await signInButton.click();
await page.waitFor(1000);
await page.waitForTimeout(1000);
const signInDialog = await page.$('#login--dialog');
expect(signInDialog).not.toBeNull();
const closeButton = await page.$('button[data-testid="close-login-dialog-button"]');
await closeButton.click();
await page.waitFor(500);
await page.waitForTimeout(500);
});
//
test('should log in an user', async () => {
// we open the dialog
await logIn();
// verify if logged in
const accountButton = await page.$('#header--button-account');
expect(accountButton).toBeDefined();
// check whether user is logged
const buttonLogout = await page.$('#header--button-logout');
expect(buttonLogout).toBeDefined();
});
test('should logout an user', async () => {
// await wa
await page.waitForTimeout(10000);
// we assume the user is logged already
await clickElement('#header--button-account', { delay: 500 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
await clickElement('#header--button-logout > span', { delay: 500 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
await evaluateSignIn();
});
//
@@ -117,7 +122,7 @@ describe('/ (Verdaccio Page)', () => {
test('should check registry info dialog', async () => {
const registryInfoButton = await page.$('#header--button-registryInfo');
registryInfoButton.click();
await page.waitFor(500);
await page.waitForTimeout(500);
const registryInfoDialog = await page.$('#registryInfo--dialog-container');
expect(registryInfoDialog).not.toBeNull();
@@ -129,9 +134,9 @@ describe('/ (Verdaccio Page)', () => {
test('should publish a package', async () => {
await global.__SERVER__.putPackage(scopedPackageMetadata.name, scopedPackageMetadata);
await page.waitFor(1000);
await page.waitForTimeout(1000);
await page.reload();
await page.waitFor(1000);
await page.waitForTimeout(1000);
const packagesList = await getPackages();
expect(packagesList).toHaveLength(1);
});
@@ -142,7 +147,7 @@ describe('/ (Verdaccio Page)', () => {
// console.log("-->packagesList:", packagesList);
const firstPackage = packagesList[0];
await firstPackage.click({ delay: 200 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
const readmeText = await page.evaluate(
() => document.querySelector('.markdown-body').textContent
);
@@ -160,7 +165,7 @@ describe('/ (Verdaccio Page)', () => {
const dependenciesTab = await page.$$('#dependencies-tab');
expect(dependenciesTab).toHaveLength(1);
await dependenciesTab[0].click({ delay: 200 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
const tags = await page.$$('.dep-tag');
const tag = tags[0];
const label = await page.evaluate((el) => el.innerText, tag);
@@ -171,7 +176,7 @@ describe('/ (Verdaccio Page)', () => {
const versionsTab = await page.$$('#versions-tab');
expect(versionsTab).toHaveLength(1);
await versionsTab[0].click({ delay: 200 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
const versionItems = await page.$$('.version-item');
expect(versionItems).toHaveLength(2);
});
@@ -180,33 +185,33 @@ describe('/ (Verdaccio Page)', () => {
const upLinksTab = await page.$$('#uplinks-tab');
expect(upLinksTab).toHaveLength(1);
await upLinksTab[0].click({ delay: 200 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
});
test('should display readme tab', async () => {
const readmeTab = await page.$$('#readme-tab');
expect(readmeTab).toHaveLength(1);
await readmeTab[0].click({ delay: 200 });
await page.waitFor(1000);
await page.waitForTimeout(1000);
});
test('should publish a protected package', async () => {
await page.goto('http://0.0.0.0:55552');
await page.waitFor(500);
await page.waitForTimeout(500);
await global.__SERVER_PROTECTED__.putPackage(
protectedPackageMetadata.name,
protectedPackageMetadata
);
await page.waitFor(500);
await page.waitForTimeout(500);
await page.reload();
await page.waitFor(500);
await page.waitForTimeout(500);
const text = await page.evaluate(() => document.querySelector('#help-card__title').textContent);
expect(text).toMatch('No Package Published Yet');
});
test('should go to 404 page', async () => {
await page.goto('http://0.0.0.0:55552/-/web/detail/@verdaccio/not-found');
await page.waitFor(500);
await page.waitForTimeout(500);
const text = await page.evaluate(() => document.querySelector('.not-found-text').textContent);
expect(text).toMatch("Sorry, we couldn't find it...");
});

View File

@@ -3,14 +3,14 @@
"private": true,
"version": "1.1.0-6-next.1",
"devDependencies": {
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.6",
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.8",
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
"debug": "4.3.1",
"kleur": "^4.1.3",
"request": "^2.88.2",
"lodash": "^4.17.20",
"rimraf": "^3.0.2",
"puppeteer": "^7.1.0"
"puppeteer": "^9.1.1"
},
"scripts": {
"test": "jest --config jest.config.e2e.js"