1
0
mirror of https://github.com/SomboChea/ui synced 2026-01-13 22:55:48 +07:00

Compare commits

...

12 Commits

Author SHA1 Message Date
Juan Picado @jotadeveloper
4ee6c2dfe4 chore(release): 0.0.13 2019-04-14 00:28:09 +02:00
Juan Picado @jotadeveloper
13d999369d chore: update registry domain 2019-04-14 00:25:45 +02:00
Liming Jin
cc30d0b249 fix: there can be no spaces between scope and registry (#34) 2019-04-14 00:17:21 +02:00
Juan Picado @jotadeveloper
6f108370ce fix: takes the app version from verdaccio 2019-04-13 23:27:44 +02:00
Ayush Sharma
f9da05744b chore: 4.x fixes filter action flow (#33)
* chore: separates release workflow

* chore: separates release workflow
2019-04-09 09:28:52 +02:00
Juan Picado @jotadeveloper
414aaa3d84 Update README.md 2019-04-09 00:05:45 +02:00
Ayush Sharma
4a459df463 GitHub actions (#32)
* chore: fixes snapshots test

* chore: adds github actions, issue and feat templates

* chore: fixes eslint

* chore: remvoes circle ci and adds publish action

* chore: adds github-release automation using actions
2019-04-08 23:36:39 +02:00
Ayush Sharma
96b65d969a refactor: corrects eslint and variable name spacing (#31)
* refactor: corrects eslint and variable namespacing

* chore: fixes git conflict

* chore: fixes eslint
2019-04-08 22:29:20 +02:00
Juan Picado @jotadeveloper
f000438b86 chore: update lock file 2019-04-07 08:41:08 +02:00
Juan Picado @jotadeveloper
7bde18c8d9 chore: update circleci 2019-04-06 18:14:03 +02:00
Juan Picado @jotadeveloper
3a63fba339 chore: add verdaccio and webpack dev server script 2019-04-06 17:51:26 +02:00
Juan Picado @jotadeveloper
6fcb415091 chore: remove unused code 2019-04-06 17:42:52 +02:00
37 changed files with 3277 additions and 3050 deletions

View File

@@ -1,173 +0,0 @@
version: 2
aliases:
- &defaults
working_directory: ~/verdaccio
- &node8_executor
docker:
- image: circleci/node:8
- &node10_executor
docker:
- image: circleci/node:10
- &node11_executor
docker:
- image: circleci/node:11.10.1
- &default_executor
<<: *node10_executor
- &repo_key
repo-{{ .Branch }}-{{ .Revision }}
- &coverage_key
coverage-{{ .Branch }}-{{ .Revision }}
- &base_config_key
base-config-{{ .Branch }}-{{ .Revision }}
- &yarn_cache_key
yarn-sha-{{ checksum "yarn.lock" }}
- &restore_repo
attach_workspace:
at: ~/verdaccio
- &ignore_non_dev_branches
filters:
tags:
only: /.*/
branches:
ignore:
- gh-pages
- l10n_master
- /release\/.*/
- &execute_on_release
filters:
tags:
only: /v?[0-9]+(\.[0-9]+)+([-+\.][0-9a-zA-Z]+)*/
branches:
ignore:
- /.*/
jobs:
prepare:
<<: *defaults
<<: *default_executor
steps:
- checkout
- restore_cache:
key: *base_config_key
- run:
name: 'Base environment setup'
command: |
git config --global user.email "verdacciobot@users.noreply.github.com"
git config --global user.name "Verdaccio bot for Deployments"
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
echo "machine github.com login verdacciobot password $GITHUB_TOKEN" > ~/.netrc
- save_cache:
key: *base_config_key
paths:
- ~/.npmrc
- ~/.gitconfig
- ~/.netrc
- restore_cache:
key: *yarn_cache_key
- run:
name: Install Js dependencies
command: yarn install --no-progress --registry https://registry.verdaccio.org
- run:
name: Prepare CI
command: yarn lint
- run:
name: Build project
command: yarn build
- save_cache:
key: *yarn_cache_key
paths:
- ~/.yarn
- ~/.cache/yarn
- node_modules
- persist_to_workspace:
root: ~/verdaccio
paths:
- ./*
test_node8:
<<: *defaults
<<: *node8_executor
steps:
- *restore_repo
- run:
name: Test with Node 8
command: |
yarn test
test_node10:
<<: *defaults
<<: *node10_executor
steps:
- *restore_repo
- run:
name: Test with Node 10
command: |
yarn test
test_node11:
<<: *defaults
<<: *node11_executor
steps:
- *restore_repo
- run:
name: Test with Node 11
command: |
yarn run test
coverage:
<<: *defaults
<<: *default_executor
steps:
- *restore_repo
- restore_cache:
key: *coverage_key
- run:
name: Publish coverage
command: yarn run coverage:publish
- store_artifacts:
path: coverage/clover.xml
prefix: tests
- store_artifacts:
path: coverage
prefix: coverage
- store_test_results:
path: coverage/clover.xml
publish_package:
<<: *defaults
<<: *default_executor
steps:
- *restore_repo
- restore_cache:
key: *base_config_key
- run:
name: Publish
command: scripts/publish.sh
workflows:
version: 2
workflow:
jobs:
- prepare:
<<: *ignore_non_dev_branches
- test_node8:
requires:
- prepare
<<: *ignore_non_dev_branches
- test_node10:
requires:
- prepare
<<: *ignore_non_dev_branches
- test_node11:
requires:
- prepare
<<: *ignore_non_dev_branches
- coverage:
requires:
- test_node8
- test_node10
- test_node11
<<: *ignore_non_dev_branches
- publish_package:
requires:
- coverage
<<: *execute_on_release

37
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,37 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Docker || Kubernetes (please complete the following information):**
- Docker verdaccio tag: [e.g. verdaccio:beta]
- Docker commands [e.g. docker pull ...]
- Docker Version [e.g. v18.05.0-ce-rc1]
**Configuration File (cat ~/.config/verdaccio/config.yaml)**
**Debugging output**
- `$ NODE_DEBUG=request verdaccio` display request calls (verdaccio <--> uplinks)
- `$ DEBUG=express:* verdaccio` enable extreme verdaccio debug mode (verdaccio api)
- `$ npm -ddd` prints:
- `$ npm config get registry` prints:
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

32
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,32 @@
<!--
First of all, please read this section
https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md#reporting-a-bug
Some advices before file an issue
* Give a brief explanation of the issue, suggestion or feature to request.
* If the issue is a question, provide as much information you have available.
* How can I do in order to reproduce it? What environment?
* Define which version the issue happens and whether previous version the behavior is correct.
* Provide your config file is really helpful. Please be aware to hide sensitive data (passwords, server IP, etc) before post.
-->
#### My reason:
#### Steps to reproduce:
#### App Version:
#### Config file:
#### Additional information:
- `$ NODE_DEBUG=request verdaccio` display request calls (verdaccio <--> uplinks)
- `$ DEBUG=express:* verdaccio` enable extreme verdaccio debug mode (verdaccio api)
- `$ npm -ddd` prints:
- `$ npm config get registry` prints:
- Verdaccio terminal output
- Which (Windows, OS X/macOS, or Linux) environment are you running verdaccio?:
- Verdaccio configuration file, eg: `cat ~/.config/verdaccio/config.yaml`
- Container Options:
- Docker?:
- Kubernetes?:
#### Additional verbose log:

94
.github/main.workflow vendored Normal file
View File

@@ -0,0 +1,94 @@
workflow "build and test" {
resolves = [
"lint",
"test",
"branch-filter",
]
on = "push"
}
action "branch-filter" {
uses = "actions/bin/filter@master"
args = "branch"
}
action "install" {
uses = "docker://node:10"
args = "yarn install"
}
action "build" {
uses = "docker://node:10"
needs = ["install"]
args = "yarn run build"
}
action "lint" {
uses = "docker://node:10"
needs = ["install"]
args = "yarn run lint"
}
action "test" {
uses = "docker://node:10"
needs = ["build"]
args = "yarn run test"
}
workflow "release" {
resolves = [
"github-release",
"release:lint",
]
on = "push"
}
action "release:tag-filter" {
uses = "actions/bin/filter@master"
args = "tag v*"
}
action "release:install" {
uses = "docker://node:10"
needs = ["release:tag-filter"]
args = "yarn install"
}
action "release:build" {
uses = "docker://node:10"
needs = ["release:install"]
args = "yarn run build"
}
action "release:lint" {
uses = "docker://node:10"
needs = ["release:install"]
args = "yarn run lint"
}
action "release:test" {
uses = "docker://node:10"
needs = ["release:build"]
args = "yarn run test"
}
action "release:publish" {
needs = ["release:test"]
uses = "docker://node:10"
args = "sh scripts/publish.sh"
secrets = [
"REGISTRY_AUTH_TOKEN",
]
env = {
REGISTRY_URL = "registry.npmjs.org"
}
}
action "github-release" {
needs = ["release:publish"]
uses = "docker://node:10"
args = "sh scripts/github-release.sh"
secrets = [
"GITHUB_TOKEN",
]
}

27
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,27 @@
<!--
Before Pull Request check whether your commits follow this convention
https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md#git-commit-guidelines
* If your PR fix an issue don't forget to update the unit test and documentation in /docs folder
* If your PR delivers a new feature, please, provide examples and why such feature should be considered.
* Document your changes /docs
* Add unit test
* Follow the commit guidelines in order to get a quick approval
Pick one/multiple type, if none apply please suggest one, we might be included it by default
eg: bug / feature / documentation / unit test / build
-->
**Type:**
The following has been addressed in the PR:
* There is a related issue?
* Unit or Functional tests are included in the PR
**Description:**
<!-- Resolves #??? -->

View File

@@ -2,6 +2,17 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="0.0.13"></a>
## [0.0.13](https://github.com/verdaccio/ui/compare/v0.0.4...v0.0.13) (2019-04-13)
### Bug Fixes
* takes the app version from verdaccio ([6f10837](https://github.com/verdaccio/ui/commit/6f10837))
* there can be no spaces between scope and registry ([#34](https://github.com/verdaccio/ui/issues/34)) ([cc30d0b](https://github.com/verdaccio/ui/commit/cc30d0b))
<a name="0.0.4"></a>
## [0.0.4](https://github.com/verdaccio/ui/compare/v0.0.3...v0.0.4) (2019-04-04)

View File

@@ -32,7 +32,7 @@ Google Cloud Storage** or create your own plugin.
đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§
**This is a maintenance branch, only bug fixing, minor changes or security updates**.
**This is a maintenance branch, only bug fixing, minor changes or security updates**
đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§đźš§
@@ -79,4 +79,4 @@ If you have any issue you can try the following options, do no desist to ask or
### License
Verdaccio is [MIT licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)
Verdaccio is [MIT licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)

View File

@@ -1,6 +1,6 @@
{
"name": "@verdaccio/ui-theme",
"version": "0.0.4",
"version": "0.0.13",
"description": "Verdaccio User Interface",
"author": {
"name": "Verdaccio Core Team"
@@ -15,11 +15,13 @@
"@commitlint/config-conventional": "7.5.0",
"@material-ui/core": "3.9.0",
"@material-ui/icons": "3.0.2",
"@octokit/rest": "16.23.2",
"@verdaccio/babel-preset": "0.1.0",
"@verdaccio/types": "5.0.0-beta.4",
"autosuggest-highlight": "3.1.1",
"bundlesize": "0.17.1",
"codecov": "3.2.0",
"concurrently": "4.1.0",
"cross-env": "5.2.0",
"css-loader": "0.28.10",
"date-fns": "1.30.1",
@@ -42,6 +44,7 @@
"flow-bin": "0.81.0",
"flow-runtime": "0.17.0",
"friendly-errors-webpack-plugin": "1.7.0",
"get-stdin": "6.0.0",
"github-markdown-css": "2.10.0",
"html-webpack-plugin": "3.2.0",
"husky": "0.15.0-rc.8",
@@ -52,6 +55,7 @@
"jest-environment-jsdom": "24.0.0",
"jest-environment-jsdom-global": "1.1.1",
"jest-environment-node": "24.0.0",
"js-yaml": "3.13.1",
"localstorage-memory": "1.0.3",
"mini-css-extract-plugin": "0.5.0",
"node-mocks-http": "1.7.3",
@@ -85,6 +89,7 @@
"supertest": "3.4.2",
"typeface-roboto": "0.0.54",
"url-loader": "1.1.2",
"verdaccio": "4.0.0-alpha.7",
"verdaccio-auth-memory": "0.0.4",
"verdaccio-memory": "2.0.0",
"webpack": "4.20.2",
@@ -104,19 +109,21 @@
"flow": "flow check",
"release": "standard-version -a -s",
"test:clean": "npx jest --clearCache",
"test": "cross-env NODE_ENV=test BABEL_ENV=test TZ=UTC FORCE_COLOR=1 jest --config ./jest.config.js --maxWorkers 2 --passWithNoTests",
"test": "cross-env NODE_ENV=test BABEL_ENV=test TZ=UTC jest --config ./jest.config.js --maxWorkers 2 --passWithNoTests",
"test:size": "bundlesize",
"lint": "npm run flow && npm run lint:js && npm run lint:css",
"lint:js": "eslint .",
"coverage:publish": "codecov",
"lint:css": "stylelint 'src/webui/**/styles.js'",
"pre:webpack": "rimraf static/*",
"dev": "cross-env BABEL_ENV=ui babel-node tools/dev.server.js",
"build": "npm run pre:webpack && cross-env BABEL_ENV=ui webpack --config tools/webpack.prod.config.babel.js"
"dev:web": "cross-env BABEL_ENV=ui babel-node tools/dev.server.js",
"verdaccio:server": "node tools/verdaccio.js",
"build": "npm run pre:webpack && cross-env BABEL_ENV=ui webpack --config tools/webpack.prod.config.babel.js",
"dev": "concurrently --kill-others \"npm run dev:web\" \"npm run verdaccio:server\""
},
"engines": {
"node": ">=6.12.0",
"npm": ">=3"
"node": ">=8",
"npm": ">=5"
},
"husky": {
"hooks": {

View File

@@ -0,0 +1,8 @@
# Get the last tag from GitHub
lastTag=$(git describe --tags $(git rev-list --tags --max-count=1))
changelog=$(git show $GITHUB_SHA --unified=0 CHANGELOG.md | tail +12 | sed -e 's/^\+//')
echo "$changelog"
echo "$changelog" | node scripts/trigger-release.js $lastTag

View File

@@ -6,5 +6,8 @@ lastTag=$(git describe --tags $(git rev-list --tags --max-count=1))
# Print it to the console for verification
echo "Bumping version to new tag: ${lastTag}"
# creating .npmrc
echo "//$REGISTRY_URL/:_authToken=$REGISTRY_AUTH_TOKEN" > .npmrc
# Publish to NPM
npm publish --registry https://registry.npmjs.org/
npm publish --registry https://$REGISTRY_URL/

View File

@@ -0,0 +1,26 @@
"use strict";
const [ /* node */, /* file */, tag] = process.argv;
const getStdin = require("get-stdin");
const Octokit = require('@octokit/rest');
const octokit = new Octokit({
auth: `token ${process.env.GITHUB_TOKEN}`,
});
const [repoOwner, repoName] = process.env.GITHUB_REPOSITORY.split("/");
getStdin()
.then(changelog => octokit.repos.createRelease({
owner: repoOwner,
repo: repoName,
tag_name: tag,
body: changelog,
draft: true,
}))
.catch(err => {
// eslint-disable-next-line no-console
console.error(err);
process.exit(1);
});

View File

@@ -4,155 +4,12 @@
// @flow
export const DEFAULT_PORT: string = '4873';
export const DEFAULT_PROTOCOL: string = 'http';
export const DEFAULT_DOMAIN: string = 'localhost';
export const TIME_EXPIRATION_24H: string = '24h';
export const TIME_EXPIRATION_7D: string = '7d';
export const DIST_TAGS = 'dist-tags';
export const USERS = 'users';
export const DEFAULT_MIN_LIMIT_PASSWORD: number = 3;
export const DEFAULT_USER = 'Anonymous';
export const keyPem = 'verdaccio-key.pem';
export const certPem = 'verdaccio-cert.pem';
export const csrPem = 'verdaccio-csr.pem';
export const HEADERS = {
JSON: 'application/json',
CONTENT_TYPE: 'Content-type',
TEXT_PLAIN: 'text/plain',
FORWARDED_PROTO: 'X-Forwarded-Proto',
ETAG: 'ETag',
JSON_CHARSET: 'application/json; charset=utf-8',
OCTET_STREAM: 'application/octet-stream; charset=utf-8',
TEXT_CHARSET: 'text/plain; charset=utf-8',
WWW_AUTH: 'WWW-Authenticate',
GZIP: 'gzip',
};
export const CHARACTER_ENCODING = {
UTF8: 'utf8',
};
export const HEADER_TYPE = {
CONTENT_ENCODING: 'content-encoding',
CONTENT_TYPE: 'content-type',
CONTENT_LENGTH: 'content-length',
ACCEPT_ENCODING: 'accept-encoding',
};
export const ERROR_CODE = {
token_required: 'token is required',
};
export const TOKEN_BASIC = 'Basic';
export const TOKEN_BEARER = 'Bearer';
export const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
export const DEFAULT_UPLINK = 'npmjs';
export const ROLES = {
$ALL: '$all',
ALL: 'all',
$AUTH: '$authenticated',
$ANONYMOUS: '$anonymous',
DEPRECATED_ALL: '@all',
DEPRECATED_AUTH: '@authenticated',
DEPRECATED_ANONYMOUS: '@anonymous',
};
export const HTTP_STATUS = {
OK: 200,
CREATED: 201,
MULTIPLE_CHOICES: 300,
NOT_MODIFIED: 304,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
CONFLICT: 409,
UNSUPPORTED_MEDIA: 415,
BAD_DATA: 422,
INTERNAL_ERROR: 500,
SERVICE_UNAVAILABLE: 503,
LOOP_DETECTED: 508,
};
export const API_MESSAGE = {
PKG_CREATED: 'created new package',
PKG_CHANGED: 'package changed',
PKG_REMOVED: 'package removed',
PKG_PUBLISHED: 'package published',
TARBALL_UPLOADED: 'tarball uploaded successfully',
TARBALL_REMOVED: 'tarball removed',
TAG_UPDATED: 'tags updated',
TAG_REMOVED: 'tag removed',
TAG_ADDED: 'package tagged',
LOGGED_OUT: 'Logged out',
};
export const SUPPORT_ERRORS = {
PLUGIN_MISSING_INTERFACE: 'the plugin does not provide implementation of the requested feature',
TFA_DISABLED: 'the two-factor authentication is not yet supported',
};
export const API_ERROR = {
PASSWORD_SHORT: (passLength: number = DEFAULT_MIN_LIMIT_PASSWORD) =>
`The provided password is too short. Please pick a password longer than ${passLength} characters.`,
MUST_BE_LOGGED: 'You must be logged in to publish packages.',
PLUGIN_ERROR: 'bug in the auth plugin system',
CONFIG_BAD_FORMAT: 'config file must be an object',
BAD_USERNAME_PASSWORD: 'bad username/password, access denied',
NO_PACKAGE: 'no such package available',
PACKAGE_CANNOT_BE_ADDED: 'this package cannot be added',
BAD_DATA: 'bad data',
NOT_ALLOWED: 'not allowed to access package',
NOT_ALLOWED_PUBLISH: 'not allowed to publish package',
INTERNAL_SERVER_ERROR: 'internal server error',
UNKNOWN_ERROR: 'unknown error',
NOT_PACKAGE_UPLINK: 'package does not exist on uplink',
UPLINK_OFFLINE_PUBLISH: 'one of the uplinks is down, refuse to publish',
UPLINK_OFFLINE: 'uplink is offline',
CONTENT_MISMATCH: 'content length mismatch',
NOT_FILE_UPLINK: "file doesn't exist on uplink",
MAX_USERS_REACHED: 'maximum amount of users reached',
VERSION_NOT_EXIST: "this version doesn't exist",
FILE_NOT_FOUND: 'File not found',
BAD_STATUS_CODE: 'bad status code',
PACKAGE_EXIST: 'this package is already present',
BAD_AUTH_HEADER: 'bad authorization header',
WEB_DISABLED: 'Web interface is disabled in the config file',
DEPRECATED_BASIC_HEADER: 'basic authentication is deprecated, please use JWT instead',
BAD_FORMAT_USER_GROUP: 'user groups is different than an array',
RESOURCE_UNAVAILABLE: 'resource unavailable',
BAD_PACKAGE_DATA: 'bad incoming package data',
USERNAME_PASSWORD_REQUIRED: 'username and password is required',
USERNAME_ALREADY_REGISTERED: 'username is already registered',
};
export const APP_ERROR = {
CONFIG_NOT_VALID: 'CONFIG: it does not look like a valid config file',
PROFILE_ERROR: 'profile unexpected error',
PASSWORD_VALIDATION: 'not valid password',
};
export const DEFAULT_NO_README = 'ERROR: No README data found!';
export const MODULE_NOT_FOUND = 'MODULE_NOT_FOUND';
export const WEB_TITLE = 'Verdaccio';
export const PACKAGE_ACCESS = {
SCOPE: '@*/*',
ALL: '**',
};
export const UPDATE_BANNER = {
CHANGELOG_URL: 'https://github.com/verdaccio/verdaccio/releases/tag/',
};
export const STORAGE = {
PACKAGE_FILE_NAME: 'package.json',
FILE_EXIST_ERROR: 'EEXISTS',
NO_SUCH_FILE_ERROR: 'ENOENT',
DEFAULT_REVISION: '0-0000000000000000',
};

View File

@@ -1,73 +0,0 @@
/**
* @prettier
* @flow
*/
import { createDecipher, createCipher, createHash, pseudoRandomBytes } from 'crypto';
import jwt from 'jsonwebtoken';
import type { JWTSignOptions, RemoteUser } from '@verdaccio/types';
export const defaultAlgorithm = 'aes192';
export const defaultTarballHashAlgorithm = 'sha1';
export function aesEncrypt(buf: Buffer, secret: string): Buffer {
// deprecated
// https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options
const c = createCipher(defaultAlgorithm, secret);
const b1 = c.update(buf);
const b2 = c.final();
return Buffer.concat([b1, b2]);
}
export function aesDecrypt(buf: Buffer, secret: string) {
try {
// deprecated
// https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options
const c = createDecipher(defaultAlgorithm, secret);
const b1 = c.update(buf);
const b2 = c.final();
return Buffer.concat([b1, b2]);
} catch (_) {
return new Buffer(0);
}
}
export function createTarballHash() {
return createHash(defaultTarballHashAlgorithm);
}
/**
* Express doesn't do ETAGS with requests <= 1024b
* we use md5 here, it works well on 1k+ bytes, but sucks with fewer data
* could improve performance using crc32 after benchmarks.
* @param {Object} data
* @return {String}
*/
export function stringToMD5(data: Buffer | string) {
return createHash('md5')
.update(data)
.digest('hex');
}
export function generateRandomHexString(length: number = 8) {
return pseudoRandomBytes(length).toString('hex');
}
export async function signPayload(payload: RemoteUser, secretOrPrivateKey: string, options: JWTSignOptions): Promise<string> {
return new Promise(function(resolve, reject) {
return jwt.sign(
payload,
secretOrPrivateKey,
{
notBefore: '1', // Make sure the time will not rollback :)
...options,
},
(error, token) => (error ? reject(error) : resolve(token))
);
});
}
export function verifyPayload(token: string, secretOrPrivateKey: string) {
return jwt.verify(token, secretOrPrivateKey);
}

View File

@@ -1,5 +0,0 @@
// @flow
export function spliceURL(...args: Array<string>): string {
return Array.from(args).reduce((lastResult, current) => lastResult + current).replace(/([^:])(\/)+(.)/g, `$1/$3`);
}

View File

@@ -1,47 +0,0 @@
// @flow
import {stringToMD5} from '../lib/crypto-utils';
import _ from 'lodash';
// this is a generic avatar
// https://www.iconfinder.com/icons/403017/anonym_avatar_default_head_person_unknown_user_icon
// license: free commercial usage
export const GENERIC_AVATAR: string = `
data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1
ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYW
NrZ3JvdW5kPSJuZXcgLTI3IDI0IDEwMCAxMDAiIGhlaWdodD0iMTAwcHgiIGlkPSJ1bmtub3duIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3
g9Ii0yNyAyNCAxMDAgMTAwIiB3aWR0aD0iMTAwcHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy
8yMDAwL3N2ZyIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiIHhtbG5zOnhsaW5rPS
JodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48Zz48Zz48ZGVmcz48Y2lyY2xlIGN4PSIyMyIgY3k9Ijc0IiBpZD0iY2lyY2xlIi
ByPSI1MCIvPjwvZGVmcz48dXNlIGZpbGw9IiNGNUVFRTUiIG92ZXJmbG93PSJ2aXNpYmxlIiB4bGluazpocmVmPSIjY2lyY2xlIi8+PGN
saXBQYXRoIGlkPSJjaXJjbGVfMV8iPjx1c2Ugb3ZlcmZsb3c9InZpc2libGUiIHhsaW5rOmhyZWY9IiNjaXJjbGUiLz48L2NsaXBQYXR
oPjxnIGNsaXAtcGF0aD0idXJsKCNjaXJjbGVfMV8pIj48ZGVmcz48cGF0aCBkPSJNMzYsOTUuOWMwLDQsNC43LDUuMiw3LjEsNS44Yzc
uNiwyLDIyLjgsNS45LDIyLjgsNS45YzMuMiwxLjEsNS43LDMuNSw3LjEsNi42djkuOEgtMjd2LTkuOCAgICAgICBjMS4zLTMuMSwzLjk
tNS41LDcuMS02LjZjMCwwLDE1LjItMy45LDIyLjgtNS45YzIuNC0wLjYsNy4xLTEuOCw3LjEtNS44YzAtNCwwLTEwLjksMC0xMC45aDI
2QzM2LDg1LDM2LDkxLjksMzYsOTUuOXoiIGlkPSJzaG91bGRlcnMiLz48L2RlZnM+PHVzZSBmaWxsPSIjRTZDMTlDIiBvdmVyZmxvdz0
idmlzaWJsZSIgeGxpbms6aHJlZj0iI3Nob3VsZGVycyIvPjxjbGlwUGF0aCBpZD0ic2hvdWxkZXJzXzFfIj48dXNlIG92ZXJmbG93PSJ
2aXNpYmxlIiB4bGluazpocmVmPSIjc2hvdWxkZXJzIi8+PC9jbGlwUGF0aD48cGF0aCBjbGlwLXBhdGg9InVybCgjc2hvdWxkZXJzXzF
fKSIgZD0iTTIzLjIsMzVjMC4xLDAsMC4xLDAsMC4yLDBjMCwwLDAsMCwwLDAgICAgICBjMy4zLDAsOC4yLDAuMiwxMS40LDJjMy4zLD
EuOSw3LjMsNS42LDguNSwxMi4xYzIuNCwxMy43LTIuMSwzNS40LTYuMyw0Mi40Yy00LDYuNy05LjgsOS4yLTEzLjUsOS40YzAsMC0wL
jEsMC0wLjEsMCAgICAgIGMtMC4xLDAtMC4xLDAtMC4yLDBjLTAuMSwwLTAuMSwwLTAuMiwwYzAsMC0wLjEsMC0wLjEsMGMtMy43LTAuM
i05LjUtMi43LTEzLjUtOS40Yy00LjItNy04LjctMjguNy02LjMtNDIuNCAgICAgIGMxLjItNi41LDUuMi0xMC4yLDguNS0xMi4xYzMuM
i0xLjgsOC4xLTIsMTEuNC0yYzAsMCwwLDAsMCwwQzIzLjEsMzUsMjMuMSwzNSwyMy4yLDM1TDIzLjIsMzV6IiBmaWxsPSIjRDRCMDhDI
iBpZD0iaGVhZC1zaGFkb3ciLz48L2c+PC9nPjxwYXRoIGQ9Ik0yMi42LDQwYzE5LjEsMCwyMC43LDEzLjgsMjAuOCwxNS4xYzEuMSwxM
S45LTMsMjguMS02LjgsMzMuN2MtNCw1LjktOS44LDguMS0xMy41LDguMyAgICBjLTAuMiwwLTAuMiwwLTAuMywwYy0wLjEsMC0wLjEs
MC0wLjIsMEMxOC44LDk2LjgsMTMsOTQuNiw5LDg4LjdjLTMuOC01LjYtNy45LTIxLjgtNi44LTMzLjhDMi4zLDUzLjcsMy41LDQwLDIyL
jYsNDB6IiBmaWxsPSIjRjJDRUE1IiBpZD0iaGVhZCIvPjwvZz48L3N2Zz4=`;
/**
* Generate gravatar url from email address
*/
export function generateGravatarUrl(email: string = '', online: boolean = true): string {
if (online) {
if (_.isString(email) && _.size(email) > 0) {
email = email.trim().toLocaleLowerCase();
const emailMD5 = stringToMD5(email);
return `https://www.gravatar.com/avatar/${emailMD5}`;
}
return GENERIC_AVATAR;
} else {
return GENERIC_AVATAR;
}
}

View File

@@ -1,18 +1,16 @@
/* eslint-disable react/jsx-max-depth */
/**
* @prettier
*/
import React, { Component } from 'react';
import { DetailContextConsumer } from '../../pages/version/index';
import List from '@material-ui/core/List/index';
import DownloadIcon from '@material-ui/icons/CloudDownload';
import BugReportIcon from '@material-ui/icons/BugReport';
import DownloadIcon from '@material-ui/icons/CloudDownload';
import HomeIcon from '@material-ui/icons/Home';
import List from '@material-ui/core/List/index';
import Tooltip from '@material-ui/core/Tooltip/index';
import { DetailContextConsumer } from '../../pages/version/index';
import { Fab, ActionListItem } from './styles';
const ACTIONS = {
@@ -46,24 +44,14 @@ class ActionBar extends Component<any, any> {
return null;
}
return (
<a href={link} target={"_blank"}>
<a href={link} target={'_blank'}>
{component}
</a>
);
}
renderActionBarListItems = (packageMeta) => {
const {
latest: {
bugs: {
url: issue,
} = {},
homepage,
dist: {
tarball,
} = {},
} = {},
} = packageMeta;
renderActionBarListItems = packageMeta => {
const { latest: { bugs: { url: issue } = {}, homepage, dist: { tarball } = {} } = {} } = packageMeta;
const actionsMap = {
homepage,
@@ -74,11 +62,7 @@ class ActionBar extends Component<any, any> {
const renderList = Object.keys(actionsMap).reduce((component, value, key) => {
const link = actionsMap[value];
if (link) {
const fab = (
<Fab size={'small'}>
{ACTIONS[value]['icon']}
</Fab>
);
const fab = <Fab size={'small'}>{ACTIONS[value]['icon']}</Fab>;
component.push(
<Tooltip key={key} title={ACTIONS[value]['title']}>
{this.renderIconsWithLink(link, fab)}
@@ -90,19 +74,13 @@ class ActionBar extends Component<any, any> {
return (
<>
<ActionListItem alignItems={'flex-start'}>
{renderList}
</ActionListItem>
<ActionListItem alignItems={'flex-start'}>{renderList}</ActionListItem>
</>
);
};
renderActionBar = ({ packageMeta = {} }) => {
return (
<List>
{this.renderActionBarListItems(packageMeta)}
</List>
);
return <List>{this.renderActionBarListItems(packageMeta)}</List>;
};
}

View File

@@ -4,15 +4,15 @@
*/
import React from 'react';
import type { Node } from 'react';
import FileCopy from '@material-ui/icons/FileCopy';
import Tooltip from '@material-ui/core/Tooltip/index';
import type { Node } from 'react';
import { IProps } from './types';
import { ClipBoardCopy, ClipBoardCopyText, CopyIcon } from './styles';
import { copyToClipBoardUtility } from '../../utils/cli-utils';
import { TEXT } from '../../utils/constants';
import { IProps } from './types';
const CopyToClipBoard = ({ text, children }: IProps): Node => {
const renderToolTipFileCopy = () => (

View File

@@ -3,8 +3,6 @@
* @flow
*/
/* eslint react/jsx-max-depth: 0 */
import React, { Component, Fragment } from 'react';
import { withRouter } from 'react-router-dom';
import CardContent from '@material-ui/core/CardContent/index';
@@ -40,7 +38,7 @@ class DepDetail extends Component<any, any> {
};
}
const WrappDepDetail = withRouter(DepDetail);
const WrapperDependencyDetail = withRouter(DepDetail);
class DependencyBlock extends Component<any, any> {
render() {
@@ -68,7 +66,7 @@ class DependencyBlock extends Component<any, any> {
deps.map(dep => {
const [name, version] = dep;
return <WrappDepDetail key={name} name={name} onLoading={enableLoading} version={version} />;
return <WrapperDependencyDetail key={name} name={name} onLoading={enableLoading} version={version} />;
});
}

View File

@@ -4,7 +4,7 @@ import Card from '@material-ui/core/Card/index';
import CardContent from '@material-ui/core/CardContent/index';
import List from '@material-ui/core/List/index';
import ActtionBar from '../ActionBar';
import ActionBar from '../ActionBar';
import Author from '../Author';
import Developers from '../Developers';
import Dist from '../Dist';
@@ -88,7 +88,7 @@ class DetailSidebar extends Component {
}
renderActionBar = () => {
return <ActtionBar />;
return <ActionBar />;
}
}

View File

@@ -1,15 +1,18 @@
import React, {Component} from 'react';
/**
* @prettier
*/
import React, { Component } from 'react';
import Avatar from '@material-ui/core/Avatar';
import Tooltip from '@material-ui/core/Tooltip';
import Add from '@material-ui/icons/Add';
import Tooltip from '@material-ui/core/Tooltip';
import { DetailContextConsumer } from '../../pages/version';
import { Details, Heading, Content, Fab } from './styles';
interface Props {
type: 'contributors' | 'maintainers'
type: 'contributors' | 'maintainers';
}
class Developers extends Component<Props, any> {
@@ -28,11 +31,11 @@ class Developers extends Component<Props, any> {
}}
</DetailContextConsumer>
);
};
}
handleLoadMore = () => {
this.setState((prev) => ({ visibleDevs: prev.visibleDevs + 6 }));
}
this.setState(prev => ({ visibleDevs: prev.visibleDevs + 6 }));
};
renderDevelopers = (developers, packageMeta) => {
const { type } = this.props;
@@ -44,40 +47,33 @@ class Developers extends Component<Props, any> {
{developers.slice(0, visibleDevs).map(developer => (
<Details key={developer.email}>{this.renderDeveloperDetails(developer, packageMeta)}</Details>
))}
{visibleDevs < developers.length &&
<Fab onClick={this.handleLoadMore} size={'small'}><Add /></Fab>
}
{visibleDevs < developers.length && (
<Fab onClick={this.handleLoadMore} size={'small'}>
<Add />
</Fab>
)}
</Content>
</>
);
}
};
renderLinkForMail(email, avatarComponent, packageName, version) {
if(!email) {
if (!email) {
return avatarComponent;
}
return (
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={"_top"}>
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={'_top'}>
{avatarComponent}
</a>
);
}
renderDeveloperDetails = ({ name, avatar, email }, packageMeta) => {
const {
name: packageName,
version,
} = packageMeta.latest;
const avatarComponent = <Avatar aria-label={name} src={avatar} />;
return (
<Tooltip title={name}>
{this.renderLinkForMail(email, avatarComponent, packageName, version)}
</Tooltip>
);
}
const { name: packageName, version } = packageMeta.latest;
const avatarComponent = <Avatar aria-label={name} src={avatar} />;
return <Tooltip title={name}>{this.renderLinkForMail(email, avatarComponent, packageName, version)}</Tooltip>;
};
}
export default Developers;

View File

@@ -2,13 +2,12 @@
* @prettier
*/
/* eslint-disable */
import React, { Component } from 'react';
import List from '@material-ui/core/List/index';
import { DetailContextConsumer } from '../../pages/version/index';
import { Heading, DistListItem, DistChips, DownloadButton } from './styles';
import { Heading, DistListItem, DistChips } from './styles';
import fileSizeSI from '../../utils/file-size';
class Dist extends Component<any, any> {
@@ -34,10 +33,11 @@ class Dist extends Component<any, any> {
if (value) {
const label = (
<span>
<b>{title.split('-').join(' ')}</b>: {value}
{/* eslint-disable-next-line */}
<b>{title.split('-').join(' ')}</b>:{value}
</span>
);
componentList.push(<DistChips label={label} key={key} />);
componentList.push(<DistChips key={key} label={label} />);
}
return componentList;
}, []);

View File

@@ -1,5 +1,8 @@
/* eslint-disable */
import React, {Component} from 'react';
/**
* @prettier
*/
import React, { Component } from 'react';
import Avatar from '@material-ui/core/Avatar/index';
import Grid from '@material-ui/core/Grid/index';
@@ -7,29 +10,27 @@ import List from '@material-ui/core/List/index';
import ListItemText from '@material-ui/core/ListItemText/index';
import { DetailContextConsumer } from '../../pages/version/index';
import { Heading, EngineListItem } from './styles';
import node from './img/node.png';
import npm from '../Install/img/npm.svg'
import npm from '../Install/img/npm.svg';
const ICONS = {
'node-JS': <Avatar src={node} />,
'NPM-version': <Avatar src={npm} />,
}
};
class Engine extends Component {
render() {
return (
<DetailContextConsumer>
{(context) => {
{context => {
return this.renderEngine(context);
}}
</DetailContextConsumer>
);
};
}
renderEngine = ({packageMeta}) => {
renderEngine = ({ packageMeta }) => {
const { engines } = packageMeta.latest;
if (!engines) {
return null;
@@ -37,14 +38,14 @@ class Engine extends Component {
const engineDict = {
'node-JS': engines.node,
'NPM-version': engines.npm
}
'NPM-version': engines.npm,
};
const items = Object.keys(engineDict).reduce((markup, text, key) => {
const heading = engineDict[text]
if (heading){
const heading = engineDict[text];
if (heading) {
markup.push(
<Grid item={true} xs={6} key={key}>
<Grid item={true} key={key} xs={6}>
{this.renderListItems(heading, text)}
</Grid>
);
@@ -56,23 +57,19 @@ class Engine extends Component {
return null;
}
return (
<Grid container={true}>
{items}
</Grid>
);
}
return <Grid container={true}>{items}</Grid>;
};
renderListItems = (heading, text) => {
return (
<List subheader={<Heading variant={"subheading"}>{text.split('-').join(' ')}</Heading>}>
<List subheader={<Heading variant={'subheading'}>{text.split('-').join(' ')}</Heading>}>
<EngineListItem>
{ ICONS[text] }
{ICONS[text]}
<ListItemText primary={heading} />
</EngineListItem>
</List>
);
}
};
}
export default Engine;

View File

@@ -6,7 +6,6 @@
import React from 'react';
import type { Element } from 'react';
import { version } from '../../../../package.json';
import { Wrapper, Left, Right, Earth, Flags, Love, Flag, Logo, Inner, ToolTip } from './styles';
import { goToVerdaccioWebsite } from '../../utils/windows.js';
@@ -28,7 +27,7 @@ const MADEWITH_LABEL = ' Made with';
const ON_LABEL = 'on';
const HEARTH_EMOJI = '♥';
const renderRight = () => (
const renderRight = (version = window.VERDACCIO_VERSION) => (
<Right>
{POWERED_LABEL}
<Logo img={true} name={'verdaccio'} onClick={goToVerdaccioWebsite} pointer={true} size={'md'} />

View File

@@ -6,12 +6,13 @@
import styled, { css } from 'react-emotion';
import mq from '../../utils/styles/media';
import Icon from '../Icon';
import colors from '../../utils/styles/colors';
export const Wrapper = styled.div`
&& {
background: #f9f9f9;
border-top: 1px solid #e3e3e3;
color: #999999;
background: ${colors.snow};
border-top: 1px solid ${colors.greyGainsboro};
color: ${colors.nobel01};
font-size: 14px;
padding: 20px;
}
@@ -67,7 +68,7 @@ export const Earth = styled(Icon)`
export const Flags = styled.span`
&& {
position: absolute;
background: #d3dddd;
background: ${colors.greyAthens};
padding: 1px 4px;
border-radius: 3px;
height: 20px;
@@ -82,7 +83,7 @@ export const Flags = styled.span`
left: -4px;
margin-left: -5px;
border: 5px solid;
border-color: #d3dddd transparent transparent transparent;
border-color: ${colors.greyAthens} transparent transparent transparent;
transform: rotate(90deg);
}
${ToolTip}:hover & {
@@ -93,7 +94,7 @@ export const Flags = styled.span`
export const Love = styled.span`
&& {
color: #e25555;
color: ${colors.love};
padding: 0 5px;
}
`;

View File

@@ -12,6 +12,7 @@
window.VERDACCIO_API_URL = '<%= htmlWebpackPlugin.options.verdaccioURL %>/-/verdaccio/';
window.VERDACCIO_SCOPE = '<%= htmlWebpackPlugin.options.scope %>';
window.VERDACCIO_LOGO = '<%= htmlWebpackPlugin.options.logo %>';
window.VERDACCIO_VERSION = '<%= htmlWebpackPlugin.options.version_app %>';
</script>
</head>

View File

@@ -21,7 +21,7 @@ export const copyToClipBoardUtility = (str: string) => (event: SyntheticEvent<HT
};
export function getCLISetConfigRegistry(command: string, scope: string, registryUrl: string): string {
return `${command} ${scope} registry ${registryUrl}`;
return `${command} ${scope}registry ${registryUrl}`;
}
export function getCLISetRegistry(command: string, registryUrl: string): string {

View File

@@ -22,6 +22,7 @@ const colors = {
paleNavy: '#e4e8f1',
saltpan: '#f7f8f6',
snow: '#f9f9f9',
love: '#e25555',
nobel01: '#999999',
nobel02: '#9f9f9f',

View File

@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Footer /> component should load the initial state of Footer component 1`] = `"<div class=\\"css-i0nj2g e19gp4r80\\"><div class=\\"css-hzfs9b e19gp4r81\\"><div class=\\"css-d8nsp7 e19gp4r82\\"> Made with<span class=\\"css-1so4oe0 e19gp4r87\\">♥</span>on<span class=\\"css-1ie354y e19gp4r84\\"><svg class=\\"e19gp4r85 css-1kgp95j e9byyw50\\"><title>Earth</title><use xlink:href=\\"[object Object]#earth\\"></use></svg><span class=\\"css-1v4n0q4 e19gp4r86\\"><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Spain</title><use xlink:href=\\"[object Object]#spain\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Nicaragua</title><use xlink:href=\\"[object Object]#nicaragua\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>India</title><use xlink:href=\\"[object Object]#india\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Brazil</title><use xlink:href=\\"[object Object]#brazil\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>China</title><use xlink:href=\\"[object Object]#china\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Austria</title><use xlink:href=\\"[object Object]#austria\\"></use></svg></span></span></div><div class=\\"css-1wbzdyy e19gp4r83\\">Powered by<span class=\\"e19gp4r88 css-i15wza e9byyw51\\" title=\\"Verdaccio\\"><img alt=\\"Verdaccio\\" src=\\"[object Object]\\" class=\\"css-1ncdhax e9byyw52\\"></span>/ 4.0.0-alpha.3</div></div></div>"`;
exports[`<Footer /> component should load the initial state of Footer component 1`] = `"<div class=\\"css-i0nj2g e19gp4r80\\"><div class=\\"css-hzfs9b e19gp4r81\\"><div class=\\"css-d8nsp7 e19gp4r82\\"> Made with<span class=\\"css-1so4oe0 e19gp4r87\\">♥</span>on<span class=\\"css-1ie354y e19gp4r84\\"><svg class=\\"e19gp4r85 css-1kgp95j e9byyw50\\"><title>Earth</title><use xlink:href=\\"[object Object]#earth\\"></use></svg><span class=\\"css-1v4n0q4 e19gp4r86\\"><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Spain</title><use xlink:href=\\"[object Object]#spain\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Nicaragua</title><use xlink:href=\\"[object Object]#nicaragua\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>India</title><use xlink:href=\\"[object Object]#india\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Brazil</title><use xlink:href=\\"[object Object]#brazil\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>China</title><use xlink:href=\\"[object Object]#china\\"></use></svg><svg class=\\"e19gp4r88 css-f1ndto e9byyw50\\"><title>Austria</title><use xlink:href=\\"[object Object]#austria\\"></use></svg></span></span></div><div class=\\"css-1wbzdyy e19gp4r83\\">Powered by<span class=\\"e19gp4r88 css-i15wza e9byyw51\\" title=\\"Verdaccio\\"><img alt=\\"Verdaccio\\" src=\\"[object Object]\\" class=\\"css-1ncdhax e9byyw52\\"></span>/ v.1.0.0</div></div></div>"`;

View File

@@ -1,5 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<LoginModal /> should load the component in default state 1`] = `"<div role=\\"dialog\\" class=\\"mui-fixed MuiModal-root-15 MuiDialog-root-1\\" id=\\"login--form-container\\" style=\\"padding-right: 0px;\\"><div class=\\"MuiBackdrop-root-17\\" aria-hidden=\\"true\\" style=\\"opacity: 1; -webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\"></div><div class=\\"MuiDialog-container-4 MuiDialog-scrollPaper-2\\" role=\\"document\\" style=\\"opacity: 1; -webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\" tabindex=\\"-1\\"><div class=\\"MuiPaper-root-19 MuiPaper-elevation24-45 MuiPaper-rounded-20 MuiDialog-paper-5 MuiDialog-paperScrollPaper-6 MuiDialog-paperWidthXs-8 MuiDialog-paperFullWidth-13\\"><form novalidate=\\"\\"><div class=\\"MuiDialogTitle-root-46\\"><h2 class=\\"MuiTypography-root-47 MuiTypography-title-53\\">Login</h2></div><div class=\\"MuiDialogContent-root-83\\"><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"username\\">Username<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114\\" id=\\"login--form-username\\" placeholder=\\"Your username\\" required=\\"\\" type=\\"text\\" value=\\"\\"></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\" style=\\"margin-top: 8px;\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"password\\">Password<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114 MuiInputBase-inputType-132 MuiInput-inputType-117\\" id=\\"login--form-password\\" placeholder=\\"Your strong password\\" required=\\"\\" type=\\"password\\" value=\\"\\"></div></div></div><div class=\\"MuiDialogActions-root-136 dialog-footer\\"><button class=\\"MuiButtonBase-root-164 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"0\\" type=\\"button\\" id=\\"login--form-cancel\\"><span class=\\"MuiButton-label-139\\">Cancel</span><span class=\\"MuiTouchRipple-root-167\\"></span></button><button class=\\"MuiButtonBase-root-164 MuiButtonBase-disabled-165 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-disabled-158 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"-1\\" type=\\"submit\\" disabled=\\"\\" id=\\"login--form-submit\\"><span class=\\"MuiButton-label-139\\">Login</span></button></div></form></div></div></div>"`;
exports[`<LoginModal /> should load the component in default state 1`] = `"<div role=\\"dialog\\" class=\\"mui-fixed MuiModal-root-15 MuiDialog-root-1\\" id=\\"login--form-container\\" style=\\"padding-right: 0px;\\"><div class=\\"MuiBackdrop-root-17\\" aria-hidden=\\"true\\" style=\\"opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\"></div><div class=\\"MuiDialog-container-4 MuiDialog-scrollPaper-2\\" role=\\"document\\" style=\\"opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\" tabindex=\\"-1\\"><div class=\\"MuiPaper-root-19 MuiPaper-elevation24-45 MuiPaper-rounded-20 MuiDialog-paper-5 MuiDialog-paperScrollPaper-6 MuiDialog-paperWidthXs-8 MuiDialog-paperFullWidth-13\\"><form novalidate=\\"\\"><div class=\\"MuiDialogTitle-root-46\\"><h2 class=\\"MuiTypography-root-47 MuiTypography-title-53\\">Login</h2></div><div class=\\"MuiDialogContent-root-83\\"><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"username\\">Username<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114\\" id=\\"login--form-username\\" placeholder=\\"Your username\\" required=\\"\\" type=\\"text\\" value=\\"\\"></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\" style=\\"margin-top: 8px;\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"password\\">Password<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114 MuiInputBase-inputType-132 MuiInput-inputType-117\\" id=\\"login--form-password\\" placeholder=\\"Your strong password\\" required=\\"\\" type=\\"password\\" value=\\"\\"></div></div></div><div class=\\"MuiDialogActions-root-136 dialog-footer\\"><button class=\\"MuiButtonBase-root-164 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"0\\" type=\\"button\\" id=\\"login--form-cancel\\"><span class=\\"MuiButton-label-139\\">Cancel</span><span class=\\"MuiTouchRipple-root-167\\"></span></button><button class=\\"MuiButtonBase-root-164 MuiButtonBase-disabled-165 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-disabled-158 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"-1\\" type=\\"submit\\" disabled=\\"\\" id=\\"login--form-submit\\"><span class=\\"MuiButton-label-139\\">Login</span></button></div></form></div></div></div>"`;
exports[`<LoginModal /> should load the component with props 1`] = `"<div role=\\"dialog\\" class=\\"mui-fixed MuiModal-root-15 MuiDialog-root-1\\" id=\\"login--form-container\\"><div class=\\"MuiBackdrop-root-17\\" aria-hidden=\\"true\\" style=\\"opacity: 1; -webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\"></div><div class=\\"MuiDialog-container-4 MuiDialog-scrollPaper-2\\" role=\\"document\\" style=\\"opacity: 1; -webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\" tabindex=\\"-1\\"><div class=\\"MuiPaper-root-19 MuiPaper-elevation24-45 MuiPaper-rounded-20 MuiDialog-paper-5 MuiDialog-paperScrollPaper-6 MuiDialog-paperWidthXs-8 MuiDialog-paperFullWidth-13\\"><form novalidate=\\"\\"><div class=\\"MuiDialogTitle-root-46\\"><h2 class=\\"MuiTypography-root-47 MuiTypography-title-53\\">Login</h2></div><div class=\\"MuiDialogContent-root-83\\"><div class=\\"MuiTypography-root-47 MuiTypography-body1-56 MuiPaper-root-19 MuiPaper-elevation6-27 MuiSnackbarContent-root-174 loginError\\" role=\\"alertdialog\\"><div class=\\"MuiSnackbarContent-message-175\\"><div class=\\"loginErrorMsg\\" id=\\"client-snackbar\\"><svg class=\\"MuiSvgIcon-root-177 loginIcon\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\\"></path></svg><span><div><strong>Error Title</strong></div><div>Error Description</div></span></div></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"username\\">Username<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114\\" id=\\"login--form-username\\" placeholder=\\"Your username\\" required=\\"\\" type=\\"text\\" value=\\"\\"></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\" style=\\"margin-top: 8px;\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"password\\">Password<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114 MuiInputBase-inputType-132 MuiInput-inputType-117\\" id=\\"login--form-password\\" placeholder=\\"Your strong password\\" required=\\"\\" type=\\"password\\" value=\\"\\"></div></div></div><div class=\\"MuiDialogActions-root-136 dialog-footer\\"><button class=\\"MuiButtonBase-root-164 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"0\\" type=\\"button\\" id=\\"login--form-cancel\\"><span class=\\"MuiButton-label-139\\">Cancel</span><span class=\\"MuiTouchRipple-root-167\\"></span></button><button class=\\"MuiButtonBase-root-164 MuiButtonBase-disabled-165 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-disabled-158 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"-1\\" type=\\"submit\\" disabled=\\"\\" id=\\"login--form-submit\\"><span class=\\"MuiButton-label-139\\">Login</span></button></div></form></div></div></div>"`;
exports[`<LoginModal /> should load the component with props 1`] = `"<div role=\\"dialog\\" class=\\"mui-fixed MuiModal-root-15 MuiDialog-root-1\\" id=\\"login--form-container\\"><div class=\\"MuiBackdrop-root-17\\" aria-hidden=\\"true\\" style=\\"opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\"></div><div class=\\"MuiDialog-container-4 MuiDialog-scrollPaper-2\\" role=\\"document\\" style=\\"opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\\" tabindex=\\"-1\\"><div class=\\"MuiPaper-root-19 MuiPaper-elevation24-45 MuiPaper-rounded-20 MuiDialog-paper-5 MuiDialog-paperScrollPaper-6 MuiDialog-paperWidthXs-8 MuiDialog-paperFullWidth-13\\"><form novalidate=\\"\\"><div class=\\"MuiDialogTitle-root-46\\"><h2 class=\\"MuiTypography-root-47 MuiTypography-title-53\\">Login</h2></div><div class=\\"MuiDialogContent-root-83\\"><div class=\\"MuiTypography-root-47 MuiTypography-body1-56 MuiPaper-root-19 MuiPaper-elevation6-27 MuiSnackbarContent-root-174 loginError\\" role=\\"alertdialog\\"><div class=\\"MuiSnackbarContent-message-175\\"><div class=\\"loginErrorMsg\\" id=\\"client-snackbar\\"><svg class=\\"MuiSvgIcon-root-177 loginIcon\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path fill=\\"none\\" d=\\"M0 0h24v24H0z\\"></path><path d=\\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\\"></path></svg><span><div><strong>Error Title</strong></div><div>Error Description</div></span></div></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"username\\">Username<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114\\" id=\\"login--form-username\\" placeholder=\\"Your username\\" required=\\"\\" type=\\"text\\" value=\\"\\"></div></div><div class=\\"MuiFormControl-root-84 MuiFormControl-fullWidth-87\\" style=\\"margin-top: 8px;\\"><label class=\\"MuiFormLabel-root-99 MuiFormLabel-required-104 MuiInputLabel-required-92 MuiInputLabel-root-88 MuiInputLabel-formControl-93 MuiInputLabel-animated-96\\" data-shrink=\\"false\\" for=\\"password\\">Password<span class=\\"MuiFormLabel-asterisk-105\\"> *</span></label><div class=\\"MuiInputBase-root-119 MuiInput-root-106 MuiInput-underline-110 MuiInputBase-formControl-120 MuiInput-formControl-107\\"><input aria-invalid=\\"false\\" class=\\"MuiInputBase-input-129 MuiInput-input-114 MuiInputBase-inputType-132 MuiInput-inputType-117\\" id=\\"login--form-password\\" placeholder=\\"Your strong password\\" required=\\"\\" type=\\"password\\" value=\\"\\"></div></div></div><div class=\\"MuiDialogActions-root-136 dialog-footer\\"><button class=\\"MuiButtonBase-root-164 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"0\\" type=\\"button\\" id=\\"login--form-cancel\\"><span class=\\"MuiButton-label-139\\">Cancel</span><span class=\\"MuiTouchRipple-root-167\\"></span></button><button class=\\"MuiButtonBase-root-164 MuiButtonBase-disabled-165 MuiButton-root-138 MuiButton-text-140 MuiButton-flat-143 MuiButton-disabled-158 MuiButton-colorInherit-159 MuiDialogActions-action-137\\" tabindex=\\"-1\\" type=\\"submit\\" disabled=\\"\\" id=\\"login--form-submit\\"><span class=\\"MuiButton-label-139\\">Login</span></button></div></form></div></div></div>"`;

View File

@@ -6,12 +6,14 @@ import Footer from '../../../../src/webui/components/Footer/index';
jest.mock('../../../../package.json', () => ({
version: '4.0.0-alpha.3'
}))
}));
describe('<Footer /> component', () => {
let wrapper;
beforeEach(() => {
window.VERDACCIO_VERSION = 'v.1.0.0';
wrapper = mount(<Footer />);
delete window.VERDACCIO_VERSION;
});
test('should load the initial state of Footer component', () => {

56
tools/_config.yaml Normal file
View File

@@ -0,0 +1,56 @@
web:
title: Verdaccio
# gravatar: false
# sort_packages: asc
plugins: ../
auth:
auth-memory:
users:
foo:
name: test
password: test
bar:
name: bar
password: test
store:
memory:
limit: 1000
# theme:
security:
api:
jwt:
sign:
expiresIn: 60d
notBefore: 1
web:
sign:
expiresIn: 7d
notBefore: 1
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
'@*/*':
access: $all
publish: $authenticated
unpublish: $authenticated
'**':
access: $all
publish: $authenticated
unpublish: $authenticated
middlewares:
audit:
enabled: true
logs:
- { type: stdout, format: pretty, level: trace }

View File

@@ -32,7 +32,7 @@ new WebpackDevServer(compiler, {
},
proxy: [{
context: ['/-/verdaccio/logo', '/-/verdaccio/packages', '/-/static/logo.png'],
target: 'http://localhost:4873',
target: 'http://localhost:8080',
}],
}).listen(4872, 'localhost', function(err) {
if (err) {

23
tools/verdaccio.js Normal file
View File

@@ -0,0 +1,23 @@
/**
* @prettier
*/
const fs = require('fs');
const startServer = require('verdaccio').default;
const yalm = require('js-yaml');
const configJsonFormat = yalm.safeLoad(fs.readFileSync('./tools/_config.yaml', 'utf8'));
const handler = function(webServer, addr, pkgName, pkgVersion) {
webServer.listen(addr.port || addr.path, addr.host, () => {
console.log(`${pkgName}:${pkgVersion} running ${addr.proto}://${addr.host}:${addr.port}`);
});
process.on('SIGTERM', () => {
webServer.close(() => {
console.log('Process terminated');
});
});
};
startServer(configJsonFormat, 8080, '', '1.0.0', 'verdaccio', handler);

View File

@@ -38,7 +38,7 @@ export default {
scope: '',
logo: 'https://verdaccio.org/img/logo/symbol/svg/verdaccio-tiny.svg',
filename: 'index.html',
verdaccioURL: '//localhost:4873',
verdaccioURL: '//localhost:8080',
template: `${env.SRC_ROOT}/webui/template/index.html`,
debug: true,
inject: true,

View File

@@ -50,6 +50,7 @@ const prodConf = {
filename: 'index.html',
favicon: `${env.SRC_ROOT}/webui/template/favicon.ico`,
verdaccioURL: 'ToReplaceByVerdaccio',
version_app: 'ToReplaceByVersion',
template: `${env.SRC_ROOT}/webui/template/index.html`,
debug: false,
inject: true,

5335
yarn.lock

File diff suppressed because it is too large Load Diff