1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-21 07:29:37 +01:00

docs: update translations

docs: update translations
This commit is contained in:
verdacciobot 2018-01-21 00:04:36 +01:00 committed by Juan Picado @jotadeveloper
parent 4592049a7e
commit d1bed601b7
84 changed files with 2068 additions and 982 deletions

@ -17,6 +17,7 @@
"installation": "Instalación",
"kubernetes": "Kubernetes",
"logger": "Logger",
"node-api": "Node API",
"notifications": "Notificaciones",
"packages": "Acceso a paquetes",
"plugins": "Extensiones",
@ -29,6 +30,7 @@
"uplinks": "Enlaces externos",
"use-cases": "Casos de Uso",
"webui": "Interfaz de Usuario Web",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "Instalando como Servicio en Windows",
"Docs": "Documentación",
"Help": "Ayuda",
@ -42,7 +44,7 @@
"Guides": "Guías"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "Navegar Documentación",
"Ask questions about the documentation and project|no description given": "Haz preguntas sobre la documentación y el proyecto",
"Join the community|no description given": "Únete a la comunidad",

@ -17,6 +17,7 @@
"installation": "Instalação",
"kubernetes": "Kubernetes",
"logger": "Logger",
"node-api": "Node API",
"notifications": "Notifications",
"packages": "Package Access",
"plugins": "Plugins",
@ -29,6 +30,7 @@
"uplinks": "Uplinks",
"use-cases": "Use Cases",
"webui": "Interface Web",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "Instalando como um Serviço no Windows",
"Docs": "Docs",
"Help": "Ajuda",
@ -42,7 +44,7 @@
"Guides": "Guides"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "Descubra mais lendo a [documentação neste site.](/test-site/docs/en/doc1.html)",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "Documentação",
"Ask questions about the documentation and project|no description given": "Faça perguntas sobre a documentação e o projeto",
"Join the community|no description given": "Faça parte",

@ -17,6 +17,7 @@
"installation": "Installation",
"kubernetes": "Kubernetes",
"logger": "Logger",
"node-api": "Node API",
"notifications": "Notifications",
"packages": "Package Access",
"plugins": "Plugins",
@ -29,6 +30,7 @@
"uplinks": "Uplinks",
"use-cases": "Use Cases",
"webui": "Web User Interface",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "Installing As a Windows Service",
"Docs": "Docs",
"Help": "Help",
@ -42,7 +44,7 @@
"Guides": "Guides"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "Browse Docs",
"Ask questions about the documentation and project|no description given": "Ask questions about the documentation and project",
"Join the community|no description given": "Join the community",

@ -17,6 +17,7 @@
"installation": "安装",
"kubernetes": "Kubernetes",
"logger": "日志",
"node-api": "Node API",
"notifications": "通知",
"packages": "npm 包访问权限",
"plugins": "插件",
@ -29,6 +30,7 @@
"uplinks": "Uplinks",
"use-cases": "使用场景",
"webui": "Web 界面",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "作为 Windows 服务安装",
"Docs": "文档",
"Help": "帮助",
@ -42,7 +44,7 @@
"Guides": "使用指南"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "通过 [站内文档](/test-site/docs/en/doc1.html) 了解更多信息",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "浏览文档",
"Ask questions about the documentation and project|no description given": "询问有关于文档或项目的问题",
"Join the community|no description given": "加入社区",

@ -17,6 +17,7 @@
"installation": "Installation",
"kubernetes": "Kubernetes",
"logger": "Logger",
"node-api": "Node API",
"notifications": "Notifications",
"packages": "Package Access",
"plugins": "Plugins",
@ -29,6 +30,7 @@
"uplinks": "Uplinks",
"use-cases": "Use Cases",
"webui": "Web User Interface",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "Installing As a Windows Service",
"Docs": "Docs",
"Help": "Help",
@ -42,7 +44,7 @@
"Guides": "Guides"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "Browse Docs",
"Ask questions about the documentation and project|no description given": "Ask questions about the documentation and project",
"Join the community|no description given": "Join the community",

@ -17,6 +17,7 @@
"installation": "Installation",
"kubernetes": "Kubernetes",
"logger": "Logger",
"node-api": "Node API",
"notifications": "Notifications",
"packages": "Package Access",
"plugins": "Plugins",
@ -29,6 +30,7 @@
"uplinks": "Uplinks",
"use-cases": "Use Cases",
"webui": "Web User Interface",
"what-is-verdaccio": "What is Verdaccio?",
"windows": "Installing As a Windows Service",
"Docs": "Docs",
"Help": "Help",
@ -42,7 +44,7 @@
"Guides": "Guides"
},
"pages-strings": {
"Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)|no description given": "Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)",
"Learn more using the [documentation on this site.](/docs/en/installation.html)|no description given": "Learn more using the [documentation on this site.](/docs/en/installation.html)",
"Browse Docs|no description given": "Browse Docs",
"Ask questions about the documentation and project|no description given": "Ask questions about the documentation and project",
"Join the community|no description given": "Join the community",

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ The verdaccio CLI is your go start the application.
## Commands
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | ------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | the configuration file |
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | -------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | the configuration file |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>Since: <em>v2.3.6</em> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### Prefijos URL
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
Since: *v2.3.6* due [#197](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### Max Body Size
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,31 +4,33 @@ title: Docker
---
Para descargar la última [imagen de Docker](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Versiones con Etiquetas
Desde la versión `v2.x` puedes descargar imágenes de Docker [por etiquetas](https://hub.docker.com/r/verdaccio/verdaccio/tags/), a como se define aquí:
Since version `v2.x` you can pull docker images by [tag](https://hub.docker.com/r/verdaccio/verdaccio/tags/), as follows:
Para la versión mayor:
For a major version:
```bash
docker pull verdaccio/verdaccio:2
```
Para la versión menor:
For a minor version:
```bash
docker pull verdaccio/verdaccio:2.1
```
Para un (parche) especifico:
For a specific (patch) version:
```bash
docker pull verdaccio/verdaccio:2.1.7
```
Para el próximo mayor lanzamiento usando la versión `beta`.
For the next major release using the `beta` version.
```bash
docker pull verdaccio/verdaccio:beta
@ -40,19 +42,21 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Ejecutando verdaccio usando Docker
Para ejecutar el contenedor de Docker:
To run the docker container:
```bash
docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio
```
El último argumento define cual imagen se usará. La linea anterior descargara la ultima imagen desde dockerhub, si you no lo has echo aún.
The last argument defines which image to use. The above line will pull the latest prebuilt image from dockerhub, if you haven't done that already.
Si has[construido la imagen localmente](#build-your-own-docker-image)usa solamente ` http://www. verdaccio. org/verdaccio/` como último argumento.
If you have [build an image locally](#build-your-own-docker-image) use `verdaccio` as the last argument.
Puedes usar `-v` para montar ` conf` y ` storage` como volúmenes externos:
You can use `-v` to mount `conf` and `storage` to the hosts filesystem:
```bash
V_PATH=/path/for/verdaccio; docker run -it --rm --name verdaccio -p 4873:4873 \

@ -7,13 +7,14 @@ Verdaccio is a multiplatform web application, to install you need at least some
#### Prerequisites
1. Node higher than
- For version *2.x* we support from **4.6.1**
- For version *3.x* we support as minimum **6.12.0**
2. npm *>=3.x* or yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## Installing the CLI
`Verdaccio` must be install globaly using any of the most modern
`verdaccio` must be install globaly using any of the most modern
Using `npm`
@ -27,8 +28,6 @@ or using `yarn`
yarn global add verdaccio
```
> Warning: Verdaccio current is not support PM2's cluster mode, run it with cluster mode may cause unknown behavior
## Basic Usage
Once has been installed you only need to execute the CLI command.

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,7 +2,11 @@
id: webui
title: Web User Interface
---
Verdaccio contiene una interfaz web para mostrar paquetes privados, puede ser personalizable.
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml
web:

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ A linha de comando é por onde você pode controlar toda a sua instalação Verd
## Comandos
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| Comando | Padrão | Exemplo | Descrição |
| ------------------ | ------------------------------ | ------------- | ------------------------- |
| --listen \ **-l** | 4873 | -p 7000 | porta http |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | o arquivo de configuração |
| Comando | Padrão | Exemplo | Descrição |
| ------------------ | ------------------------------ | -------------- | ------------------------- |
| --listen \ **-l** | 4873 | -p 7000 | porta http |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | o arquivo de configuração |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>Since: <em>v2.3.6</em> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### URL Prefix
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
Since: *v2.3.6* due [#197](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### Max Body Size
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,7 +4,9 @@ title: Docker
---
To pull the latest pre-built [docker image](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Tagged Versions
@ -40,6 +42,8 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Running verdaccio using Docker
To run the docker container:

@ -7,13 +7,14 @@ Verdaccio is a multiplatform web application, to install you need at least some
#### Pré-requisitos
1. Node, acima da versão
- Para a versão *2.x* é suportado node a partir **4.6.1**
- Para a versão *3.x* é suportado node a partir **6.12.0**
2. npm *>=3.x* ou yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## Instação
`Verdaccio` must be install globaly using any of the most modern
`verdaccio` must be install globaly using any of the most modern
Usando `npm`
@ -27,8 +28,6 @@ ou usando `yarn`
yarn global add verdaccio
```
> Warning: Verdaccio current is not support PM2's cluster mode, run it with cluster mode may cause unknown behavior
## Como Usar
Assim que instalado, você só precisa executar um único comando na linha de comando.

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,6 +2,10 @@
id: webui
title: Web User Interface
---
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ The verdaccio CLI is your go start the application.
## Commands
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | ------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | the configuration file |
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | -------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | the configuration file |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>Since: <em>v2.3.6</em> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### URL Prefix
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
Since: *v2.3.6* due [#197](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### Max Body Size
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,7 +4,9 @@ title: Docker
---
To pull the latest pre-built [docker image](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Tagged Versions
@ -40,6 +42,8 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Running verdaccio using Docker
To run the docker container:

@ -7,13 +7,14 @@ Verdaccio is a multiplatform web application, to install you need at least some
#### Prerequisites
1. Node higher than
- For version *2.x* we support from **4.6.1**
- For version *3.x* we support as minimum **6.12.0**
2. npm *>=3.x* or yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## Installing the CLI
`Verdaccio` must be install globaly using any of the most modern
`verdaccio` must be install globaly using any of the most modern
Using `npm`
@ -27,8 +28,6 @@ or using `yarn`
yarn global add verdaccio
```
> Warning: Verdaccio current is not support PM2's cluster mode, run it with cluster mode may cause unknown behavior
## Basic Usage
Once has been installed you only need to execute the CLI command.

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,6 +2,10 @@
id: webui
title: Web User Interface
---
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ The verdaccio CLI is your go start the application.
## Commands
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | ------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | the configuration file |
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | -------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | the configuration file |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>Since: <em>v2.3.6</em> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### URL Prefix
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
Since: *v2.3.6* due [#197](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### Max Body Size
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,7 +4,9 @@ title: Docker
---
To pull the latest pre-built [docker image](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Tagged Versions
@ -40,6 +42,8 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Running verdaccio using Docker
To run the docker container:

@ -7,13 +7,14 @@ Verdaccio is a multiplatform web application, to install you need at least some
#### Prerequisites
1. Node higher than
- For version *2.x* we support from **4.6.1**
- For version *3.x* we support as minimum **6.12.0**
2. npm *>=3.x* or yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## Installing the CLI
`Verdaccio` must be install globaly using any of the most modern
`verdaccio` must be install globaly using any of the most modern
Using `npm`
@ -27,8 +28,6 @@ or using `yarn`
yarn global add verdaccio
```
> Warning: Verdaccio current is not support PM2's cluster mode, run it with cluster mode may cause unknown behavior
## Basic Usage
Once has been installed you only need to execute the CLI command.

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,6 +2,10 @@
id: webui
title: Web User Interface
---
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ Verdaccio 命令行是启动和控制此应用的工具
## 命令
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| 参数 | 默认值 | 示例 | 描述 |
| ------------------ | ------------------------------ | ------------- | --------- |
| --listen \ **-l** | 4873 | -p 7000 | HTTP 监听端口 |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | 配置文件路径 |
| 参数 | 默认值 | 示例 | 描述 |
| ------------------ | ------------------------------ | -------------- | --------- |
| --listen \ **-l** | 4873 | -p 7000 | HTTP 监听端口 |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | 配置文件路径 |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>最低版本: <em> v2.3.6 </em> 由于 <a href="https://github.com/verdaccio/verdaccio/pull/223"> #223 </a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### URL 前缀
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
最低版本: * v2.3.6 * 由于 [ #197 ](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### 最大 Body 尺寸
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"发布了新的包: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,7 +4,9 @@ title: Docker
---
To pull the latest pre-built [docker image](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Tagged Versions
@ -40,6 +42,8 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Running verdaccio using Docker
To run the docker container:

@ -7,13 +7,14 @@ Verdaccio 是一个基于 Web 技术的跨平台应用,在安装它之前你
#### 最低要求:
1. Node.js 版本
- Verdaccio *2.x*: 不低于 **4.6.1**
- Verdaccio *3.x* 不低于 **6.12.0**
2. npm *>=3.x* 或 yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## 安装
`Verdaccio` 必须通过以下任一方式作为全局模块安装
`verdaccio` must be install globaly using any of the most modern
使用 `npm`
@ -27,8 +28,6 @@ npm install -g verdaccio
yarn global add verdaccio
```
> 警告: Verdaccio 目前不支持 PM2 的 Cluster 多进程模式,通过此方式运行可能造成未知后果
## 基本使用
安装后只需要通过命令行启动即可使用

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,6 +2,10 @@
id: webui
title: Web User Interface
---
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````

@ -12,13 +12,13 @@ Verdaccio relies on `yarn` instead `npm` to download depenedencies.
## Scripts
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches. (yes
We have a list of scripts that you will use for diferent kind of tasks, in the following section we describe all posible task based on branches.
#### Master branch (2.x)
### Branch (2.x)
On master branch the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
On branch `2.x` the unique part we have to build is the UI which is based on React.js, webpack and CSS Modules.
### Scripts
#### Scripts
| script | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
@ -39,9 +39,9 @@ On master branch the unique part we have to build is the UI which is based on Re
| build:docker | create a local docker image with `verdaccio` |
| build:rpi | create a local docker for raspberry pi image with `verdaccio` **(experimental with no support)** |
#### Branch (3.x)
#### Master branch (3.x)
The next major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
The current major version is based on `babel` and `flow`. If you switch from master ensure to run `yarn install` again.
*Note: Only new scripts in bold*
@ -55,10 +55,12 @@ The next major version is based on `babel` and `flow`. If you switch from master
| release | this script is used to generate changelog and raise up the version according the commits messages |
| prepublish | it ensures before publish the new ui is being generated |
| test | run all the test `jest` |
| test:unit | run the unit test |
| test:func | run the funtional test |
| pre:ci | specific task for CI, build the UI required for test |
| pretest | A shorcut for transpile the code |
| test:ci | run test generating coverage |
| test:only | run only test |
| coverage:publish | publish on `codecov` the coverage (don't use it) |
| coverage:publish | publish on `codecov` the coverage (CI task specific, do not use it) |
| lint | run the linting for javascript code. |
| lint:css | run the linter for `css` |
| dev:webui | run a `webpack` server with hot reloading enabled `http://localhost:4872/#/` it requires a `verdaccio` server running in port `4873`. |

@ -7,10 +7,18 @@ The verdaccio CLI is your go start the application.
## Commands
```bash
$ verdaccio --listen 4000 --config ./config.yaml
$ verdaccio --listen 4000 --config ~./config.yaml
```
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | ------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~/config.yaml | the configuration file |
| Command | Default | Example | Description |
| ------------------ | ------------------------------ | -------------- | ---------------------- |
| --listen \ **-l** | 4873 | -p 7000 | http port |
| --config \ **-c** | ~/.local/verdaccio/config.yaml | ~./config.yaml | the configuration file |
## Default config file location
To locate the home directory, we rely on **$XDG_DATA_HOME** as a first choice and Windows environment we look for [APPDATA environment variable](https://www.howtogeek.com/318177/what-is-the-appdata-folder-in-windows/).
## Default storage location
We use **$XDG_DATA_HOME** environment variable as default to locate the storage by default which [should be the same](https://askubuntu.com/questions/538526/is-home-local-share-the-default-value-for-xdg-data-home-in-ubuntu-14-04) as $HOME/.local/share. If you are using a custom storage, this location is irrelevant.

@ -96,7 +96,7 @@ publish:
allow_offline: false
```
<small>Since: <em>v2.3.6</em> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
<small>Since: <code>verdaccio@2.3.6</code> due <a href="https://github.com/verdaccio/verdaccio/pull/223">#223</a></small>
### URL Prefix
@ -104,7 +104,7 @@ publish:
url_prefix: https://dev.company.local/verdaccio/
```
Since: *v2.3.6* due [#197](https://github.com/verdaccio/verdaccio/pull/197)
Since: `verdaccio@2.3.6` due [#197](https://github.com/verdaccio/verdaccio/pull/197)
### Max Body Size
@ -149,4 +149,6 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
```
```
> For more detailed configuration settings, please [check the source code](https://github.com/verdaccio/verdaccio/tree/master/conf).

@ -60,9 +60,9 @@ We have support for **Kubernetes**, **Puppet**, **Ansible** and **Chef** and we
### I can do translations
Verdaccio aims to be multilingual, in order to achieve it we have the awesome support of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
Verdaccio aims to be multilingual, in order to achieve it **we have the awesome support** of [Crowdin](https://crowdin.com) that is an amazing platform for translations.
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="100px" />
<img src="https://d3n8a8pro7vhmx.cloudfront.net/uridu/pages/144/attachments/original/1485948891/Crowdin.png" width="400px" />
We have setup a project where you can choose your favourite language, if you do not find your language feel free to request one [creating a ticket](https://github.com/verdaccio/verdaccio/issues/new).
@ -74,4 +74,82 @@ If you are thinking *"I've seen already the [repositories](repositories.md) and
You will need learn how to build, [we have prepared a guide just for that](build.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
Once you have played around with all scripts and you know how to use them, we are ready to go to the next step, run the [**Unit Test**](test.md).
## Full list of contributors. We want to see your face here !
| [<img alt="juanpicado" src="https://avatars0.githubusercontent.com/u/558752?v=4&s=117" width="117" />](https://github.com/juanpicado) | [<img alt="rlidwka" src="https://avatars0.githubusercontent.com/u/999113?v=4&s=117" width="117" />](https://github.com/rlidwka) | [<img alt="Meeeeow" src="https://avatars3.githubusercontent.com/u/19658647?v=4&s=117" width="117" />](https://github.com/Meeeeow) | [<img alt="trentearl" src="https://avatars2.githubusercontent.com/u/802857?v=4&s=117" width="117" />](https://github.com/trentearl) | [<img alt="ayusharma" src="https://avatars0.githubusercontent.com/u/6918450?v=4&s=117" width="117" />](https://github.com/ayusharma) |
|:-------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|
| [juanpicado](https://github.com/juanpicado) | [rlidwka](https://github.com/rlidwka) | [Meeeeow](https://github.com/Meeeeow) | [trentearl](https://github.com/trentearl) | [ayusharma](https://github.com/ayusharma) |
| [<img alt="verdacciobot" src="https://avatars0.githubusercontent.com/u/35213902?v=4&s=117" width="117" />](https://github.com/verdacciobot) | [<img alt="jmwilkinson" src="https://avatars0.githubusercontent.com/u/17836030?v=4&s=117" width="117" />](https://github.com/jmwilkinson) | [<img alt="UnitedMarsupials" src="https://avatars1.githubusercontent.com/u/1486340?v=4&s=117" width="117" />](https://github.com/UnitedMarsupials) | [<img alt="ryan-codingintrigue" src="https://avatars0.githubusercontent.com/u/9048902?v=4&s=117" width="117" />](https://github.com/ryan-codingintrigue) | [<img alt="ramonornela" src="https://avatars1.githubusercontent.com/u/187946?v=4&s=117" width="117" />](https://github.com/ramonornela) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|
| [verdacciobot](https://github.com/verdacciobot) | [jmwilkinson](https://github.com/jmwilkinson) | [UnitedMarsupials](https://github.com/UnitedMarsupials) | [ryan-codingintrigue](https://github.com/ryan-codingintrigue) | [ramonornela](https://github.com/ramonornela) |
| [<img alt="renovate-bot" src="https://avatars0.githubusercontent.com/u/25180681?v=4&s=117" width="117" />](https://github.com/renovate-bot) | [<img alt="rodriguesbreno" src="https://avatars2.githubusercontent.com/u/19731692?v=4&s=117" width="117" />](https://github.com/rodriguesbreno) | [<img alt="vernak2539" src="https://avatars2.githubusercontent.com/u/521270?v=4&s=117" width="117" />](https://github.com/vernak2539) | [<img alt="jachstet-sea" src="https://avatars0.githubusercontent.com/u/7993508?v=4&s=117" width="117" />](https://github.com/jachstet-sea) | [<img alt="lgaitan" src="https://avatars0.githubusercontent.com/u/5970350?v=4&s=117" width="117" />](https://github.com/lgaitan) |
|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|
| [renovate-bot](https://github.com/renovate-bot) | [rodriguesbreno](https://github.com/rodriguesbreno) | [vernak2539](https://github.com/vernak2539) | [jachstet-sea](https://github.com/jachstet-sea) | [lgaitan](https://github.com/lgaitan) |
| [<img alt="crispy1989" src="https://avatars1.githubusercontent.com/u/2132722?v=4&s=117" width="117" />](https://github.com/crispy1989) | [<img alt="neuquino" src="https://avatars1.githubusercontent.com/u/1971027?v=4&s=117" width="117" />](https://github.com/neuquino) | [<img alt="markpeterfejes" src="https://avatars3.githubusercontent.com/u/7912231?v=4&s=117" width="117" />](https://github.com/markpeterfejes) | [<img alt="steve-p-com" src="https://avatars3.githubusercontent.com/u/5180548?v=4&s=117" width="117" />](https://github.com/steve-p-com) | [<img alt="BartDubois" src="https://avatars0.githubusercontent.com/u/1180931?v=4&s=117" width="117" />](https://github.com/BartDubois) |
|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [crispy1989](https://github.com/crispy1989) | [neuquino](https://github.com/neuquino) | [markpeterfejes](https://github.com/markpeterfejes) | [steve-p-com](https://github.com/steve-p-com) | [BartDubois](https://github.com/BartDubois) |
| [<img alt="karfau" src="https://avatars1.githubusercontent.com/u/135657?v=4&s=117" width="117" />](https://github.com/karfau) | [<img alt="030" src="https://avatars1.githubusercontent.com/u/7524528?v=4&s=117" width="117" />](https://github.com/030) | [<img alt="Qwerios" src="https://avatars2.githubusercontent.com/u/254447?v=4&s=117" width="117" />](https://github.com/Qwerios) | [<img alt="wiggisser" src="https://avatars3.githubusercontent.com/u/3647678?v=4&s=117" width="117" />](https://github.com/wiggisser) | [<img alt="kfatehi" src="https://avatars1.githubusercontent.com/u/175305?v=4&s=117" width="117" />](https://github.com/kfatehi) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|
| [karfau](https://github.com/karfau) | [030](https://github.com/030) | [Qwerios](https://github.com/Qwerios) | [wiggisser](https://github.com/wiggisser) | [kfatehi](https://github.com/kfatehi) |
| [<img alt="imsnif" src="https://avatars3.githubusercontent.com/u/795598?v=4&s=117" width="117" />](https://github.com/imsnif) | [<img alt="denisbabineau" src="https://avatars2.githubusercontent.com/u/12616025?v=4&s=117" width="117" />](https://github.com/denisbabineau) | [<img alt="HCanber" src="https://avatars2.githubusercontent.com/u/800302?v=4&s=117" width="117" />](https://github.com/HCanber) | [<img alt="jgoz" src="https://avatars2.githubusercontent.com/u/132233?v=4&s=117" width="117" />](https://github.com/jgoz) | [<img alt="josephg" src="https://avatars1.githubusercontent.com/u/47413?v=4&s=117" width="117" />](https://github.com/josephg) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [imsnif](https://github.com/imsnif) | [denisbabineau](https://github.com/denisbabineau) | [HCanber](https://github.com/HCanber) | [jgoz](https://github.com/jgoz) | [josephg](https://github.com/josephg) |
| [<img alt="kba" src="https://avatars0.githubusercontent.com/u/273367?v=4&s=117" width="117" />](https://github.com/kba) | [<img alt="aledbf" src="https://avatars2.githubusercontent.com/u/161571?v=4&s=117" width="117" />](https://github.com/aledbf) | [<img alt="drubin" src="https://avatars0.githubusercontent.com/u/237513?v=4&s=117" width="117" />](https://github.com/drubin) | [<img alt="plitex" src="https://avatars3.githubusercontent.com/u/2946823?v=4&s=117" width="117" />](https://github.com/plitex) | [<img alt="nedelenbos" src="https://avatars2.githubusercontent.com/u/6542243?v=4&s=117" width="117" />](https://github.com/nedelenbos) |
|:-----------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [kba](https://github.com/kba) | [aledbf](https://github.com/aledbf) | [drubin](https://github.com/drubin) | [plitex](https://github.com/plitex) | [nedelenbos](https://github.com/nedelenbos) |
| [<img alt="mysiar" src="https://avatars3.githubusercontent.com/u/13708162?v=4&s=117" width="117" />](https://github.com/mysiar) | [<img alt="bufferoverflow" src="https://avatars2.githubusercontent.com/u/378909?v=4&s=117" width="117" />](https://github.com/bufferoverflow) | [<img alt="osher" src="https://avatars0.githubusercontent.com/u/803101?v=4&s=117" width="117" />](https://github.com/osher) | [<img alt="danielo515" src="https://avatars2.githubusercontent.com/u/2270425?v=4&s=117" width="117" />](https://github.com/danielo515) | [<img alt="marnel" src="https://avatars3.githubusercontent.com/u/3189424?v=4&s=117" width="117" />](https://github.com/marnel) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [mysiar](https://github.com/mysiar) | [bufferoverflow](https://github.com/bufferoverflow) | [osher](https://github.com/osher) | [danielo515](https://github.com/danielo515) | [marnel](https://github.com/marnel) |
| [<img alt="aszmyd" src="https://avatars2.githubusercontent.com/u/3050805?v=4&s=117" width="117" />](https://github.com/aszmyd) | [<img alt="estliberitas" src="https://avatars2.githubusercontent.com/u/568962?v=4&s=117" width="117" />](https://github.com/estliberitas) | [<img alt="Alexandre-io" src="https://avatars0.githubusercontent.com/u/8135542?v=4&s=117" width="117" />](https://github.com/Alexandre-io) | [<img alt="amirmohsen" src="https://avatars1.githubusercontent.com/u/7075106?v=4&s=117" width="117" />](https://github.com/amirmohsen) | [<img alt="BarthV" src="https://avatars3.githubusercontent.com/u/1901955?v=4&s=117" width="117" />](https://github.com/BarthV) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|
| [aszmyd](https://github.com/aszmyd) | [estliberitas](https://github.com/estliberitas) | [Alexandre-io](https://github.com/Alexandre-io) | [amirmohsen](https://github.com/amirmohsen) | [BarthV](https://github.com/BarthV) |
| [<img alt="BogdanAlexandru" src="https://avatars2.githubusercontent.com/u/5050074?v=4&s=117" width="117" />](https://github.com/BogdanAlexandru) | [<img alt="iambrandonn" src="https://avatars2.githubusercontent.com/u/1644549?v=4&s=117" width="117" />](https://github.com/iambrandonn) | [<img alt="robi-wan" src="https://avatars3.githubusercontent.com/u/30210?v=4&s=117" width="117" />](https://github.com/robi-wan) | [<img alt="crohrer" src="https://avatars3.githubusercontent.com/u/1255222?v=4&s=117" width="117" />](https://github.com/crohrer) | [<img alt="psychocode" src="https://avatars3.githubusercontent.com/u/4641709?v=4&s=117" width="117" />](https://github.com/psychocode) |
|:------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [BogdanAlexandru](https://github.com/BogdanAlexandru) | [iambrandonn](https://github.com/iambrandonn) | [robi-wan](https://github.com/robi-wan) | [crohrer](https://github.com/crohrer) | [psychocode](https://github.com/psychocode) |
| [<img alt="conorhastings" src="https://avatars2.githubusercontent.com/u/8263298?v=4&s=117" width="117" />](https://github.com/conorhastings) | [<img alt="coreyjewett" src="https://avatars3.githubusercontent.com/u/12782?v=4&s=117" width="117" />](https://github.com/coreyjewett) | [<img alt="dbroadhurst" src="https://avatars1.githubusercontent.com/u/5667105?v=4&s=117" width="117" />](https://github.com/dbroadhurst) | [<img alt="etiennetremel" src="https://avatars1.githubusercontent.com/u/995474?v=4&s=117" width="117" />](https://github.com/etiennetremel) | [<img alt="einfallstoll" src="https://avatars3.githubusercontent.com/u/619048?v=4&s=117" width="117" />](https://github.com/einfallstoll) |
|:--------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:|
| [conorhastings](https://github.com/conorhastings) | [coreyjewett](https://github.com/coreyjewett) | [dbroadhurst](https://github.com/dbroadhurst) | [etiennetremel](https://github.com/etiennetremel) | [einfallstoll](https://github.com/einfallstoll) |
| [<img alt="gempain" src="https://avatars2.githubusercontent.com/u/13135149?v=4&s=117" width="117" />](https://github.com/gempain) | [<img alt="lbguilherme" src="https://avatars0.githubusercontent.com/u/546954?v=4&s=117" width="117" />](https://github.com/lbguilherme) | [<img alt="gecruz" src="https://avatars1.githubusercontent.com/u/29457476?v=4&s=117" width="117" />](https://github.com/gecruz) | [<img alt="idangozlan" src="https://avatars3.githubusercontent.com/u/1991021?v=4&s=117" width="117" />](https://github.com/idangozlan) | [<img alt="jrussellsmyth" src="https://avatars3.githubusercontent.com/u/2998207?v=4&s=117" width="117" />](https://github.com/jrussellsmyth) |
|:---------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|
| [gempain](https://github.com/gempain) | [lbguilherme](https://github.com/lbguilherme) | [gecruz](https://github.com/gecruz) | [idangozlan](https://github.com/idangozlan) | [jrussellsmyth](https://github.com/jrussellsmyth) |
| [<img alt="jirutka" src="https://avatars1.githubusercontent.com/u/949228?v=4&s=117" width="117" />](https://github.com/jirutka) | [<img alt="kingjan1999" src="https://avatars3.githubusercontent.com/u/3208269?v=4&s=117" width="117" />](https://github.com/kingjan1999) | [<img alt="vStone" src="https://avatars2.githubusercontent.com/u/356719?v=4&s=117" width="117" />](https://github.com/vStone) | [<img alt="zaventh" src="https://avatars1.githubusercontent.com/u/669283?v=4&s=117" width="117" />](https://github.com/zaventh) | [<img alt="jeremymoritz" src="https://avatars3.githubusercontent.com/u/2779583?v=4&s=117" width="117" />](https://github.com/jeremymoritz) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
| [jirutka](https://github.com/jirutka) | [kingjan1999](https://github.com/kingjan1999) | [vStone](https://github.com/vStone) | [zaventh](https://github.com/zaventh) | [jeremymoritz](https://github.com/jeremymoritz) |
| [<img alt="jondlm" src="https://avatars2.githubusercontent.com/u/3290587?v=4&s=117" width="117" />](https://github.com/jondlm) | [<img alt="speier" src="https://avatars3.githubusercontent.com/u/415836?v=4&s=117" width="117" />](https://github.com/speier) | [<img alt="kodypeterson" src="https://avatars1.githubusercontent.com/u/1934708?v=4&s=117" width="117" />](https://github.com/kodypeterson) | [<img alt="mrblackus" src="https://avatars3.githubusercontent.com/u/2353980?v=4&s=117" width="117" />](https://github.com/mrblackus) | [<img alt="metaa" src="https://avatars3.githubusercontent.com/u/5056880?v=4&s=117" width="117" />](https://github.com/metaa) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:|
| [jondlm](https://github.com/jondlm) | [speier](https://github.com/speier) | [kodypeterson](https://github.com/kodypeterson) | [mrblackus](https://github.com/mrblackus) | [metaa](https://github.com/metaa) |
| [<img alt="bajtos" src="https://avatars1.githubusercontent.com/u/1140553?v=4&s=117" width="117" />](https://github.com/bajtos) | [<img alt="okv" src="https://avatars3.githubusercontent.com/u/465522?v=4&s=117" width="117" />](https://github.com/okv) | [<img alt="Vrtak-CZ" src="https://avatars1.githubusercontent.com/u/112567?v=4&s=117" width="117" />](https://github.com/Vrtak-CZ) | [<img alt="rafacesar" src="https://avatars3.githubusercontent.com/u/71136?v=4&s=117" width="117" />](https://github.com/rafacesar) | [<img alt="rbpinheiro" src="https://avatars2.githubusercontent.com/u/1257483?v=4&s=117" width="117" />](https://github.com/rbpinheiro) |
|:------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [bajtos](https://github.com/bajtos) | [okv](https://github.com/okv) | [Vrtak-CZ](https://github.com/Vrtak-CZ) | [rafacesar](https://github.com/rafacesar) | [rbpinheiro](https://github.com/rbpinheiro) |
| [<img alt="r3wald" src="https://avatars3.githubusercontent.com/u/190202?v=4&s=117" width="117" />](https://github.com/r3wald) | [<img alt="robertgroh" src="https://avatars3.githubusercontent.com/u/5773739?v=4&s=117" width="117" />](https://github.com/robertgroh) | [<img alt="prssn" src="https://avatars1.githubusercontent.com/u/951218?v=4&s=117" width="117" />](https://github.com/prssn) | [<img alt="RodrigoBalest" src="https://avatars0.githubusercontent.com/u/4810463?v=4&s=117" width="117" />](https://github.com/RodrigoBalest) | [<img alt="RomainLK" src="https://avatars3.githubusercontent.com/u/1440514?v=4&s=117" width="117" />](https://github.com/RomainLK) |
|:-----------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|
| [r3wald](https://github.com/r3wald) | [robertgroh](https://github.com/robertgroh) | [prssn](https://github.com/prssn) | [RodrigoBalest](https://github.com/RodrigoBalest) | [RomainLK](https://github.com/RomainLK) |
| [<img alt="rmg" src="https://avatars2.githubusercontent.com/u/17978?v=4&s=117" width="117" />](https://github.com/rmg) | [<img alt="samcday" src="https://avatars0.githubusercontent.com/u/531550?v=4&s=117" width="117" />](https://github.com/samcday) | [<img alt="tarun1793" src="https://avatars0.githubusercontent.com/u/1783440?v=4&s=117" width="117" />](https://github.com/tarun1793) | [<img alt="tcort" src="https://avatars3.githubusercontent.com/u/216720?v=4&s=117" width="117" />](https://github.com/tcort) | [<img alt="grrowl" src="https://avatars2.githubusercontent.com/u/907140?v=4&s=117" width="117" />](https://github.com/grrowl) |
|:----------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| [rmg](https://github.com/rmg) | [samcday](https://github.com/samcday) | [tarun1793](https://github.com/tarun1793) | [tcort](https://github.com/tcort) | [grrowl](https://github.com/grrowl) |
| [<img alt="tlvince" src="https://avatars2.githubusercontent.com/u/323761?v=4&s=117" width="117" />](https://github.com/tlvince) | [<img alt="lordvlad" src="https://avatars2.githubusercontent.com/u/1217769?v=4&s=117" width="117" />](https://github.com/lordvlad) | [<img alt="wpasternak" src="https://avatars3.githubusercontent.com/u/958449?v=4&s=117" width="117" />](https://github.com/wpasternak) | [<img alt="yannickcr" src="https://avatars2.githubusercontent.com/u/13209?v=4&s=117" width="117" />](https://github.com/yannickcr) | [<img alt="yannickglt" src="https://avatars0.githubusercontent.com/u/1006426?v=4&s=117" width="117" />](https://github.com/yannickglt) |
|:-------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|
| [tlvince](https://github.com/tlvince) | [lordvlad](https://github.com/lordvlad) | [wpasternak](https://github.com/wpasternak) | [yannickcr](https://github.com/yannickcr) | [yannickglt](https://github.com/yannickglt) |
| [<img alt="silkentrance" src="https://avatars3.githubusercontent.com/u/6068824?v=4&s=117" width="117" />](https://github.com/silkentrance) | [<img alt="jjaakola" src="https://avatars3.githubusercontent.com/u/3587824?v=4&s=117" width="117" />](https://github.com/jjaakola) | [<img alt="maxlaverse" src="https://avatars0.githubusercontent.com/u/3045354?v=4&s=117" width="117" />](https://github.com/maxlaverse) | [<img alt="ChadKillingsworth" src="https://avatars2.githubusercontent.com/u/1247639?v=4&s=117" width="117" />](https://github.com/ChadKillingsworth) |
|:------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------------------:|
| [silkentrance](https://github.com/silkentrance) | [jjaakola](https://github.com/jjaakola) | [maxlaverse](https://github.com/maxlaverse) | [ChadKillingsworth](https://github.com/ChadKillingsworth) |

@ -2,12 +2,20 @@
id: dev-plugins
title: Developing Plugins
---
There are many ways to extend `verdaccio`, currently we only support `authentication plugins`
There are many ways to extend `verdaccio`, currently we support `authentication plugins`, `middleware plugins` (since `v2.7.0`) and `storage plugins` since (`v3.x`).
## Authentication Plugins
This section will describe how it looks like a Verdaccio plugin in a ES5 way. Basically we have to return an object with a single method called `authenticate` that will recieve 3 arguments (`user, password, callback`). Once the authentication has been executed there is 2 options to give a response to `verdaccio`.
### API
```js
function authenticate (user, password, callback) {
...more stuff
}
```
##### OnError
Either something bad happened or auth was unsuccessful.
@ -57,10 +65,75 @@ Auth.prototype.authenticate = function (user, password, callback) {
module.exports = Auth;
```
## Storage Plugins
And the setup
// in progress
```yaml
auth:
htpasswd:
file: ./htpasswd
```
Where `htpasswd` is the sufix of the plugin name. eg: `verdaccio-htpasswd` and the rest of the body would be the plugin configuration params.
## Middleware Integration
// in progress
Middleware plugins have the capability to modify the API layer, either adding new endpoints or intercepting requests. A pretty good example of middleware plugin is the (sinopia-github-oauth)[https://github.com/soundtrackyourbrand/sinopia-github-oauth]) compatible with `verdaccio`.
### API
```js
function register_middlewares(expressApp, auth, storage) {
...more stuff
}
```
To register a middleware we need an object with a single method called `register_middlewares` that will recieve 3 arguments (`expressApp, auth, storage`). *Auth* is the authentification instance and *storage* is also the main Storage instance that will give you have access to all to the storage actions.
## Storage Plugins
Since `verdaccio@3.x` we also can plug a custom storage.
### API
The storage API is a bit more complex, you will need to create a class that return a `ILocalData` implementation. Please see details bellow.
```js
<br />class LocalDatabase<ILocalData>{
constructor(config: Config, logger: Logger): ILocalData;
}
interface ILocalData {
add(name: string): SyncReturn;
remove(name: string): SyncReturn;
get(): StorageList;
getPackageStorage(packageInfo: string): IPackageStorage;
sync(): ?SyncReturn;
}
interface ILocalPackageManager {
writeTarball(name: string): IUploadTarball;
readTarball(name: string): IReadTarball;
readPackage(fileName: string, callback: Callback): void;
createPackage(name: string, value: any, cb: Callback): void;
deletePackage(fileName: string, callback: Callback): void;
removePackage(callback: Callback): void;
updatePackage(pkgFileName: string,
updateHandler: Callback,
onWrite: Callback,
transformPackage: Function,
onEnd: Callback): void;
savePackage(fileName: string, json: Package, callback: Callback): void;
}
interface IUploadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
interface IReadTarball extends stream$PassThrough {
abort(): void;
done(): void;
}
```
> This API still is experimental and might change next minor versions. The default [LocalStorage plugin](https://github.com/verdaccio/local-storage) it comes built-in in `verdaccio` and it is being loaded if any storage plugin has been defined.

@ -4,7 +4,9 @@ title: Docker
---
To pull the latest pre-built [docker image](https://hub.docker.com/r/verdaccio/verdaccio/):
`docker pull verdaccio/verdaccio`
```bash
docker pull verdaccio/verdaccio
```
## Tagged Versions
@ -40,6 +42,8 @@ The Canary version (master branch) is tagged as `alpha`
docker pull verdaccio/verdaccio:alpha
```
> If you are interested on a list of tags, [please visit the Docker Hub website](https://hub.docker.com/r/verdaccio/verdaccio/tags/).
## Running verdaccio using Docker
To run the docker container:

@ -7,13 +7,14 @@ Verdaccio is a multiplatform web application, to install you need at least some
#### Prerequisites
1. Node higher than
- For version *2.x* we support from **4.6.1**
- For version *3.x* we support as minimum **6.12.0**
2. npm *>=3.x* or yarn
- For version `verdaccio@2.x` we support from Node `v4.6.1`.
- For version `verdaccio@3.x` we support as minimum Node `6.12.0`
2. npm `>=3.x` or `yarn`
3. The web interface support browsers `Chrome, Firefox, Edge, and IE9`
## Installing the CLI
`Verdaccio` must be install globaly using any of the most modern
`verdaccio` must be install globaly using any of the most modern
Using `npm`
@ -27,8 +28,6 @@ or using `yarn`
yarn global add verdaccio
```
> Warning: Verdaccio current is not support PM2's cluster mode, run it with cluster mode may cause unknown behavior
## Basic Usage
Once has been installed you only need to execute the CLI command.

@ -2,7 +2,7 @@
id: node-api
title: Node API
---
Verdaccio can be invoqued programmatically.
Verdaccio can be invoqued programmatically. The node API was introduced after version `verdaccio@3.0.0-alpha.10`.
## Usage

@ -4,25 +4,25 @@ title: Source Code
---
`verdaccio` is composed or multiple repositories you might contribute. Look into the **issues** tab whether there is a ticket waiting for you
| Repository | Usage | Stack |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| Repository | Usage | Stack |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| <https://github.com/verdaccio/verdaccio> | The main repository | Node, Express, async, React, Babel, ES6, Mocha, Markdown, HTML, Sass |
| <https://github.com/verdaccio/streams> | Small library to handle streams | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/file-locking> | Small library to handle locked files | ES6, Babel, *Soon: Flow* |
| <https://github.com/verdaccio/local-storage> | Default dependency for verdaccio to handle local file system storage (since `v3.x`) | ES6, Babel, Flow |
| <https://github.com/verdaccio/flow-types> | `flow` type definitions for verdaccio and sub dependencies. | Flow, flow-typed |
| <https://github.com/verdaccio/verdaccio.github.io> | Public `verdaccio` website and future documentation page. | Markdown, HTML, Sass, Github Pages |
| <https://github.com/verdaccio/docker-examples> | Docker examples with `docker-compose` to play around with integrations, (nginx, kubernetes, apache, ldap, etc..) | Docker Compose, Docker |
| <https://github.com/verdaccio/puppet-verdaccio> | Puppet support | Puppet |
| <https://github.com/verdaccio/ansible-verdaccio> | Ansible support | Ansible |
| <https://github.com/verdaccio/verdaccio-cookbook> | Chef support | Chef |
| <https://github.com/chainlink/charts/tree/master/stable/verdaccio> | Kubernetes support | Kubernetes |
## Experimental Repos
The following repositories aims to be part of the future infraestructure of `verdaccio` and are just PoC looking for active colaborators.
| Repository | Usage | Stack |
| ------------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-plugin-auth-htpasswd> | Default authentification plugin based on Babel | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |
| <https://github.com/verdaccio/blog> | Any article related with verdaccio | Markdown |
| Repository | Usage | Stack |
| --------------------------------------------------------- | ---------------------------------------------- | ------------------ |
| <https://github.com/verdaccio/verdaccio-memory> | An experimental storage in memory | ES6, Babel, Flow |
| <https://github.com/verdaccio/generator-verdaccio-plugin> | Yeoman generators for future verdaccio plugins | ES6, Babel, Yeoman |

@ -6,7 +6,7 @@ All tests are split in three folders:
- `test/unit` - Tests that cover functions that transform data in an non-trivial way. These tests simply `require()` a few files and run code in there, so they are very fast.
- `test/functional` - Tests that launch a verdaccio instance and perform a series of requests to it over http. They are slower than unit tests.
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **This actually has not been tested or
- `test/integration` - Tests that launch a verdaccio instance and do requests to it using npm. They are really slow and can hit a real npm registry. **unmaintained test**
Unit and functional tests are executed automatically by running `npm test` from the project's root directory. Integration tests are supposed to be executed manually from time to time.
@ -23,22 +23,29 @@ That will trigger only two first groups of test, unit and functional.
### Using test/unit
The following is just an example how a unit test should looks like. Basically follow the `mocha` standard. Try to describe what exactly does the unit test in a single sentence in the header of the `it` section.
The following is just an example how a unit test should looks like. Basically follow the `jest` standard.
Try to describe what exactly does the unit test in a single sentence in the header of the `test` section.
```javacript
'use strict';
const verdaccio = require('../../src/api/index');
const config = require('./partials/config');
let assert = require('assert');
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('basic system test', () => {
describe('Parse interval', function() {
before(function(done) {
..... some magic stuff before the show
});
beforeAll(function(done) {
// something important
});
it('server should respond on /', function(done) {
... this is an async test
});});
afterAll((done) => {
// undo something important
});
test('server should respond on /', done => {
// your test
done();
});
});
```
### Using test/functional
@ -48,108 +55,80 @@ Funtional testing in verdaccio has a bit more of complextity that needs a deep e
All starts in the `index.js` file. Let's dive in into it.
```javascript
// create 3 server instances
require('./lib/startup');
...
// we create 3 server instances
const config1 = new VerdaccioConfig(
'./store/test-storage',
'./store/config-1.yaml',
'http://localhost:55551/');
const config2 = new VerdaccioConfig(
'./store/test-storage2',
'./store/config-2.yaml',
'http://localhost:55552/');
const config3 = new VerdaccioConfig(
'./store/test-storage3',
'./store/config-3.yaml',
'http://localhost:55553/');
const server1: IServerBridge = new Server(config1.domainPath);
const server2: IServerBridge = new Server(config2.domainPath);
const server3: IServerBridge = new Server(config3.domainPath);
const process1: IServerProcess = new VerdaccioProcess(config1, server1, SILENCE_LOG);
const process2: IServerProcess = new VerdaccioProcess(config2, server2, SILENCE_LOG);
const process3: IServerProcess = new VerdaccioProcess(config3, server3, SILENCE_LOG);
const express: any = new ExpressServer();
...
describe('functional test verdaccio', function() {
// recover the server instances
const server = process.server;
const server2 = process.server2;
const server3 = process.server3;
// On start initialise 3 verdaccio servers
before(function(done) {
Promise.all([
require('./lib/startup').start('./store/test-storage', '/store/config-1.yaml'),
require('./lib/startup').start('./store/test-storage2', '/store/config-2.yaml'),
require('./lib/startup').start('./store/test-storage3', '/store/config-3.yaml'),
]).then(() => {
done();
}).catch(function(error) {
console.error("error on start servers", error);
// we check whether all instances has been started, since run in independent processes
beforeAll((done) => {
Promise.all([
process1.init(),
process2.init(),
process3.init()]).then((forks) => {
_.map(forks, (fork) => {
processRunning.push(fork[0]);
});
express.start(EXPRESS_PORT).then((app) =>{
done();
}, (err) => {
done(err);
});
}).catch((error) => {
done(error);
});
});
});
before(function() {
return Promise.all([server, server2, server3].map(function(server) {
// save a lsof -p output in order to compare on finish on finish all test
}));
});
..........
// here is the unique line you should add, the new functional test.
require('./my-functional-test.js')();
// On finish kill all server
after(function(done) {
Promise.all([check(server), check(server2), check(server3)]).then(function() {
done();
}, (reason) => {
assert.equal(reason, null);
done();
// after finish all, we ensure are been stoped
afterAll(() => {
_.map(processRunning, (fork) => {
fork.stop();
});
express.server.close();
});
});
});
```
Perhaps this is not he best approach, but, it's how works right now. So, you just learnt how the bootstrap works and how to add a new group of functional tests.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `process.server;`, `process.server2;` and ``process.server3;`.
Using such reference you will be able to send request to any of the 3 instance running.
#### The lib/startup.js
The startup file is the responsable to create the 3 verdaccio instances and inject them to the `process.x` global variable.
#### The lib/request.js
This module holds a `PromiseAssert` which extends from `Promise` adding methods to handle all request from `lib/server.js`.
### Usage
Here we are gonna describe how it looks like an usual functional test, check inline for more detail information.
#### The lib/server.js
The server class is just a wrapper that simulates a `npm` client and provides a simple API for the funtional test.
As we mention in the previous section, we are creating 3 process servers that are accessible in each process as `server1`, `server2` and ``server3`.
Using such reference you will be able to send request to any of the 3 instance running.
```javascript
'use strict';
module.exports = function() {
// you can access the 3 instance through process global variables
const server = process.server;
const server2 = process.server2;
describe('my-functional-group-test', function() {
before(function() {
// create a raw emtpy package
const pkg = require('./fixtures/package')('new-package');
return server.putPackage('new-package', pkg)
// check whether was uploaded correctly
.status(201)
// check whether body response is ok
.body_ok(/created new package/);
});
// since before are not registred, we use emtpy it to display before putPackage was success
it('creating new package / srv1', function() {});
it('should do something else here ..... ', function() {
// this should fails since fakeVersion does not exist
// note we use server2 because is an uplink of server 1
return server2.getTarball('new-package', 'fakeVersion')
.status(404)
.body_error(/no such file/);
});
<br />export default function(server) {
// we recieve any server instance via arguments
test('add tag - 404', () => {
// we interact with the server instance.
return server.addTag('testpkg-tag', 'tagtagtag', '0.0.1').status(404).body_error(/no such package/);
});
};
});
```
### Test/integration
These section never has been used, but we are looking for help to make it run properly. All new ideas are very welcome.
These section never has been used, but we are looking for help to make it run properly. **All new ideas are very welcome.**

@ -4,6 +4,8 @@ title: Uplinks
---
An *uplink* is a link with an external registry that provides acccess to external packages.
![Uplinks](/img/uplinks.png)
### Usage
```yaml
@ -23,21 +25,21 @@ uplinks:
You can define mutiple uplinks and each of them must have an unique name (key). They can have two properties:
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | -------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
| Property | Type | Required | Example | Support | Description | Default |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| url | string | Yes | https://registry.npmjs.org/ | all | The registry url | npmjs |
| ca | string | No | ~./ssl/client.crt' | all | SSL path certificate | No default |
| timeout | string | No | 100ms | all | set new timeout for the request | 30s |
| maxage | string | No | 10m | all | limit maximun failure request | 2m |
| fail_timeout | string | No | 10m | all | defines max time when a request becomes a failure | 5m |
| max_fails | number | No | 2 | all | limit maximun failure request | 2 |
| cache | boolean | No | [true,false] | >= 2.1 | avoid cache tarballs | true |
| auth | list | No | type: [bearer,basic], [token: "token",token_env: [true,\<get name process.env\>]] | >= 2.5 | assigns the header 'Authorization' see: http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules | disabled |
| headers | list | No | authorization: "Basic YourBase64EncodedCredentials==" | all | list of custom headers for the uplink | disabled |
### You Must know
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, *sinopia@1.4.0*, *npmjs registry*, *yarn registry* and more.
* Setting `cache` to false will help to save space in your hard drive.
* Uplinks must be registries compatible with the `npm` endpoints. Eg: *verdaccio*, `sinopia@1.4.0`, *npmjs registry*, *yarn registry*, *JFrog*, *Nexus* and more.
* Setting `cache` to false will help to save space in your hard drive. This will avoid store `tarballs` but [it will keep metadata in folders](https://github.com/verdaccio/verdaccio/issues/391).
* Exceed with multiple uplinks might slow down the lookup of your packages due for each request a npm client does, verdaccio does 1 call for each uplink.
* The (timeout, maxage and fail_timeout) format follow the [NGINX measurement units](http://nginx.org/en/docs/syntax.html)

@ -2,6 +2,10 @@
id: webui
title: Web User Interface
---
<p align="center"><img src="https://firebasestorage.googleapis.com/v0/b/jotadeveloper-website.appspot.com/o/verdaccio_long_video2.gif?alt=media&token=4d20cad1-f700-4803-be14-4b641c651b41"></p>
Verdaccio has a web user interface to display only the private packges and can be customisable.
```yaml

@ -0,0 +1,28 @@
---
id: what-is-verdaccio
title: What is Verdaccio?
---
## In a nutshell
* It's a web app based on Node.js
* It's a private npm registry
* It's a local network proxy
* It's a Pluggable application
* It's a fairly easy install and use
* We offer Docker and Kubernetes support
* It is 100% compatible with yarn, npm and pnpm
* It was born based on `sinopia@1.4.0` fork and *backward compatible*
* Verdaccio means **A green color popular in late medieval Italy for fresco painting**.
## What's a registry
* A repository for packages that implements the CommonJS Compliant Package Registry specification for reading package info
* Store npm packages
* Provide an API compatible with npm clients
* Semantic Versioning (semver) compatible
```bash curl -v https://registry.npmjs.org/aaa
* Connected to registry.npmjs.org (151.101.12.162) port 443 (#0)
* Connection #0 to host registry.npmjs.org left intact {"_id":"aaa","_rev":"6-ad86dfc8720569871753b5bf561f2741","name":"aaa","description":"aaa...","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"aaa","version":"0.0.1","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.1","dist": {"shasum":"a04fa88ad887a70dd5429652ce23823619dfd7c3","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.1.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}},"0.0.2":{"name":"aaa","version":"0.0.2","description":"aaa...","main":"index.js","scripts":{"test":"test.js"},"repository":{"type":"git","url":"http:/www.google.git"},"keywords":["math"],"author":{"name":"peter"},"license":"BSD","_id":"aaa@0.0.2","dist": {"shasum":"acd2f632b94b0f89765e75bb7b7549ce5b01caa2","tarball":"https://registry.npmjs.org/aaa/-/aaa-0.0.2.tgz"},"_npmVersion":"1.1.62","_npmUser":{"name":"erhu65","email":"erhu65@gmail.com"},"maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"directories":{}}},"readme":"ERROR: No README.md file found!","maintainers":[{"name":"erhu65","email":"erhu65@gmail.com"}],"timmacbook-j:verdaccio.mmacbookmacbook-j:verdaccio.master.git jpicmacbook-j:verdaccio.master.git jpicmacbookmacbookmacbookmacbookmacbook ````