mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-02-17 03:19:36 +01:00
docs: add pages to ui components (#3557)
* rename method * Update ui-components.md * clean up jest * docs: add pages to ui components * Update ui-components.yml * chore: add some example docs
This commit is contained in:
parent
ce13b55693
commit
a1f78368c4
7
.github/workflows/ui-components.yml
vendored
7
.github/workflows/ui-components.yml
vendored
@ -13,6 +13,9 @@ on:
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
env:
|
||||
DEBUG: verdaccio*
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
permissions:
|
||||
@ -54,7 +57,7 @@ jobs:
|
||||
run: cp -R packages/ui-components/public/* packages/ui-components/storybook-static
|
||||
- name: 🔥 Deploy Production UI Netlify
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'workflow_dispatch'
|
||||
uses: verdaccio/action-netlify-deploy@v1.0.0
|
||||
uses: verdaccio/action-netlify-deploy@v2.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
netlify-auth-token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
@ -62,7 +65,7 @@ jobs:
|
||||
build-dir: './packages/ui-components/storybook-static'
|
||||
- name: 🤖 Deploy Preview UI Components Netlify
|
||||
if: github.repository == 'verdaccio/verdaccio'
|
||||
uses: verdaccio/action-netlify-deploy@v1.0.0
|
||||
uses: verdaccio/action-netlify-deploy@v2.0.0
|
||||
id: netlify_preview_ui
|
||||
with:
|
||||
draft: true
|
||||
|
@ -89,11 +89,7 @@ const App: React.FC = () => {
|
||||
}, []);
|
||||
return (
|
||||
<StrictMode>
|
||||
<TranslatorProvider
|
||||
i18n={i18n}
|
||||
listLanguages={listLanguages}
|
||||
loadDayJSLocale={loadDayJSLocale}
|
||||
>
|
||||
<TranslatorProvider i18n={i18n} listLanguages={listLanguages} onMount={loadDayJSLocale}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<StyledBox display="flex" flexDirection="column" height="100%">
|
||||
<Router history={history}>
|
||||
|
@ -33,7 +33,7 @@ export const parameters = {
|
||||
// required by AppConfigurationProvider
|
||||
export const withMuiTheme = (Story) => (
|
||||
<Provider store={store}>
|
||||
<TranslatorProvider loadDayJSLocale={() => {}} i18n={config} listLanguages={listLanguages}>
|
||||
<TranslatorProvider onMount={() => {}} i18n={config} listLanguages={listLanguages}>
|
||||
<AppConfigurationProvider>
|
||||
<ThemeProvider>
|
||||
<StyleBaseline />
|
||||
|
103
packages/ui-components/README.md
Normal file
103
packages/ui-components/README.md
Normal file
@ -0,0 +1,103 @@
|
||||
# UI Components
|
||||
|
||||
A collection of components ready to use for building complex user interfaces.
|
||||
|
||||
- `components`: Independent components to use to build different layouts, all components are based on [MUI (Material UI)](https://mui.com/).
|
||||
- `providers`: Providers are useful components that uses the React [`Context`](https://reactjs.org/docs/context.html), for instance, the `VersionProvider` connects the Redux store with independent components. The `AppConfigurationProvider` is able to read the
|
||||
- `store`: The Redux store powered by [`Rematch`](https://rematchjs.org), could be used with the global object `__VERDACCIO_BASENAME_UI_OPTIONS` that verdaccio uses to provide the UI configuration.
|
||||
- `theme`: The `ThemeProvider` is an abstraction of the _material-ui_ theme provider.
|
||||
- `sections`: A group of components to setup quickly sections of the application, like the sidebar, header of footer.
|
||||
- `layouts`: Are the combination of one or more sections ready to use.
|
||||
- `hooks`: A collection of useful React hooks.
|
||||
|
||||
```bash
|
||||
npm i -D @verdaccio/ui-components@6-next
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
The set of components requires libraries available in a project:
|
||||
|
||||
- React >17
|
||||
- Material UI >5.x
|
||||
- Redux >4.x
|
||||
- Emotion >11
|
||||
- i18next >20.x
|
||||
- TypeScript is optional but recommended.
|
||||
|
||||
### The store
|
||||
|
||||
All components assume there is a Redux storage, thus a `<Provider/>` wrap is the required that wrap the application.
|
||||
|
||||
```jsx
|
||||
import { store } from '@verdaccio/ui-components';
|
||||
|
||||
<Provider store={store}>....APP</Provider>;
|
||||
```
|
||||
|
||||
The default storage is powered by Rematch and contains the required `dispatch` to fetch data from the registry.
|
||||
|
||||
- Fetch all private packages
|
||||
|
||||
```jsx
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const packages = useSelector((state: RootState) => state.packages.response);
|
||||
useEffect(() => {
|
||||
dispatch.packages.getPackages();
|
||||
}, [dispatch]);
|
||||
```
|
||||
|
||||
## How to use it
|
||||
|
||||
```jsx
|
||||
import React from 'react';
|
||||
import { Route, Router, Switch } from 'react-router-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import {
|
||||
Home,
|
||||
store,
|
||||
Loading,
|
||||
NotFound,
|
||||
Route as Routes,
|
||||
TranslatorProvider,
|
||||
VersionProvider,
|
||||
loadable,
|
||||
} from '@verdaccio/ui-components';
|
||||
|
||||
// to enable webpack code splitting
|
||||
const VersionPage = loadable(() => import('../pages/Version'));
|
||||
|
||||
const App: React.FC = () => {
|
||||
// configuration from config.yaml
|
||||
const { configOptions } = useConfig();
|
||||
const listLanguages = [{lng: 'en-US', icon: <someSVGIcon>, menuKey: 'lng.english'}];
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<AppConfigurationProvider>
|
||||
<ThemeProvider>
|
||||
<TranslatorProvider i18n={i18n} listLanguages={listLanguages} onMount={() => {}}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Router history={history}>
|
||||
<Header HeaderInfoDialog={CustomInfoDialog} />
|
||||
<Switch>
|
||||
<Route exact={true} path={Routes.ROOT}>
|
||||
<Home />
|
||||
</Route>
|
||||
<Route exact={true} path={Routes.SCOPE_PACKAGE}>
|
||||
<VersionProvider>
|
||||
<VersionPage />
|
||||
</VersionProvider>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
{configOptions.showFooter && <Footer />}
|
||||
</Suspense>
|
||||
</TranslatorProvider>
|
||||
</ThemeProvider>
|
||||
</AppConfigurationProvider>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
``
|
||||
```
|
@ -1,8 +1,6 @@
|
||||
const config = require('../../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
automock: false,
|
||||
collectCoverage: false,
|
||||
testEnvironment: 'jest-environment-jsdom-global',
|
||||
transform: {
|
||||
'^.+\\.(js|ts|tsx)$': 'babel-jest',
|
||||
@ -15,15 +13,9 @@ module.exports = Object.assign({}, config, {
|
||||
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect', '<rootDir>/jest/setup-env.ts'],
|
||||
setupFiles: ['<rootDir>/jest/setup.ts'],
|
||||
transformIgnorePatterns: ['<rootDir>/node_modules/(?!react-syntax-highlighter)'],
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/coverage',
|
||||
'<rootDir>/scripts',
|
||||
'<rootDir>/tools',
|
||||
'<rootDir>/build',
|
||||
'<rootDir>/.vscode/',
|
||||
'<rootDir>/test/e2e/',
|
||||
],
|
||||
snapshotSerializers: ['@emotion/jest/serializer'],
|
||||
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**'],
|
||||
modulePathIgnorePatterns: ['<rootDir>/build/'],
|
||||
moduleNameMapper: {
|
||||
'\\.(s?css)$': '<rootDir>/jest/identity.js',
|
||||
'\\.(png)$': '<rootDir>/jest/identity.js',
|
||||
@ -34,4 +26,13 @@ module.exports = Object.assign({}, config, {
|
||||
'react-markdown': '<rootDir>/src/__mocks__/react-markdown.tsx',
|
||||
'remark-*': '<rootDir>/src/__mocks__/remark-plugin.ts',
|
||||
},
|
||||
coverageReporters: [['text', { skipFull: true }]],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 68,
|
||||
functions: 65,
|
||||
lines: 73,
|
||||
statements: 73,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
2
packages/ui-components/jest/server.d.ts
vendored
2
packages/ui-components/jest/server.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
declare const server: import('msw/lib/SetupServerApi-70cc71a7').S;
|
||||
export { server };
|
@ -4,9 +4,6 @@ import 'whatwg-fetch';
|
||||
|
||||
import { server } from './server';
|
||||
|
||||
// mock load translations to avoid warnings
|
||||
// jest.mock('../src/i18n/loadTranslationFile');
|
||||
|
||||
beforeAll(() => {
|
||||
server.listen({
|
||||
onUnhandledRequest: 'warn',
|
||||
|
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* API Mocks for WebUI
|
||||
*/
|
||||
import login from '../store/login';
|
||||
import logo from '../store/logo';
|
||||
import { packageInformation } from '../store/package';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
/**
|
||||
* Register mock api endpoints
|
||||
* @param {string} endpoint
|
||||
* @returns {Promise}
|
||||
*/
|
||||
const register = (url, method = 'get', options = {}) => {
|
||||
if (url === 'login' && method.toLocaleLowerCase() === 'post') {
|
||||
return login(options);
|
||||
}
|
||||
|
||||
if (url === 'logo' && method.toLocaleLowerCase() === 'get') {
|
||||
return logo();
|
||||
}
|
||||
|
||||
if (url === 'sidebar/verdaccio' && method.toLocaleLowerCase() === 'get') {
|
||||
return new Promise(function (resolve) {
|
||||
resolve(packageMeta);
|
||||
});
|
||||
}
|
||||
|
||||
if (url === 'packages' && method.toLocaleLowerCase() === 'get') {
|
||||
return new Promise(function (resolve) {
|
||||
resolve(packageInformation);
|
||||
});
|
||||
}
|
||||
|
||||
throw Error(`URL not found: ${url}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind API methods
|
||||
*/
|
||||
class API {
|
||||
public request(...rest) {
|
||||
return register.call(null, ...rest);
|
||||
}
|
||||
}
|
||||
|
||||
export default new API();
|
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* Token Utility
|
||||
*/
|
||||
import dayjs from 'dayjs';
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
export function generateTokenWithTimeRange(amount = 0) {
|
||||
const payload = {
|
||||
username: 'verdaccio',
|
||||
exp: Number.parseInt(String(dayjs(new Date()).add(amount, 'hour').valueOf() / 1000), 10),
|
||||
};
|
||||
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||
}
|
||||
|
||||
export function generateTokenWithExpirationAsString() {
|
||||
const payload = { username: 'verdaccio', exp: 'I am not a number' };
|
||||
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||
}
|
||||
|
||||
export function generateInvalidToken() {
|
||||
const payload = `invalidtoken`;
|
||||
return `xxxxxx.${Base64.encode(payload)}.xxxxxx`;
|
||||
}
|
||||
|
||||
export function generateTokenWithOutExpiration() {
|
||||
const payload = {
|
||||
username: 'verdaccio',
|
||||
};
|
||||
return `xxxxxx.${Base64.encode(JSON.stringify(payload))}.xxxxxx`;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import { API_ERROR } from '../../../../lib/constants';
|
||||
|
||||
/**
|
||||
* API mock for login endpoint
|
||||
* @param {object} config configuration of api call
|
||||
* @returns {promise}
|
||||
*/
|
||||
export default function login(config): Promise<unknown> {
|
||||
return new Promise(function loginCallbackPromise(resolve, reject): void {
|
||||
const body = JSON.parse(config.body);
|
||||
if (body.username === 'sam' && body.password === '1234') {
|
||||
resolve({
|
||||
username: 'sam',
|
||||
token: 'TEST_TOKEN',
|
||||
});
|
||||
} else {
|
||||
// perhaps we should rethink this reject regarding the eslint rule
|
||||
/* eslint-disable prefer-promise-reject-errors */
|
||||
reject({
|
||||
error: API_ERROR.BAD_USERNAME_PASSWORD,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Mock response for logo api
|
||||
* @returns {promise}
|
||||
*/
|
||||
export default function <T>(): Promise<T> {
|
||||
return Promise.resolve('http://localhost/-/static/logo.png');
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
export const packageInformation = [
|
||||
{
|
||||
name: 'jquery',
|
||||
title: 'jQuery',
|
||||
description: 'JavaScript library for DOM operations',
|
||||
version: '3.3.2-pre',
|
||||
main: 'dist/jquery.js',
|
||||
homepage: 'https://jquery.com',
|
||||
author: {
|
||||
name: 'JS Foundation and other contributors',
|
||||
url: 'https://github.com/jquery/jquery/blob/master/AUTHORS.txt',
|
||||
avatar: '',
|
||||
},
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'https://github.com/jquery/jquery.git',
|
||||
},
|
||||
keywords: ['jquery', 'javascript', 'browser', 'library'],
|
||||
bugs: {
|
||||
url: 'https://github.com/jquery/jquery/issues',
|
||||
},
|
||||
license: 'MIT',
|
||||
dependencies: {},
|
||||
devDependencies: {
|
||||
'babel-core': '7.0.0-beta.0',
|
||||
'babel-plugin-transform-es2015-for-of': '7.0.0-beta.0',
|
||||
commitplease: '3.2.0',
|
||||
'core-js': '2.5.7',
|
||||
'eslint-config-jquery': '1.0.1',
|
||||
grunt: '1.0.3',
|
||||
'grunt-babel': '7.0.0',
|
||||
'grunt-cli': '1.2.0',
|
||||
'grunt-compare-size': '0.4.2',
|
||||
'grunt-contrib-uglify': '3.3.0',
|
||||
'grunt-contrib-watch': '1.1.0',
|
||||
'grunt-eslint': '20.2.0',
|
||||
'grunt-git-authors': '3.2.0',
|
||||
'grunt-jsonlint': '1.1.0',
|
||||
'grunt-karma': '2.0.0',
|
||||
'grunt-newer': '1.3.0',
|
||||
'grunt-npmcopy': '0.1.0',
|
||||
'gzip-js': '0.3.2',
|
||||
husky: '0.14.3',
|
||||
insight: '0.10.1',
|
||||
jsdom: '5.6.1',
|
||||
karma: '2.0.3',
|
||||
'karma-browserstack-launcher': '1.3.0',
|
||||
'karma-chrome-launcher': '2.2.0',
|
||||
'karma-firefox-launcher': '1.1.0',
|
||||
'karma-qunit': '1.2.1',
|
||||
'load-grunt-tasks': '4.0.0',
|
||||
'native-promise-only': '0.8.1',
|
||||
'promises-aplus-tests': '2.1.2',
|
||||
q: '1.5.1',
|
||||
'qunit-assert-step': '1.1.1',
|
||||
qunitjs: '1.23.1',
|
||||
'raw-body': '2.3.3',
|
||||
requirejs: '2.3.5',
|
||||
sinon: '2.3.7',
|
||||
sizzle: '2.3.3',
|
||||
'strip-json-comments': '2.0.1',
|
||||
testswarm: '1.1.0',
|
||||
'uglify-js': '3.4.0',
|
||||
},
|
||||
scripts: {
|
||||
build: 'npm install && grunt',
|
||||
start: 'grunt watch',
|
||||
'test:browserless': 'grunt && grunt test:slow',
|
||||
'test:browser': 'grunt && grunt karma:main',
|
||||
test: 'grunt && grunt test:slow && grunt karma:main',
|
||||
jenkins: 'npm run test:browserless',
|
||||
precommit: 'grunt lint:newer qunit_fixture',
|
||||
commitmsg: 'node node_modules/commitplease',
|
||||
},
|
||||
commitplease: {
|
||||
nohook: true,
|
||||
components: [
|
||||
'Docs',
|
||||
'Tests',
|
||||
'Build',
|
||||
'Support',
|
||||
'Release',
|
||||
'Core',
|
||||
'Ajax',
|
||||
'Attributes',
|
||||
'Callbacks',
|
||||
'CSS',
|
||||
'Data',
|
||||
'Deferred',
|
||||
'Deprecated',
|
||||
'Dimensions',
|
||||
'Effects',
|
||||
'Event',
|
||||
'Manipulation',
|
||||
'Offset',
|
||||
'Queue',
|
||||
'Selector',
|
||||
'Serialize',
|
||||
'Traversing',
|
||||
'Wrap',
|
||||
],
|
||||
markerPattern: '^((clos|fix|resolv)(e[sd]|ing))|^(refs?)',
|
||||
ticketPattern: '^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|^(Refs? [^#])',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'lodash',
|
||||
version: '4.17.4',
|
||||
license: 'MIT',
|
||||
private: true,
|
||||
main: 'lodash.js',
|
||||
author: {
|
||||
name: 'John david dalton',
|
||||
url: 'test url',
|
||||
avatar: 'test avatar',
|
||||
},
|
||||
engines: {
|
||||
node: '>=4.0.0',
|
||||
},
|
||||
sideEffects: false,
|
||||
scripts: {
|
||||
build: 'npm run build:main && npm run build:fp',
|
||||
'build:fp': 'node lib/fp/build-dist.js',
|
||||
'build:fp-modules': 'node lib/fp/build-modules.js',
|
||||
'build:main': 'node lib/main/build-dist.js',
|
||||
'build:main-modules': 'node lib/main/build-modules.js',
|
||||
doc: 'node lib/main/build-doc github && npm run test:doc',
|
||||
'doc:fp': 'node lib/fp/build-doc',
|
||||
'doc:site': 'node lib/main/build-doc site',
|
||||
'doc:sitehtml':
|
||||
'optional-dev-dependency marky-markdown@^9.0.1 && npm run doc:site && node lib/main/build-site',
|
||||
pretest: 'npm run build',
|
||||
style: 'eslint *.js .internal/**/*.js',
|
||||
test: 'npm run test:main && npm run test:fp',
|
||||
'test:doc': 'markdown-doctest doc/*.md',
|
||||
'test:fp': 'node test/test-fp',
|
||||
'test:main': 'node test/test',
|
||||
validate: 'npm run style && npm run test',
|
||||
},
|
||||
devDependencies: {
|
||||
async: '^2.1.4',
|
||||
benchmark: '^2.1.3',
|
||||
chalk: '^1.1.3',
|
||||
cheerio: '^0.22.0',
|
||||
'codecov.io': '~0.1.6',
|
||||
coveralls: '^2.11.15',
|
||||
'curl-amd': '~0.8.12',
|
||||
docdown: '~0.7.2',
|
||||
dojo: '^1.12.1',
|
||||
ecstatic: '^2.1.0',
|
||||
eslint: '^3.15.0',
|
||||
'eslint-plugin-import': '^2.2.0',
|
||||
'fs-extra': '~1.0.0',
|
||||
glob: '^7.1.1',
|
||||
istanbul: '0.4.5',
|
||||
jquery: '^3.1.1',
|
||||
lodash: '4.17.3',
|
||||
'lodash-doc-globals': '^0.1.1',
|
||||
'markdown-doctest': '^0.9.1',
|
||||
'optional-dev-dependency': '^2.0.0',
|
||||
platform: '^1.3.3',
|
||||
'qunit-extras': '^3.0.0',
|
||||
qunitjs: '^2.1.0',
|
||||
request: '^2.79.0',
|
||||
requirejs: '^2.3.2',
|
||||
'sauce-tunnel': '^2.5.0',
|
||||
'uglify-js': '2.7.5',
|
||||
webpack: '^1.14.0',
|
||||
},
|
||||
greenkeeper: {
|
||||
ignore: ['lodash'],
|
||||
},
|
||||
},
|
||||
];
|
@ -1,591 +0,0 @@
|
||||
export const packageMeta = {
|
||||
name: 'verdaccio',
|
||||
'dist-tags': { latest: '2.7.1', beta: '2.4.1-beta' },
|
||||
time: {
|
||||
modified: '2017-12-14T15:43:27.317Z',
|
||||
created: '2016-07-28T12:48:43.536Z',
|
||||
'1.4.0': '2016-07-28T12:48:43.536Z',
|
||||
'2.0.0': '2016-08-26T22:36:41.762Z',
|
||||
'2.0.1': '2016-08-29T13:26:21.754Z',
|
||||
'2.1.0': '2016-10-12T00:48:03.025Z',
|
||||
'2.1.1': '2017-02-07T06:43:22.801Z',
|
||||
'2.2.0-v20170212': '2017-02-12T14:48:27.322Z',
|
||||
'2.1.2': '2017-03-09T06:25:28.107Z',
|
||||
'2.1.3': '2017-03-29T20:03:36.850Z',
|
||||
'2.1.4': '2017-04-13T20:08:41.131Z',
|
||||
'2.1.5': '2017-04-22T09:07:39.821Z',
|
||||
'2.1.6': '2017-05-12T07:43:36.616Z',
|
||||
'2.1.7': '2017-05-14T13:50:14.016Z',
|
||||
'2.1.10': '2017-06-03T09:53:52.449Z',
|
||||
'2.2.0': '2017-06-08T19:02:53.618Z',
|
||||
'2.2.1': '2017-06-17T16:23:14.158Z',
|
||||
'2.2.2': '2017-07-02T13:13:13.304Z',
|
||||
'2.2.3': '2017-07-04T20:43:59.442Z',
|
||||
'2.2.4': '2017-07-05T17:28:07.187Z',
|
||||
'2.2.5': '2017-07-05T17:34:11.089Z',
|
||||
'2.2.6': '2017-07-13T05:04:54.418Z',
|
||||
'2.2.7': '2017-07-15T23:27:24.523Z',
|
||||
'2.3.0-beta': '2017-07-15T23:31:31.664Z',
|
||||
'2.2.7-r': '2017-07-18T19:44:48.946Z',
|
||||
'2.3.0-beta-1': '2017-07-22T16:27:45.025Z',
|
||||
'2.3.0-beta-2': '2017-07-22T17:12:09.905Z',
|
||||
'2.3.0-beta-3': '2017-07-22T17:35:05.771Z',
|
||||
'2.3.0-beta-4': '2017-07-22T18:22:42.563Z',
|
||||
'2.3.0': '2017-07-22T23:08:37.513Z',
|
||||
'2.3.1-pre': '2017-07-24T05:50:40.852Z',
|
||||
'2.3.1': '2017-07-25T05:24:27.651Z',
|
||||
'2.3.2': '2017-07-28T23:05:36.431Z',
|
||||
'2.3.3': '2017-07-29T10:05:30.120Z',
|
||||
'2.3.4': '2017-07-29T10:18:44.061Z',
|
||||
'2.3.5': '2017-08-14T06:22:57.686Z',
|
||||
'2.3.6': '2017-08-17T04:30:44.872Z',
|
||||
'2.4.0': '2017-09-23T08:01:22.780Z',
|
||||
'2.4.1-beta': '2017-10-01T08:57:14.509Z',
|
||||
'2.5.0': '2017-10-01T12:31:06.333Z',
|
||||
'2.5.1': '2017-10-01T13:32:06.584Z',
|
||||
'2.6.0': '2017-10-18T20:22:32.836Z',
|
||||
'2.6.1': '2017-10-19T17:26:24.083Z',
|
||||
'2.6.2': '2017-10-21T08:37:16.527Z',
|
||||
'2.6.3': '2017-10-21T16:04:05.556Z',
|
||||
'2.6.4': '2017-10-31T17:47:03.647Z',
|
||||
'2.6.5': '2017-11-05T09:09:31.332Z',
|
||||
'2.6.6': '2017-11-08T22:47:16.504Z',
|
||||
'2.7.0': '2017-12-05T23:25:06.372Z',
|
||||
'2.7.1': '2017-12-14T15:43:27.317Z',
|
||||
},
|
||||
_uplinks: {
|
||||
abc: { etag: 'ddfdxjn8m8n6gn70-8m', fetched: 1532297472000 },
|
||||
npmjs: { etag: '"5a272ad2-4f6b1"', fetched: 1513266232741 },
|
||||
xyz: { etag: '564748hydydygs-s7ehj', fetched: 1532124672000 },
|
||||
},
|
||||
_rev: '16-ba1b806df0298246',
|
||||
_attachments: {},
|
||||
latest: {
|
||||
name: 'verdaccio',
|
||||
version: '2.7.1',
|
||||
description: 'Private npm repository server',
|
||||
author: {
|
||||
name: 'User NPM',
|
||||
email: 'test@author.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/a5a236ba477ee98908600c40cda74f4a',
|
||||
},
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'git://github.com/verdaccio/verdaccio.git',
|
||||
},
|
||||
main: 'index.js',
|
||||
bin: { verdaccio: './bin/verdaccio' },
|
||||
dependencies: {
|
||||
'@verdaccio/file-locking': '0.0.3',
|
||||
JSONStream: '^1.1.1',
|
||||
'apache-md5': '^1.1.2',
|
||||
async: '^2.0.1',
|
||||
'body-parser': '^1.15.0',
|
||||
bunyan: '^1.8.0',
|
||||
chalk: '^2.0.1',
|
||||
commander: '^2.11.0',
|
||||
compression: '1.6.2',
|
||||
cookies: '^0.7.0',
|
||||
cors: '^2.8.3',
|
||||
express: '4.15.3',
|
||||
global: '^4.3.2',
|
||||
handlebars: '4.0.5',
|
||||
'http-errors': '^1.4.0',
|
||||
'js-string-escape': '1.0.1',
|
||||
'js-yaml': '^3.6.0',
|
||||
jsonwebtoken: '^7.4.1',
|
||||
lockfile: '^1.0.1',
|
||||
lodash: '4.17.4',
|
||||
lunr: '^0.7.0',
|
||||
marked: '0.3.6',
|
||||
mime: '^1.3.6',
|
||||
minimatch: '^3.0.2',
|
||||
mkdirp: '^0.5.1',
|
||||
pkginfo: '^0.4.0',
|
||||
request: '^2.72.0',
|
||||
semver: '^5.1.0',
|
||||
'unix-crypt-td-js': '^1.0.0',
|
||||
},
|
||||
devDependencies: {
|
||||
axios: '0.16.2',
|
||||
'babel-cli': '6.24.1',
|
||||
'babel-core': '6.25.0',
|
||||
'babel-eslint': '7.2.3',
|
||||
'babel-loader': '7.1.1',
|
||||
'babel-plugin-flow-runtime': '0.11.1',
|
||||
'babel-plugin-transform-decorators-legacy': '1.3.4',
|
||||
'babel-plugin-transform-runtime': '6.23.0',
|
||||
'babel-polyfill': '^6.26.0',
|
||||
'babel-preset-env': '1.5.2',
|
||||
'babel-preset-flow': '6.23.0',
|
||||
'babel-preset-react': '6.24.1',
|
||||
'babel-preset-stage-2': '6.24.1',
|
||||
'babel-preset-stage-3': '6.24.1',
|
||||
'babel-runtime': '6.23.0',
|
||||
'codacy-coverage': '2.0.2',
|
||||
codecov: '2.2.0',
|
||||
coveralls: '2.13.1',
|
||||
'css-loader': '0.28.4',
|
||||
'element-react': '1.0.16',
|
||||
'element-theme-default': '1.3.7',
|
||||
eslint: '4.2.0',
|
||||
'eslint-config-google': '0.8.0',
|
||||
'eslint-loader': '1.8.0',
|
||||
'eslint-plugin-babel': '4.1.1',
|
||||
'eslint-plugin-flowtype': '2.35.0',
|
||||
'eslint-plugin-import': '2.6.1',
|
||||
'eslint-plugin-react': '7.1.0',
|
||||
'extract-text-webpack-plugin': '3.0.0',
|
||||
'file-loader': '0.11.2',
|
||||
'flow-runtime': '0.13.0',
|
||||
'friendly-errors-webpack-plugin': '1.6.1',
|
||||
'fs-extra': '4.0.1',
|
||||
'github-markdown-css': '2.8.0',
|
||||
'html-webpack-plugin': '2.29.0',
|
||||
'in-publish': '2.0.0',
|
||||
'localstorage-memory': '1.0.2',
|
||||
mocha: '3.4.2',
|
||||
'mocha-lcov-reporter': '1.3.0',
|
||||
'node-sass': '4.5.3',
|
||||
'normalize.css': '7.0.0',
|
||||
nyc: '11.0.3',
|
||||
ora: '1.3.0',
|
||||
'prop-types': '15.5.10',
|
||||
react: '15.6.1',
|
||||
'react-dom': '15.6.1',
|
||||
'react-hot-loader': '3.0.0-beta.7',
|
||||
'react-router-dom': '4.1.1',
|
||||
'react-syntax-highlighter': '5.6.2',
|
||||
rimraf: '2.6.1',
|
||||
'sass-loader': '6.0.6',
|
||||
'source-map-loader': '0.2.1',
|
||||
'standard-version': '4.2.0',
|
||||
'style-loader': '0.18.2',
|
||||
stylelint: '7.13.0',
|
||||
'stylelint-config-standard': '16.0.0',
|
||||
'stylelint-webpack-plugin': '0.8.0',
|
||||
'url-loader': '0.5.8',
|
||||
webpack: '3.2.0',
|
||||
'webpack-dev-server': '2.5.0',
|
||||
'webpack-merge': '4.1.0',
|
||||
},
|
||||
keywords: [
|
||||
'private',
|
||||
'package',
|
||||
'repository',
|
||||
'registry',
|
||||
'enterprise',
|
||||
'modules',
|
||||
'proxy',
|
||||
'server',
|
||||
],
|
||||
scripts: {
|
||||
release: 'standard-version -a -s',
|
||||
prepublish: 'in-publish && npm run build:webui || not-in-publish',
|
||||
test: 'mocha ./test/functional ./test/unit --reporter=spec --full-trace',
|
||||
'pre:ci': 'npm run build:webui',
|
||||
'test:ci': 'npm run test:coverage',
|
||||
'test:only': 'mocha ./test/functional ./test/unit',
|
||||
'test:coverage': 'nyc npm t',
|
||||
'coverage:html': 'nyc report --reporter=html',
|
||||
'coverage:publish': 'nyc report --reporter=lcov | codecov',
|
||||
lint: 'eslint .',
|
||||
'lint:css': "stylelint 'src/**/*.scss' --syntax scss",
|
||||
'pre:webpack': 'npm run lint && rimraf static/*',
|
||||
'dev:webui': 'babel-node tools/dev.server.js',
|
||||
'build:webui': 'npm run pre:webpack && webpack --config tools/webpack.prod.config.babel.js',
|
||||
'build:docker': 'docker build -t verdaccio . --no-cache',
|
||||
'build:docker:rpi': 'docker build -f Dockerfile.rpi -t verdaccio:rpi .',
|
||||
},
|
||||
engines: { node: '>=4.6.1', npm: '>=2.15.9' },
|
||||
preferGlobal: true,
|
||||
publishConfig: { registry: 'https://registry.verdaccio.org' },
|
||||
license: 'WTFPL',
|
||||
contributors: [
|
||||
{
|
||||
name: '030',
|
||||
email: 'test1@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/4ef03c2bf8d8689527903212d96fb45b',
|
||||
},
|
||||
{
|
||||
name: 'User NPM',
|
||||
email: 'test2@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/a5a236ba477ee98908600c40cda74f4a',
|
||||
},
|
||||
{
|
||||
name: 'User NPM',
|
||||
email: 'test3@test.comu',
|
||||
avatar: 'https://www.gravatar.com/avatar/41a61049006855759bd6ec82ef0543a0',
|
||||
},
|
||||
{
|
||||
name: 'Alex Vernacchia',
|
||||
email: 'tes4@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/06975001f7f2be7052bcf978700c6112',
|
||||
},
|
||||
{
|
||||
name: 'Alexander Makarenko',
|
||||
email: 'test5@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/d9acfc4ed4e49a436738ff26a722dce4',
|
||||
},
|
||||
{
|
||||
name: 'Alexandre-io',
|
||||
email: 'test6@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/2e095c7cfd278f72825d0fed6e12e3b1',
|
||||
},
|
||||
{
|
||||
name: 'Aram Drevekenin',
|
||||
email: 'test7@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/371edff6d79c39bb9e36bde39d41a4b0',
|
||||
},
|
||||
{
|
||||
name: 'Bart Dubois',
|
||||
email: 'test8@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/4acf72b14fcb459286c988c4523bafc8',
|
||||
},
|
||||
{
|
||||
name: 'Barthélemy Vessemont',
|
||||
email: 'test9@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/322cd2fad528a55c4351ec76d85ef525',
|
||||
},
|
||||
{
|
||||
name: 'Brandon Nicholls',
|
||||
email: 'test10@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/2d3b462f08f214ed459967aa7ef206f7',
|
||||
},
|
||||
{
|
||||
name: 'Bren Norris',
|
||||
email: 'test11@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/465a42204a22efada0f15b46a7cdad3a',
|
||||
},
|
||||
{
|
||||
name: 'Brett Trotter',
|
||||
email: 'test12@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/27a54519dcbe64c6d705f3cc4854595a',
|
||||
},
|
||||
{
|
||||
name: 'Brian Peacock',
|
||||
email: 'test13@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/3dd3d627330e7e048c13a7480f19842e',
|
||||
},
|
||||
{
|
||||
name: 'Cedric Darne',
|
||||
email: 'test14@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/0a617cebc6539940d7956c86e86c72a6',
|
||||
},
|
||||
{
|
||||
name: 'Chad Killingsworth',
|
||||
email: 'test15@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/a5825b2d69311e559e28a535e5f0d483',
|
||||
},
|
||||
{
|
||||
name: 'Chris Breneman',
|
||||
email: 'test16@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/3c5c3edef955c93edac672cbad04d7cd',
|
||||
},
|
||||
{
|
||||
name: 'Cody Droz',
|
||||
email: 'test17@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/b762ce4d14acfece36e783b1592d882b',
|
||||
},
|
||||
{
|
||||
name: 'Daniel Rodríguez Rivero',
|
||||
email: 'test18@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/ac7f548c31e8a002cfa41bd4c71e222d',
|
||||
},
|
||||
{
|
||||
name: 'Denis Babineau',
|
||||
email: 'test19@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/ee5a522e067759ba0403824ecebeab4d',
|
||||
},
|
||||
{
|
||||
name: 'Emmanuel Narh',
|
||||
email: 'test20@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/93a84a6120969fd181785ff9de834f0a',
|
||||
},
|
||||
{
|
||||
name: 'Fabio Poloni',
|
||||
email: 'test21@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/f9a05677360e5f52fcca6e1af9b0f2ee',
|
||||
},
|
||||
{
|
||||
name: 'Facundo Chambó',
|
||||
email: 'test22@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/ec9e7c590ba4081c25fcf197f90a4ea0',
|
||||
},
|
||||
{
|
||||
name: 'Guilherme Bernal',
|
||||
email: 'test23@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/e5d55dcf2495618e8b9f8778f8353ee0',
|
||||
},
|
||||
{
|
||||
name: 'Jakub Jirutka',
|
||||
email: 'test24@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/061bdb74aa4a543108658b277a257b4b',
|
||||
},
|
||||
{
|
||||
name: 'James Newell',
|
||||
email: 'test25@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/825190aaae6ec7fd95085e1fb6f261d2',
|
||||
},
|
||||
{
|
||||
name: 'Jan Vansteenkiste',
|
||||
email: 'test26@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/41835625a324201c796a0a0cffe4796b',
|
||||
},
|
||||
{
|
||||
name: 'Jannis Achstetter',
|
||||
email: 'test27@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/92d1cce007b032f4a63c6df764f18030',
|
||||
},
|
||||
{
|
||||
name: 'Jeremy Moritz',
|
||||
email: 'test28@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/008127e8f10293f43e62de3b7b3520e1',
|
||||
},
|
||||
{
|
||||
name: 'John Gozde',
|
||||
email: 'test29@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/3e8927c60cb043a56fdd6531cfcaddbc',
|
||||
},
|
||||
{
|
||||
name: 'Jon de la Motte',
|
||||
email: 'test30@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/126c1ea4fdb20bbb85c3ff735b7b0964',
|
||||
},
|
||||
{
|
||||
name: 'Joseph Gentle',
|
||||
email: 'test31@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/484f0b8ba8b7cc43db0be8f910a91254',
|
||||
},
|
||||
{
|
||||
name: 'José De Paz',
|
||||
email: 'test32@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/2532122835f5ebf1642b707ae088c895',
|
||||
},
|
||||
{
|
||||
name: 'Juan Carlos Picado',
|
||||
email: 'test33@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/c676605ff39f9c7a43f5518a8ce54e12',
|
||||
},
|
||||
{
|
||||
name: 'Juan Carlos Picado',
|
||||
email: 'test34@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/fba48015a688c38cc84e5b55b07858c0',
|
||||
},
|
||||
{
|
||||
name: 'User NPM',
|
||||
email: 'test35@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/fba48015a688c38cc84e5b55b07858c0',
|
||||
},
|
||||
{
|
||||
name: 'User NPM @nickname',
|
||||
email: 'test36@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/fba48015a688c38cc84e5b55b07858c0',
|
||||
},
|
||||
{
|
||||
name: 'Kalman Speier',
|
||||
email: 'test37@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/272806ba17639e2fbf811e51eb8bfb99',
|
||||
},
|
||||
{
|
||||
name: 'Keyvan Fatehi',
|
||||
email: 'test38@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/22735d1ba5765955914eb2d597dfaab5',
|
||||
},
|
||||
{
|
||||
name: 'Kody J. Peterson',
|
||||
email: 'test39@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/918a15afc52e9b0a67b2651191b23d04',
|
||||
},
|
||||
{
|
||||
name: 'Madison Grubb',
|
||||
email: 'test40@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/73b84fdf661c11d48d3370bfa197162b',
|
||||
},
|
||||
{
|
||||
name: 'Manuel de Brito Fontes',
|
||||
email: 'test41@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/8798ca0a499428e5e8f25d3614ac8b6e',
|
||||
},
|
||||
{
|
||||
name: 'Mark Doeswijk',
|
||||
email: 'test42@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/0d70ebd6c46dc01502bfab5f8c2d2bc5',
|
||||
},
|
||||
{
|
||||
name: 'Meeeeow',
|
||||
email: 'test43@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/baa061890d7b352ba121082272419a8a',
|
||||
},
|
||||
{
|
||||
name: 'Meeeeow',
|
||||
email: 'test44@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/12a36e093451d4c0f75d4240960ce29b',
|
||||
},
|
||||
{
|
||||
name: 'Michael Arnel',
|
||||
email: 'test45@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/5f9a5ed24c63609d52651258f6dd8c12',
|
||||
},
|
||||
{
|
||||
name: 'Michael Crowe',
|
||||
email: 'test46@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/eec9ee62019852da28a3bc91c57907f9',
|
||||
},
|
||||
{
|
||||
name: 'Miguel Mejias',
|
||||
email: 'test47@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/7289a01fedfdb9ddf855ee4dd4d41ae2',
|
||||
},
|
||||
{
|
||||
name: 'Miroslav Bajtoš',
|
||||
email: 'test48@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/b4d8831300713259f74aea79f842ca57',
|
||||
},
|
||||
{
|
||||
name: 'Nate Ziarek',
|
||||
email: 'test49@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/6442023756294fd43aa518bbe5cc6dcc',
|
||||
},
|
||||
{
|
||||
name: 'Nick',
|
||||
email: 'test50@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/8a810f12c9624ea2092852fe7c19f1ee',
|
||||
},
|
||||
{
|
||||
name: 'Piotr Synowiec',
|
||||
email: 'test51@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/87028f33a3e1e5b4201c371abddf93e2',
|
||||
},
|
||||
{
|
||||
name: 'Rafael Cesar',
|
||||
email: 'test52@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/204ed93fa5be7e2f9f299ad8bca6431f',
|
||||
},
|
||||
{
|
||||
name: 'Robert Ewald',
|
||||
email: 'test53@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/ec2166ce419f78fb354f128b01a4a44d',
|
||||
},
|
||||
{
|
||||
name: 'Robert Groh',
|
||||
email: 'test54@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/565ccb5374a3e0e31a75f11da2eb57aa',
|
||||
},
|
||||
{
|
||||
name: 'Robin Persson',
|
||||
email: 'test55@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/99da46e4d59664134b176869340f464b',
|
||||
},
|
||||
{
|
||||
name: 'Romain Lai-King',
|
||||
email: 'test56@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/69d0370c58399d0e0bbd15ccabfe1ec5',
|
||||
},
|
||||
{
|
||||
name: 'Ryan Graham',
|
||||
email: 'test57@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/8bd1dd86bbf8705a5a702b86a2f3a390',
|
||||
},
|
||||
{
|
||||
name: 'Ryan Graham',
|
||||
email: 'test58@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/e272ab422c1c629e9be26cba8b6c0166',
|
||||
},
|
||||
{
|
||||
name: 'Sam Day',
|
||||
email: 'test59@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/1886554b0562a0eeeb78a4d1f27917ea',
|
||||
},
|
||||
{
|
||||
name: 'Tarun Garg',
|
||||
email: 'test60@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/185e200c3451cfbe341f0e758626303a',
|
||||
},
|
||||
{
|
||||
name: 'Thomas Cort',
|
||||
email: 'test61@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/120d2921c33c1bd8dedfce67a28dcc63',
|
||||
},
|
||||
{
|
||||
name: 'Tom Vincent',
|
||||
email: 'test62@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/fb0c7faeda7f5d5632182a3d80381bfa',
|
||||
},
|
||||
{
|
||||
name: 'Trent Earl',
|
||||
email: 'test63@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/1e30abe66d21824b89c28d05e5b57d84',
|
||||
},
|
||||
{
|
||||
name: 'Yannick Croissant',
|
||||
email: 'test64@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/1e619ddb2a180222dd3d9f0348e65b9b',
|
||||
},
|
||||
{
|
||||
name: 'Yannick Galatol',
|
||||
email: 'test65@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/2f624f92326fef845bb2c07b392b7e48',
|
||||
},
|
||||
{
|
||||
name: 'cklein',
|
||||
email: 'test66@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/f8288370380881cf3afc5a92a63d652d',
|
||||
},
|
||||
{
|
||||
name: 'danielo515',
|
||||
email: 'test67@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/ac7f548c31e8a002cfa41bd4c71e222d',
|
||||
},
|
||||
{
|
||||
name: 'jmwilkinson',
|
||||
email: 'test68@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/3b99683f0a4c26a8906ecbe7968a4ade',
|
||||
},
|
||||
{
|
||||
name: 'nickname',
|
||||
email: 'test69@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/fba48015a688c38cc84e5b55b07858c0',
|
||||
},
|
||||
{
|
||||
name: 'nickname',
|
||||
email: 'test70@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/047ba1e853d20459e531619af5493c56',
|
||||
},
|
||||
{
|
||||
name: 'maxlaverse',
|
||||
email: 'test71@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/74324a2900906c45949a8c5cee6d0730',
|
||||
},
|
||||
{
|
||||
name: 'saheba',
|
||||
email: 'test72@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/77644c51856cab149e0f550c5f0c6ed8',
|
||||
},
|
||||
{
|
||||
name: 'steve-p-com',
|
||||
email: 'test73@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/bef1821d3036b8b9242c4999826c1c3c',
|
||||
},
|
||||
{
|
||||
name: 'trent.earl',
|
||||
email: 'test74@test.local',
|
||||
avatar: 'https://www.gravatar.com/avatar/f84b8ae496f7c988dce5a71d773e75bb',
|
||||
},
|
||||
],
|
||||
readmeFilename: 'README.md',
|
||||
gitHead: '567dbe327819ed30afb96906f8d43f19740e2e3d',
|
||||
bugs: { url: 'https://github.com/verdaccio/verdaccio/issues' },
|
||||
homepage: 'https://github.com/verdaccio/verdaccio#readme',
|
||||
_id: 'verdaccio@2.7.1',
|
||||
_shasum: '958c919180e7f2ed6775f48d4ec64bd8de2a14df',
|
||||
_from: '.',
|
||||
_npmVersion: '3.10.10',
|
||||
_nodeVersion: '6.9.5',
|
||||
_npmUser: {},
|
||||
dist: {
|
||||
shasum: '958c919180e7f2ed6775f48d4ec64bd8de2a14df',
|
||||
tarball: 'https://registry.verdaccio.org/verdaccio/-/verdaccio-2.7.1.tgz',
|
||||
},
|
||||
},
|
||||
};
|
@ -12,6 +12,7 @@
|
||||
],
|
||||
"scripts": {
|
||||
"test": "cross-env TZ=UTC jest --config jest/jest.config.js",
|
||||
"test:html": "cross-env TZ=UTC jest --config jest/jest.config.js --coverage-reporters=html",
|
||||
"clean": "rimraf ./build",
|
||||
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
|
@ -11,7 +11,6 @@ export type Props = {
|
||||
packageMeta: any;
|
||||
};
|
||||
|
||||
/* eslint-disable verdaccio/jsx-spread */
|
||||
const ActionBar: React.FC<Props> = ({ showRaw, showDownloadTarball = true, packageMeta }) => {
|
||||
const [isRawViewerOpen, setIsRawViewerOpen] = useState(false);
|
||||
|
||||
|
@ -19,6 +19,10 @@ export function getAuthorName(authorName?: string): string {
|
||||
return authorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param param0
|
||||
* @returns
|
||||
*/
|
||||
const Author: FC<{ packageMeta }> = ({ packageMeta }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
export { default } from './Dist';
|
@ -2,13 +2,24 @@ import Avatar from '@mui/material/Avatar';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import List from '@mui/material/List';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import React from 'react';
|
||||
import React, { FC } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { PackageMetaInterface } from '../../types/packageMeta';
|
||||
import { NodeJS, Npm, Pnpm, Yarn } from '../Icons';
|
||||
import { EngineListItem, StyledText } from './styles';
|
||||
|
||||
const EngineItem = ({ title, element, engineText }) => (
|
||||
/**
|
||||
* The props type for {@link EngineItem}.
|
||||
*/
|
||||
type EngineItemProps = { title: string; element: React.ReactElement; engineText?: string };
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @category Component
|
||||
*/
|
||||
const EngineItem: FC<EngineItemProps> = ({ title, element, engineText }) => (
|
||||
<Grid item={true} xs={6}>
|
||||
<List subheader={<StyledText variant={'subtitle1'}>{title}</StyledText>}>
|
||||
<EngineListItem>
|
||||
@ -19,7 +30,23 @@ const EngineItem = ({ title, element, engineText }) => (
|
||||
</Grid>
|
||||
);
|
||||
|
||||
const Engine: React.FC<{ packageMeta }> = ({ packageMeta }) => {
|
||||
interface EngineMetadata extends Omit<PackageMetaInterface, 'latest'> {
|
||||
latest: {
|
||||
engines?: { npm?: string; node?: string; pnpm?: string; yarn?: string };
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The props type for {@link Engine}.
|
||||
*/
|
||||
export type Props = { packageMeta: EngineMetadata };
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @category Component
|
||||
*/
|
||||
const Engine: React.FC<Props> = ({ packageMeta }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const engines = packageMeta?.latest?.engines;
|
||||
|
@ -1,6 +1,15 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
// based on https://usehooks.com/useLocalStorage/
|
||||
/**
|
||||
*
|
||||
* @example
|
||||
```jsx
|
||||
const [isDarkModeStorage, setIsDarkMode] = useLocalStorage('darkMode', isDarkModeDefault);
|
||||
```
|
||||
|
||||
based on https://usehooks.com/useLocalStorage/
|
||||
@category Hooks
|
||||
*/
|
||||
const useLocalStorage = <V>(key: string, initialValue: V) => {
|
||||
// State to store our value
|
||||
// Pass initial state function to useState so logic is only executed once
|
||||
|
@ -1,6 +1,11 @@
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
// based on https://usehooks.com/useOnClickOutside/
|
||||
/**
|
||||
*
|
||||
* @example
|
||||
based on https://usehooks.com/useOnClickOutside/
|
||||
@category Hooks
|
||||
*/
|
||||
function useOnClickOutside<R extends HTMLElementTagNameMap[keyof HTMLElementTagNameMap]>(
|
||||
ref: React.RefObject<R>,
|
||||
handler: (event: MouseEvent | TouchEvent) => void
|
||||
|
@ -18,12 +18,16 @@ const I18nTranslatorContext = createContext<TranslatorProviderProps>({
|
||||
listLanguages: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Translator provider
|
||||
* @category Provider
|
||||
*/
|
||||
const TranslatorProvider: FunctionComponent<{
|
||||
children: React.ReactElement<any>;
|
||||
i18n: any;
|
||||
listLanguages: any;
|
||||
loadDayJSLocale: () => {};
|
||||
}> = ({ children, loadDayJSLocale, i18n, listLanguages }) => {
|
||||
onMount: () => {};
|
||||
}> = ({ children, onMount, i18n, listLanguages }) => {
|
||||
const currentLanguage = i18n.languages?.[0];
|
||||
const [language, setLanguage] = useLocalStorage<string>('language', currentLanguage);
|
||||
const changeLanguage = useCallback(async () => {
|
||||
@ -32,8 +36,8 @@ const TranslatorProvider: FunctionComponent<{
|
||||
|
||||
useEffect(() => {
|
||||
changeLanguage();
|
||||
loadDayJSLocale();
|
||||
}, [language, loadDayJSLocale, changeLanguage]);
|
||||
onMount();
|
||||
}, [language, onMount, changeLanguage]);
|
||||
|
||||
return (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
|
@ -0,0 +1,22 @@
|
||||
# `VersionProvider`
|
||||
|
||||
Use the hook `useVersion()` to get an object with:
|
||||
|
||||
- packageMeta
|
||||
- packageName
|
||||
- packageVersion
|
||||
|
||||
The provider must be
|
||||
|
||||
```jsx
|
||||
function CustomComponent() {
|
||||
const { packageMeta, packageName, packageVersion } = useVersion();
|
||||
return <div />;
|
||||
}
|
||||
|
||||
<Route path={Routes.PACKAGE}>
|
||||
<VersionProvider>
|
||||
<CustomComponent />
|
||||
</VersionProvider>
|
||||
</Route>;
|
||||
```
|
@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
import { Route } from 'react-router-dom';
|
||||
|
||||
import { Route as Routes, store } from '../../';
|
||||
import {
|
||||
act,
|
||||
cleanup,
|
||||
renderWithStore,
|
||||
screen,
|
||||
waitFor,
|
||||
} from '../../test/test-react-testing-library';
|
||||
import VersionProvider, { useVersion } from './VersionProvider';
|
||||
|
||||
function CustomComponent() {
|
||||
const { packageMeta, packageName, packageVersion } = useVersion();
|
||||
return (
|
||||
<div>
|
||||
<div>{packageMeta?.latest?.license}</div>
|
||||
<div>{packageName}</div>
|
||||
<div>{packageVersion}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable react/jsx-no-bind*/
|
||||
describe('<Header /> component with logged in state', () => {
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
|
||||
test('should load data from the provider', async () => {
|
||||
await act(async () => {
|
||||
renderWithStore(
|
||||
<MemoryRouter initialEntries={[`/-/web/detail/storybook`]}>
|
||||
<Route path={Routes.PACKAGE}>
|
||||
<VersionProvider>
|
||||
<CustomComponent />
|
||||
</VersionProvider>
|
||||
</Route>
|
||||
</MemoryRouter>,
|
||||
store
|
||||
);
|
||||
});
|
||||
await waitFor(() => screen.getByText('storybook'));
|
||||
expect(screen.getByText('storybook')).toBeInTheDocument();
|
||||
expect(screen.getByText('MIT')).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -40,6 +40,25 @@ interface Params {
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @example
|
||||
Once a component has been wrapped with `VersionProvider`, use the hook `useVersion()` to get an object with:
|
||||
```jsx
|
||||
function CustomComponent() {
|
||||
const { packageMeta, packageName, packageVersion } = useVersion();
|
||||
return <div />;
|
||||
}
|
||||
|
||||
<Route path={Routes.PACKAGE}>
|
||||
<VersionProvider>
|
||||
<CustomComponent />
|
||||
</VersionProvider>
|
||||
</Route>;
|
||||
```
|
||||
On mount, the provider will fetch data from the store for specific package or version provided via router.
|
||||
@category Provider
|
||||
*/
|
||||
const VersionProvider: React.FC<{ children: any }> = ({ children }) => {
|
||||
const { version: packageVersion, package: pkgName, scope } = useParams<Params>();
|
||||
// @ts-ignore
|
||||
@ -50,6 +69,7 @@ const VersionProvider: React.FC<{ children: any }> = ({ children }) => {
|
||||
const dispatch = useDispatch<Dispatch>();
|
||||
useEffect(() => {
|
||||
const packageName = getRouterPackageName(pkgName, scope);
|
||||
|
||||
dispatch.manifest.getManifest({ packageName, packageVersion });
|
||||
}, [dispatch, packageVersion, pkgName, scope]);
|
||||
|
||||
|
@ -29,6 +29,10 @@ function getConfiguration() {
|
||||
return uiConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @category Model
|
||||
*/
|
||||
export const configuration = createModel<RootModel>()({
|
||||
state: {
|
||||
config: getConfiguration(),
|
||||
|
@ -4,6 +4,10 @@ import type { RootModel } from '.';
|
||||
import { downloadFile, extractFileName } from '../../utils/url';
|
||||
import API from '../api';
|
||||
|
||||
/**
|
||||
*
|
||||
* @category Model
|
||||
*/
|
||||
export const download = createModel<RootModel>()({
|
||||
state: {},
|
||||
reducers: {},
|
||||
|
@ -30,6 +30,10 @@ const defaultUserState: LoginBody = {
|
||||
username,
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @category Model
|
||||
*/
|
||||
export const login = createModel<RootModel>()({
|
||||
state: {
|
||||
username: defaultUserState.username,
|
||||
|
@ -22,6 +22,10 @@ function isPackageVersionValid(
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @category Model
|
||||
*/
|
||||
export const manifest = createModel<RootModel>()({
|
||||
state: {},
|
||||
reducers: {
|
||||
|
@ -5,6 +5,10 @@ import { Manifest } from '@verdaccio/types';
|
||||
import type { RootModel } from '.';
|
||||
import API from '../api';
|
||||
|
||||
/**
|
||||
*
|
||||
* @category Model
|
||||
*/
|
||||
export const packages = createModel<RootModel>()({
|
||||
state: {
|
||||
response: [] as Manifest[],
|
||||
|
19
packages/ui-components/src/types/index.d.ts
vendored
19
packages/ui-components/src/types/index.d.ts
vendored
@ -1,19 +0,0 @@
|
||||
declare module '*.svg' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const value: string;
|
||||
export = value;
|
||||
}
|
||||
|
||||
declare module '*.jpg' {
|
||||
const value: string;
|
||||
export = value;
|
||||
}
|
||||
|
||||
declare module '*.md' {
|
||||
const value: string;
|
||||
export = value;
|
||||
}
|
@ -1,41 +1,45 @@
|
||||
export type ModuleType = 'commonjs' | 'module';
|
||||
|
||||
export type Latest = {
|
||||
author?: Author;
|
||||
deprecated?: string;
|
||||
name: string;
|
||||
dist: {
|
||||
fileCount: number;
|
||||
unpackedSize: number;
|
||||
tarball?: string;
|
||||
};
|
||||
engines?: {
|
||||
node?: string;
|
||||
npm?: string;
|
||||
pnpm?: string;
|
||||
yarn?: string;
|
||||
};
|
||||
license?: Partial<LicenseInterface> | string;
|
||||
version: string;
|
||||
homepage?: string;
|
||||
bugs?: {
|
||||
url: string;
|
||||
};
|
||||
repository?: {
|
||||
type?: string;
|
||||
url?: string;
|
||||
};
|
||||
main?: string;
|
||||
type?: ModuleType;
|
||||
types?: string;
|
||||
description?: string;
|
||||
funding?: Funding;
|
||||
maintainers?: Developer[];
|
||||
contributors?: Developer[];
|
||||
};
|
||||
|
||||
export interface PackageMetaInterface {
|
||||
versions?: Versions;
|
||||
'dist-tags'?: DistTags;
|
||||
time?: Time;
|
||||
latest: {
|
||||
author?: Author;
|
||||
deprecated?: string;
|
||||
name: string;
|
||||
dist: {
|
||||
fileCount: number;
|
||||
unpackedSize: number;
|
||||
tarball?: string;
|
||||
};
|
||||
engines?: {
|
||||
node?: string;
|
||||
npm?: string;
|
||||
};
|
||||
license?: Partial<LicenseInterface> | string;
|
||||
version: string;
|
||||
homepage?: string;
|
||||
bugs?: {
|
||||
url: string;
|
||||
};
|
||||
repository?: {
|
||||
type?: string;
|
||||
url?: string;
|
||||
};
|
||||
main?: string;
|
||||
type?: ModuleType;
|
||||
types?: string;
|
||||
description?: string;
|
||||
funding?: Funding;
|
||||
maintainers?: Developer[];
|
||||
contributors?: Developer[];
|
||||
};
|
||||
_uplinks: Record<string, { fetched: number }>;
|
||||
latest: Latest;
|
||||
_uplinks?: Record<string, { fetched: number }>;
|
||||
}
|
||||
|
||||
export interface Developer {
|
||||
|
@ -1,6 +1,15 @@
|
||||
/* eslint-disable verdaccio/jsx-spread */
|
||||
import React, { Suspense, lazy } from 'react';
|
||||
|
||||
/**
|
||||
* With the combination of a bundler, enable to code split a package.
|
||||
*
|
||||
* @example
|
||||
```jsx
|
||||
const VersionPage = loadable(() => import(/'../pages/Version'));
|
||||
```
|
||||
@category HOC
|
||||
*/
|
||||
export default (importCallback: any) => {
|
||||
const TargetComponent = lazy(importCallback);
|
||||
return (props: any) => (
|
||||
|
@ -12,5 +12,10 @@
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": ["src/**/*", "./src/types/index.d.ts"]
|
||||
"include": ["src/**/*", "./src/types/index.d.ts"],
|
||||
"typedocOptions": {
|
||||
"categoryOrder": ["Model", "Component", "Provider", "*"],
|
||||
"defaultCategory": "Component",
|
||||
"categorizeByGroup": "false"
|
||||
}
|
||||
}
|
||||
|
523
pnpm-lock.yaml
generated
523
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -72,7 +72,7 @@ const App: React.FC = () => {
|
||||
<Provider store={store}>
|
||||
<AppConfigurationProvider>
|
||||
<ThemeProvider>
|
||||
<TranslatorProvider i18n={i18n} listLanguages={listLanguages} loadDayJSLocale={() => {}}>
|
||||
<TranslatorProvider i18n={i18n} listLanguages={listLanguages} onMount={() => {}}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Router history={history}>
|
||||
<Header HeaderInfoDialog={CustomInfoDialog} />
|
||||
|
@ -167,6 +167,20 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'docusaurus-plugin-typedoc',
|
||||
{
|
||||
entryPoints: ['../packages/ui-components/src/index.ts'],
|
||||
tsconfig: '../packages/ui-components/tsconfig.build.json',
|
||||
id: 'api/ui-components',
|
||||
out: 'api/ui-components',
|
||||
sidebar: {
|
||||
categoryLabel: '@verdaccio/ui-components',
|
||||
fullNames: true,
|
||||
watch: process.env.TYPEDOC_WATCH,
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'docusaurus-plugin-typedoc',
|
||||
{
|
||||
|
@ -1,10 +1,11 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@verdaccio/website",
|
||||
"version": "5.19.0",
|
||||
"version": "5.19.1",
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start --no-open",
|
||||
"start:typedoc": "TYPEDOC_WATCH=true docusaurus start --no-open",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
@ -46,7 +47,7 @@
|
||||
"copy-text-to-clipboard": "3.0.1",
|
||||
"docusaurus-plugin-contributors": "workspace:1.0.1-6-next.0",
|
||||
"docusaurus-plugin-sentry": "1.0.0",
|
||||
"docusaurus-plugin-typedoc": "latest",
|
||||
"docusaurus-plugin-typedoc": "0.18.0",
|
||||
"p-cancelable": "2.1.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
@ -55,6 +56,8 @@
|
||||
"react-twitter-widgets": "^1.10.0",
|
||||
"typedoc": "0.23.23",
|
||||
"typedoc-plugin-markdown": "3.14.0",
|
||||
"typedoc-plugin-merge-modules": "4.0.1",
|
||||
"typedoc-github-wiki-theme": "^1.0.1",
|
||||
"use-is-in-viewport": "^1.0.9",
|
||||
"usehooks-ts": "2.9.1"
|
||||
},
|
||||
@ -80,7 +83,6 @@
|
||||
"prism-react-renderer": "^1.2.1",
|
||||
"sass": "1.57.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"typedoc-github-wiki-theme": "^1.0.1",
|
||||
"url-loader": "4.1.1"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user