Compare commits
12 Commits
@verdaccio
...
@verdaccio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ef60915e6 | ||
|
|
55ee3fdd97 | ||
|
|
4ebf18816a | ||
|
|
276a0a63a7 | ||
|
|
f3f00052d8 | ||
|
|
d2c65da9c7 | ||
|
|
2924ffa235 | ||
|
|
6b1a28deb8 | ||
|
|
a54c18c02a | ||
|
|
52b47868e3 | ||
|
|
8582548559 | ||
|
|
32f66cc2c7 |
5
.changeset/calm-pants-impress.md
Normal file
5
.changeset/calm-pants-impress.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'verdaccio-aws-s3-storage': patch
|
||||
---
|
||||
|
||||
Fix the prefix used to delete from s3 when unpublishing packages
|
||||
5
.changeset/gold-vans-tease.md
Normal file
5
.changeset/gold-vans-tease.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@verdaccio/utils': patch
|
||||
---
|
||||
|
||||
Fixed the validation of the name when searching for a tarball that have scoped package name
|
||||
6
.changeset/heavy-ravens-lay.md
Normal file
6
.changeset/heavy-ravens-lay.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@verdaccio/cli': minor
|
||||
'@verdaccio/fastify-migration': minor
|
||||
---
|
||||
|
||||
[Fastify] Add ping endpoint
|
||||
@@ -33,24 +33,27 @@
|
||||
"verdaccio-aws-s3-storage": "11.0.0-alpha.0",
|
||||
"verdaccio-google-cloud": "11.0.0-alpha.0",
|
||||
"verdaccio-memory": "11.0.0-alpha.0",
|
||||
"@verdaccio/website": "0.0.1",
|
||||
"@verdaccio/ui-theme": "6.0.0-alpha.1",
|
||||
"@verdaccio/e2e-cli": "1.0.0",
|
||||
"@verdaccio/e2e-ui": "1.0.0",
|
||||
"@verdaccio/cli-standalone": "6.0.0-alpha.3",
|
||||
"@verdaccio/tarball": "11.0.0-alpha.3",
|
||||
"@verdaccio/url": "11.0.0-alpha.3",
|
||||
"@verdaccio/fastify-migration": "6.0.0-6-next.9"
|
||||
"@verdaccio/fastify-migration": "6.0.0-6-next.9",
|
||||
"@verdaccio/eslint-config": "1.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-mice-obey",
|
||||
"big-lobsters-sin",
|
||||
"calm-pants-impress",
|
||||
"few-cooks-destroy",
|
||||
"fifty-jars-rest",
|
||||
"gentle-parrots-lay",
|
||||
"gentle-trains-switch",
|
||||
"gold-vans-tease",
|
||||
"healthy-bikes-behave",
|
||||
"healthy-poets-compare",
|
||||
"heavy-ravens-lay",
|
||||
"hip-hounds-destroy",
|
||||
"late-adults-love",
|
||||
"late-parents-act",
|
||||
|
||||
@@ -9,4 +9,3 @@ Full package name queries was not finding anithing. It was happening
|
||||
becouse of stemmer of [lunr.js](https://lunrjs.com/).
|
||||
|
||||
To fix this, the stemmer of [lunr.js](https://lunrjs.com/) was removed from search pipeline.
|
||||
|
||||
|
||||
102
.eslintrc
102
.eslintrc
@@ -1,102 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"google",
|
||||
"plugin:react/recommended",
|
||||
"plugin:jest/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/typescript",
|
||||
"plugin:jsx-a11y/recommended",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": ["import", "jest", "jsx-a11y", "react-hooks"],
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"globals": {
|
||||
"__APP_VERSION__": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"allowImportExportEverywhere": true,
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 11,
|
||||
"ecmaFeatures": {
|
||||
"impliedStrict": true,
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"extensions": [".js", ".jsx", ".ts", ".tsx"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"rules": {
|
||||
"curly": ["error", "all"],
|
||||
"react/prop-types": 0,
|
||||
"jest/no-export": 0,
|
||||
"jest/no-test-callback": 0,
|
||||
"jest/expect-expect": 0,
|
||||
"jest/no-try-expect": 0,
|
||||
"jest/no-done-callback": "off",
|
||||
"jest/no-conditional-expect": "off",
|
||||
"keyword-spacing": "off",
|
||||
"no-tabs": "off",
|
||||
"no-useless-escape": "off",
|
||||
"padded-blocks": "off",
|
||||
"require-jsdoc": "off",
|
||||
"valid-jsdoc": "off",
|
||||
"import/order": ["error"],
|
||||
"eol-last": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
||||
"no-trailing-spaces": "error",
|
||||
"camelcase": "off",
|
||||
"guard-for-in": "error",
|
||||
"new-cap": "error",
|
||||
"max-len": ["error", 100],
|
||||
"no-console": ["error", { "allow": ["warn"] }],
|
||||
"no-constant-condition": "error",
|
||||
"no-debugger": "error",
|
||||
"no-empty": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-invalid-this": "error",
|
||||
"no-new-require": "error",
|
||||
"no-undef": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-var": "error",
|
||||
"one-var": "error",
|
||||
"prefer-rest-params": "error",
|
||||
"prefer-spread": "error",
|
||||
"handle-callback-err": 0,
|
||||
"prefer-const": 0,
|
||||
"@typescript-eslint/camelcase": 0,
|
||||
"@typescript-eslint/ban-ts-ignore": 0,
|
||||
"@typescript-eslint/no-var-requires": 0,
|
||||
"@typescript-eslint/no-inferrable-types": 0,
|
||||
"@typescript-eslint/no-empty-function": 0,
|
||||
"@typescript-eslint/no-this-alias": 0,
|
||||
"@typescript-eslint/no-use-before-define": 0,
|
||||
"@typescript-eslint/array-type": ["error"],
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/indent": 0,
|
||||
"@typescript-eslint/ban-ts-comment": 0,
|
||||
"@typescript-eslint/ban-types": 0,
|
||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||
|
||||
// rules to fix
|
||||
"no-unused-vars": ["warn", { "vars": "all", "args": "none" }],
|
||||
"jest/no-identical-title": ["warn"],
|
||||
"prefer-promise-reject-errors": ["warn"],
|
||||
"jest/no-disabled-tests": ["warn"],
|
||||
"jest/no-commented-out-tests": ["warn"],
|
||||
"@typescript-eslint/prefer-optional-chain": ["warn"],
|
||||
"@typescript-eslint/explicit-member-accessibility": ["warn"],
|
||||
"@typescript-eslint/no-unused-vars": ["warn"]
|
||||
}
|
||||
}
|
||||
3
.eslintrc.js
Normal file
3
.eslintrc.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: ['@verdaccio/eslint-config'],
|
||||
};
|
||||
23
.github/workflows/ci.yml
vendored
23
.github/workflows/ci.yml
vendored
@@ -100,8 +100,6 @@ jobs:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
## we run scripts due gatsby needs it
|
||||
## when website is excluded we can add --ignore-scripts
|
||||
run: pnpm recursive install --frozen-lockfile --ignore-scripts
|
||||
- name: build
|
||||
run: pnpm build
|
||||
@@ -194,27 +192,6 @@ jobs:
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
- name: Test CLI
|
||||
run: pnpm test:e2e:cli
|
||||
website:
|
||||
needs: [format, lint]
|
||||
runs-on: ubuntu-latest
|
||||
name: website build node 14
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 14
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@latest -g
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
- name: Build website
|
||||
run: |
|
||||
cd website
|
||||
pnpm build:website
|
||||
test-windows:
|
||||
needs: [format, lint]
|
||||
runs-on: windows-latest
|
||||
|
||||
@@ -10,7 +10,7 @@ let _localMemory = require('./local-memory');
|
||||
let _localMemory2 = _interopRequireDefault(_localMemory);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
return obj && obj.__esModule ? obj : {default: obj};
|
||||
}
|
||||
|
||||
exports.LocalMemory = _localMemory2.default;
|
||||
|
||||
@@ -9,7 +9,7 @@ let _memoryHandler = require('./memory-handler');
|
||||
let _memoryHandler2 = _interopRequireDefault(_memoryHandler);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
return obj && obj.__esModule ? obj : {default: obj};
|
||||
}
|
||||
|
||||
const DEFAULT_LIMIT = 1000;
|
||||
@@ -43,8 +43,8 @@ class LocalMemory {
|
||||
cb(null);
|
||||
} else {
|
||||
this.logger.info(
|
||||
{ limit: this.limit },
|
||||
'Storage memory has reached limit of @{limit} packages'
|
||||
{limit: this.limit},
|
||||
'Storage memory has reached limit of @{limit} packages',
|
||||
);
|
||||
cb(new Error('Storage memory has reached limit of limit packages'));
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ let _memoryFs2 = _interopRequireDefault(_memoryFs);
|
||||
let _streams = require('@verdaccio/streams');
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
return obj && obj.__esModule ? obj : {default: obj};
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
@@ -111,8 +111,8 @@ class MemoryHandler {
|
||||
const uploadStream = new _streams.UploadTarball();
|
||||
const temporalName = `/${name}`;
|
||||
|
||||
process.nextTick(function () {
|
||||
fs.exists(temporalName, function (exists) {
|
||||
process.nextTick(function() {
|
||||
fs.exists(temporalName, function(exists) {
|
||||
if (exists) {
|
||||
return uploadStream.emit('error', fSError(fileExist));
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class MemoryHandler {
|
||||
|
||||
uploadStream.pipe(file);
|
||||
|
||||
uploadStream.done = function () {
|
||||
uploadStream.done = function() {
|
||||
const onEnd = function onEnd() {
|
||||
uploadStream.emit('success');
|
||||
};
|
||||
@@ -130,7 +130,7 @@ class MemoryHandler {
|
||||
uploadStream.on('end', onEnd);
|
||||
};
|
||||
|
||||
uploadStream.abort = function () {
|
||||
uploadStream.abort = function() {
|
||||
uploadStream.emit('error', fSError('transmision aborted', 400));
|
||||
file.end();
|
||||
};
|
||||
@@ -150,8 +150,8 @@ class MemoryHandler {
|
||||
|
||||
const readTarballStream = new _streams.ReadTarball();
|
||||
|
||||
process.nextTick(function () {
|
||||
fs.exists(pathName, function (exists) {
|
||||
process.nextTick(function() {
|
||||
fs.exists(pathName, function(exists) {
|
||||
if (!exists) {
|
||||
readTarballStream.emit('error', noPackageFoundError());
|
||||
} else {
|
||||
@@ -164,7 +164,7 @@ class MemoryHandler {
|
||||
readTarballStream.emit('error', error);
|
||||
});
|
||||
|
||||
readTarballStream.abort = function () {
|
||||
readTarballStream.abort = function() {
|
||||
readStream.destroy(fSError('read has been aborted', 400));
|
||||
};
|
||||
}
|
||||
|
||||
27
package.json
27
package.json
@@ -39,7 +39,7 @@
|
||||
"@babel/register": "7.13.14",
|
||||
"@babel/runtime": "7.13.10",
|
||||
"@changesets/changelog-github": "^0.2.8",
|
||||
"@changesets/cli": "^2.15.0",
|
||||
"@changesets/cli": "2.15.0",
|
||||
"@changesets/get-dependents-graph": "^1.2.0",
|
||||
"@commitlint/cli": "8.3.5",
|
||||
"@commitlint/config-conventional": "8.2.0",
|
||||
@@ -71,6 +71,7 @@
|
||||
"@typescript-eslint/parser": "4.13.0",
|
||||
"@verdaccio/types": "workspace:*",
|
||||
"@verdaccio/ui-theme": "workspace:*",
|
||||
"@verdaccio/eslint-config": "workspace:*",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "26.6.3",
|
||||
@@ -78,20 +79,21 @@
|
||||
"babel-plugin-emotion": "11.0.0",
|
||||
"codecov": "3.8.1",
|
||||
"concurrently": "^5.3.0",
|
||||
"core-js": "^3.10.1",
|
||||
"core-js": "^3.12.1",
|
||||
"cross-env": "7.0.3",
|
||||
"detect-secrets": "1.0.6",
|
||||
"eslint": "7.19.0",
|
||||
"eslint": "7.26.0",
|
||||
"eslint-config-google": "0.14.0",
|
||||
"eslint-config-prettier": "7.2.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-babel": "5.3.1",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jest": "24.1.3",
|
||||
"eslint-plugin-import": "2.23.2",
|
||||
"eslint-plugin-jest": "24.3.6",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react": "7.23.2",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
||||
"eslint-plugin-verdaccio": "9.6.1",
|
||||
"eslint-plugin-verdaccio": "10.0.0",
|
||||
"eslint-plugin-prettier": "3.4.0",
|
||||
"fs-extra": "9.1.0",
|
||||
"get-stdin": "7.0.0",
|
||||
"husky": "2.7.0",
|
||||
@@ -107,14 +109,14 @@
|
||||
"nock": "12.0.3",
|
||||
"nodemon": "^2.0.7",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "2.2.1",
|
||||
"prettier": "2.3.0",
|
||||
"rimraf": "3.0.2",
|
||||
"selfsigned": "1.10.8",
|
||||
"supertest": "4.0.2",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.4",
|
||||
"update-ts-references": "2.3.0",
|
||||
"verdaccio": "^5.0.1",
|
||||
"verdaccio": "^5.0.4",
|
||||
"verdaccio-audit": "workspace:*",
|
||||
"verdaccio-auth-memory": "workspace:*",
|
||||
"verdaccio-htpasswd": "workspace:*",
|
||||
@@ -126,7 +128,7 @@
|
||||
"docker": "docker build -t verdaccio/verdaccio:local . --no-cache",
|
||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
|
||||
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
|
||||
"lint": "eslint \"**/*.{js,jsx,ts,tsx}\"",
|
||||
"lint": "eslint --max-warnings 165 \"**/*.{js,jsx,ts,tsx}\"",
|
||||
"test": "pnpm recursive test --filter ./packages",
|
||||
"test:e2e:cli": "pnpm test --filter ...@verdaccio/e2e-cli",
|
||||
"test:e2e:ui": "pnpm test --filter ...@verdaccio/e2e-ui",
|
||||
@@ -139,9 +141,6 @@
|
||||
"start:ts": "ts-node packages/verdaccio/src/start.ts -- --listen 8000",
|
||||
"debug": "node --inspect packages/verdaccio/debug/bootstrap.js",
|
||||
"debug:break": "node --inspect-brk packages/verdaccio/debug/bootstrap.js",
|
||||
"website:lint": "cd website && yarn lint",
|
||||
"website:develop": "cd website && yarn develop",
|
||||
"website:build": "cd website && yarn build",
|
||||
"changeset": "changeset",
|
||||
"changeset:check": "changeset status --since-master",
|
||||
"ci:version": "run-s ci:version:changeset ci:version:install",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @verdaccio/api
|
||||
|
||||
## 6.0.0-6-next.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/auth@6.0.0-6-next.9
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/tarball@11.0.0-6-next.6
|
||||
- @verdaccio/middleware@6.0.0-6-next.9
|
||||
- @verdaccio/store@6.0.0-6-next.10
|
||||
- @verdaccio/hooks@6.0.0-6-next.4
|
||||
|
||||
## 6.0.0-6-next.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/api",
|
||||
"version": "6.0.0-6-next.11",
|
||||
"version": "6.0.0-6-next.12",
|
||||
"description": "loaders logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -39,15 +39,15 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/tarball": "workspace:11.0.0-6-next.5",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.10",
|
||||
"@verdaccio/tarball": "workspace:11.0.0-6-next.6",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"cookies": "0.8.0",
|
||||
"debug": "^4.1.1",
|
||||
"express": "4.17.1",
|
||||
@@ -56,7 +56,7 @@
|
||||
"semver": "7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"body-parser": "1.19.0",
|
||||
"lodash": "^4.17.20",
|
||||
|
||||
@@ -41,7 +41,7 @@ export default function (route, auth, storage): void {
|
||||
route.get('/-/v1/search', (req, res) => {
|
||||
// TODO: implement proper result scoring weighted by quality, popularity and
|
||||
// maintenance query parameters
|
||||
let [text, size, from /* , quality, popularity, maintenance */] = [
|
||||
let [text, size, from] = [
|
||||
'text',
|
||||
'size',
|
||||
'from' /* , 'quality', 'popularity', 'maintenance' */,
|
||||
|
||||
@@ -5,10 +5,11 @@ import { $ResponseExtend, $RequestExtend } from '../../types/custom';
|
||||
import { initializeServer, publishTaggedVersion, publishVersion } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
jest.mock('@verdaccio/auth', () => ({
|
||||
|
||||
@@ -11,10 +11,11 @@ import { $ResponseExtend, $RequestExtend } from '../../types/custom';
|
||||
import { initializeServer, publishVersion } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
jest.setTimeout(50000000);
|
||||
|
||||
@@ -16,10 +16,11 @@ import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
||||
import { initializeServer } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
const mockAuthenticate = jest.fn(() => (_name, _password, callback): void => {
|
||||
@@ -53,10 +54,11 @@ describe('user', () => {
|
||||
|
||||
test('should test add a new user', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
mockAddUser.mockImplementationOnce(() => (_name, _password, callback): void => {
|
||||
@@ -85,10 +87,11 @@ describe('user', () => {
|
||||
|
||||
test('should test fails on add a existing user with login', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
supertest(await initializeServer('user.yaml'))
|
||||
.put('/-/user/org.couchdb.user:jotaNew')
|
||||
@@ -124,10 +127,11 @@ describe('user', () => {
|
||||
|
||||
test('should test fails add a new user with missing name', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
mockAddUser.mockImplementationOnce(() => (_name, _password, callback): void => {
|
||||
return callback(getBadRequest(API_ERROR.USERNAME_PASSWORD_REQUIRED));
|
||||
@@ -153,10 +157,11 @@ describe('user', () => {
|
||||
|
||||
test('should test fails add a new user with missing password', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: undefined };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
const credentialsShort = _.cloneDeep(credentials);
|
||||
delete credentialsShort.password;
|
||||
@@ -181,10 +186,11 @@ describe('user', () => {
|
||||
|
||||
test('should test fails add a new user with wrong password', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test' };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test' };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
mockAuthenticate.mockImplementationOnce(() => (_name, _password, callback): void => {
|
||||
return callback(getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
||||
@@ -210,10 +216,11 @@ describe('user', () => {
|
||||
|
||||
test('should be able to logout an user', async (done) => {
|
||||
mockApiJWTmiddleware.mockImplementationOnce(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test' };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'test' };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
mockAuthenticate.mockImplementationOnce(() => (_name, _password, callback): void => {
|
||||
return callback(getUnauthorized(API_ERROR.BAD_USERNAME_PASSWORD));
|
||||
|
||||
@@ -6,10 +6,11 @@ import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
||||
import { initializeServer } from './_helper';
|
||||
|
||||
const mockApiJWTmiddleware = jest.fn(
|
||||
() => (req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
() =>
|
||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
||||
_next();
|
||||
}
|
||||
);
|
||||
|
||||
jest.mock('@verdaccio/auth', () => ({
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @verdaccio/auth
|
||||
|
||||
## 6.0.0-6-next.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/loaders@6.0.0-6-next.4
|
||||
|
||||
## 6.0.0-6-next.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/auth",
|
||||
"version": "6.0.0-6-next.8",
|
||||
"version": "6.0.0-6-next.9",
|
||||
"description": "logger",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -40,10 +40,10 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"verdaccio-htpasswd": "workspace:11.0.0-alpha.6",
|
||||
"debug": "^4.1.1",
|
||||
"express": "4.17.1",
|
||||
@@ -51,7 +51,7 @@
|
||||
"lodash": "4.17.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7"
|
||||
},
|
||||
"funding": {
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @verdaccio/cli
|
||||
|
||||
## 6.0.0-6-next.17
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 55ee3fdd: [Fastify] Add ping endpoint
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [55ee3fdd]
|
||||
- @verdaccio/fastify-migration@6.0.0-6-next.10
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/node-api@6.0.0-6-next.17
|
||||
|
||||
## 6.0.0-6-next.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/cli",
|
||||
"version": "6.0.0-6-next.16",
|
||||
"version": "6.0.0-6-next.17",
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
@@ -40,19 +40,23 @@
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
"watch": "pnpm build:js --F --watch",
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
"build": "pnpm run build:js && pnpm run build:types",
|
||||
"start": "ts-node src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.17",
|
||||
"@verdaccio/fastify-migration": "workspace:6.0.0-6-next.10",
|
||||
"commander": "6.2.0",
|
||||
"clipanion": "3.0.0-rc.11",
|
||||
"envinfo": "7.4.0",
|
||||
"kleur": "3.0.3",
|
||||
"semver": "7.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "9.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/verdaccio"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Command, Option } from 'clipanion';
|
||||
import { findConfigFile, parseConfigFile } from '@verdaccio/config';
|
||||
import { setup, logger } from '@verdaccio/logger';
|
||||
import server from '@verdaccio/fastify-migration';
|
||||
import { ConfigRuntime } from '@verdaccio/types';
|
||||
|
||||
export const DEFAULT_PROCESS_NAME: string = 'verdaccio';
|
||||
|
||||
@@ -19,17 +21,29 @@ export class NewServer extends Command {
|
||||
description: 'use this configuration file (default: ./config.yaml)',
|
||||
});
|
||||
|
||||
private initLogger(logConfig: ConfigRuntime) {
|
||||
try {
|
||||
if (logConfig.logs) {
|
||||
process.emitWarning('config.logs is deprecated, rename configuration to "config.log"');
|
||||
}
|
||||
// FUTURE: remove fallback when is ready
|
||||
setup(logConfig.log || logConfig.logs);
|
||||
} catch {
|
||||
throw new Error('error on init logger');
|
||||
}
|
||||
}
|
||||
|
||||
public async execute() {
|
||||
try {
|
||||
const configPathLocation = findConfigFile(this.config as string);
|
||||
const configParsed = parseConfigFile(configPathLocation);
|
||||
const { web } = configParsed;
|
||||
this.initLogger(configParsed);
|
||||
|
||||
process.title = web?.title || DEFAULT_PROCESS_NAME;
|
||||
// const { version, name } = require('../../package.json');
|
||||
const ser = await server();
|
||||
await ser.listen(4000);
|
||||
console.log('fastify running on port 4000');
|
||||
const ser = await server({ logger });
|
||||
await ser.listen(4873);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @verdaccio/config
|
||||
|
||||
## 6.0.0-6-next.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
|
||||
## 6.0.0-6-next.6
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/config",
|
||||
"version": "6.0.0-6-next.6",
|
||||
"version": "6.0.0-6-next.7",
|
||||
"description": "logger",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"debug": "^4.2.0",
|
||||
"js-yaml": "3.14.0",
|
||||
"lodash": "^4.17.20",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import Path from 'path';
|
||||
import _ from 'lodash';
|
||||
import buildDebug from 'debug';
|
||||
|
||||
@@ -27,28 +26,34 @@ const debug = buildDebug('verdaccio:config');
|
||||
* Find and get the first config file that match.
|
||||
* @return {String} the config file path
|
||||
*/
|
||||
function findConfigFile(configPath: string | undefined): string {
|
||||
function findConfigFile(configPath?: string): string {
|
||||
// console.log(process.env);
|
||||
if (typeof configPath !== 'undefined') {
|
||||
return Path.resolve(configPath);
|
||||
return path.resolve(configPath);
|
||||
}
|
||||
|
||||
const configPaths: SetupDirectory[] = getConfigPaths();
|
||||
|
||||
debug('%o posible locations found', configPaths.length);
|
||||
if (_.isEmpty(configPaths)) {
|
||||
// this should never happens
|
||||
throw new Error('no configuration files can be processed');
|
||||
}
|
||||
|
||||
const primaryConf: any = _.find(configPaths, (configLocation: any) =>
|
||||
// find the first location that already exist
|
||||
const primaryConf: SetupDirectory | void = _.find(configPaths, (configLocation: SetupDirectory) =>
|
||||
fileExists(configLocation.path)
|
||||
);
|
||||
if (_.isNil(primaryConf) === false) {
|
||||
|
||||
if (typeof primaryConf !== 'undefined') {
|
||||
debug('previous location exist already %s', primaryConf?.path);
|
||||
return primaryConf.path;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return createConfigFile(_.head(configPaths)).path;
|
||||
}
|
||||
|
||||
function createConfigFile(configLocation: any): SetupDirectory {
|
||||
function createConfigFile(configLocation: SetupDirectory): SetupDirectory {
|
||||
createConfigFolder(configLocation);
|
||||
|
||||
const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig());
|
||||
@@ -60,13 +65,18 @@ function createConfigFile(configLocation: any): SetupDirectory {
|
||||
|
||||
export function readDefaultConfig(): Buffer {
|
||||
const pathDefaultConf: string = path.resolve(__dirname, 'conf/default.yaml');
|
||||
|
||||
try {
|
||||
debug('default configuration file %s', pathDefaultConf);
|
||||
fs.accessSync(pathDefaultConf, fs.constants.R_OK);
|
||||
} catch {
|
||||
throw new TypeError('configuration file does not have enough permissions for reading');
|
||||
}
|
||||
// @ts-ignore
|
||||
return fs.readFileSync(pathDefaultConf, CHARACTER_ENCODING.UTF8);
|
||||
}
|
||||
|
||||
function createConfigFolder(configLocation): void {
|
||||
fs.mkdirSync(Path.dirname(configLocation.path), { recursive: true });
|
||||
fs.mkdirSync(path.dirname(configLocation.path), { recursive: true });
|
||||
debug(`Creating default config file in %o`, configLocation?.path);
|
||||
}
|
||||
|
||||
@@ -78,64 +88,89 @@ function updateStorageLinks(configLocation, defaultConfig): string {
|
||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data
|
||||
// files should be stored, If $XDG_DATA_HOME is either not set or empty, a default
|
||||
// equal to $HOME/.local/share should be used.
|
||||
// $FlowFixMe
|
||||
let dataDir =
|
||||
process.env.XDG_DATA_HOME || Path.join(process.env.HOME as string, '.local', 'share');
|
||||
process.env.XDG_DATA_HOME || path.join(process.env.HOME as string, '.local', 'share');
|
||||
if (folderExists(dataDir)) {
|
||||
dataDir = Path.resolve(Path.join(dataDir, pkgJSON.name, 'storage'));
|
||||
debug(`previous storage located`);
|
||||
debug(`update storage links to %s`, dataDir);
|
||||
dataDir = path.resolve(path.join(dataDir, pkgJSON.name, 'storage'));
|
||||
return defaultConfig.replace(/^storage: .\/storage$/m, `storage: ${dataDir}`);
|
||||
}
|
||||
debug(`could not find a previous storage location, skip override`);
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of configuration locations by platform.
|
||||
* @returns
|
||||
*/
|
||||
function getConfigPaths(): SetupDirectory[] {
|
||||
const listPaths: SetupDirectory[] = [
|
||||
const listPaths: (SetupDirectory | void)[] = [
|
||||
getXDGDirectory(),
|
||||
getWindowsDirectory(),
|
||||
getRelativeDefaultDirectory(),
|
||||
getOldDirectory(),
|
||||
].reduce(function (acc, currentValue: any): SetupDirectory[] {
|
||||
if (_.isUndefined(currentValue) === false) {
|
||||
];
|
||||
|
||||
return listPaths.reduce(function (acc, currentValue: SetupDirectory | void): SetupDirectory[] {
|
||||
if (typeof currentValue !== 'undefined') {
|
||||
debug('directory detected path %s for type %s', currentValue?.path, currentValue.type);
|
||||
acc.push(currentValue);
|
||||
}
|
||||
return acc;
|
||||
}, [] as SetupDirectory[]);
|
||||
|
||||
return listPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get XDG_CONFIG_HOME or HOME location (usually unix)
|
||||
* @returns
|
||||
*/
|
||||
const getXDGDirectory = (): SetupDirectory | void => {
|
||||
const XDGConfig = getXDGHome() || (process.env.HOME && Path.join(process.env.HOME, '.config'));
|
||||
|
||||
if (XDGConfig && folderExists(XDGConfig)) {
|
||||
const xDGConfigPath =
|
||||
process.env.XDG_CONFIG_HOME || (process.env.HOME && path.join(process.env.HOME, '.config'));
|
||||
if (xDGConfigPath && folderExists(xDGConfigPath)) {
|
||||
debug('XDGConfig folder path %s', xDGConfigPath);
|
||||
return {
|
||||
path: Path.join(XDGConfig, pkgJSON.name, CONFIG_FILE),
|
||||
path: path.join(xDGConfigPath, pkgJSON.name, CONFIG_FILE),
|
||||
type: XDG,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const getXDGHome = (): string | void => process.env.XDG_CONFIG_HOME;
|
||||
|
||||
/**
|
||||
* Detect windows location, APPDATA
|
||||
* usually something like C:\User\<Build User>\AppData\Local
|
||||
* @returns
|
||||
*/
|
||||
const getWindowsDirectory = (): SetupDirectory | void => {
|
||||
if (process.platform === WIN32 && process.env.APPDATA && folderExists(process.env.APPDATA)) {
|
||||
debug('is windows appdata: %s', process.env.APPDATA);
|
||||
return {
|
||||
path: Path.resolve(Path.join(process.env.APPDATA, pkgJSON.name, CONFIG_FILE)),
|
||||
path: path.resolve(path.join(process.env.APPDATA, pkgJSON.name, CONFIG_FILE)),
|
||||
type: WIN,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return relative directory, this is the default.
|
||||
* It will cretate config in your {currentLocation/verdaccio/config.yaml}
|
||||
* @returns
|
||||
*/
|
||||
const getRelativeDefaultDirectory = (): SetupDirectory => {
|
||||
return {
|
||||
path: Path.resolve(Path.join('.', pkgJSON.name, CONFIG_FILE)),
|
||||
path: path.resolve(path.join('.', pkgJSON.name, CONFIG_FILE)),
|
||||
type: 'def',
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This should never happens, consider it DEPRECATED
|
||||
* @returns
|
||||
*/
|
||||
const getOldDirectory = (): SetupDirectory => {
|
||||
return {
|
||||
path: Path.resolve(Path.join('.', CONFIG_FILE)),
|
||||
path: path.resolve(path.join('.', CONFIG_FILE)),
|
||||
type: 'old',
|
||||
};
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ class Config implements AppConfig {
|
||||
/**
|
||||
* Store or create whether receive a secret key
|
||||
*/
|
||||
public checkSecretKey(secret: string): string {
|
||||
public checkSecretKey(secret?: string): string {
|
||||
debug('check secret key');
|
||||
if (_.isString(secret) && _.isEmpty(secret) === false) {
|
||||
this.secret = secret;
|
||||
|
||||
105
packages/config/test/config.path.spec.ts
Normal file
105
packages/config/test/config.path.spec.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import os from 'os';
|
||||
import { findConfigFile } from '../src/config-path';
|
||||
|
||||
const mockmkDir = jest.fn();
|
||||
const mockaccessSync = jest.fn();
|
||||
const mockwriteFile = jest.fn();
|
||||
|
||||
jest.mock('fs', () => {
|
||||
const fsOri = jest.requireActual('fs');
|
||||
return {
|
||||
...fsOri,
|
||||
statSync: (path) => ({
|
||||
isDirectory: () => {
|
||||
if (path.match(/fail/)) {
|
||||
throw Error('file does not exist');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
accessSync: (a) => mockaccessSync(a),
|
||||
mkdirSync: (a) => mockmkDir(a),
|
||||
writeFileSync: (a) => mockwriteFile(a),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
describe('config-path', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('findConfigFile', () => {
|
||||
if (os.platform() !== 'win32') {
|
||||
describe('using defiled location from arguments', () => {
|
||||
test('with custom location', () => {
|
||||
expect(findConfigFile('/home/user/custom/location/config.yaml')).toEqual(
|
||||
'/home/user/custom/location/config.yaml'
|
||||
);
|
||||
expect(mockwriteFile).not.toHaveBeenCalled();
|
||||
expect(mockmkDir).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('whith env variables', () => {
|
||||
test('with XDG_CONFIG_HOME if directory exist but config file is missing', () => {
|
||||
process.env.XDG_CONFIG_HOME = '/home/user';
|
||||
expect(findConfigFile()).toEqual('/home/user/verdaccio/config.yaml');
|
||||
expect(mockwriteFile).toHaveBeenCalledWith('/home/user/verdaccio/config.yaml');
|
||||
expect(mockmkDir).toHaveBeenCalledWith('/home/user/verdaccio');
|
||||
});
|
||||
|
||||
test('with HOME if directory exist but config file is missing', () => {
|
||||
delete process.env.XDG_CONFIG_HOME;
|
||||
process.env.HOME = '/home/user';
|
||||
expect(findConfigFile()).toEqual('/home/user/.config/verdaccio/config.yaml');
|
||||
expect(mockwriteFile).toHaveBeenCalledWith('/home/user/.config/verdaccio/config.yaml');
|
||||
expect(mockmkDir).toHaveBeenCalledWith('/home/user/.config/verdaccio');
|
||||
});
|
||||
|
||||
describe('error handling', () => {
|
||||
test('XDG_CONFIG_HOME is not directory fallback to default', () => {
|
||||
process.env.XDG_CONFIG_HOME = '/home/user/fail';
|
||||
mockaccessSync.mockImplementation(() => {});
|
||||
mockwriteFile.mockImplementation(() => {});
|
||||
expect(findConfigFile()).toMatch('packages/config/verdaccio/config.yaml');
|
||||
});
|
||||
|
||||
test('no permissions on read default config file', () => {
|
||||
process.env.XDG_CONFIG_HOME = '/home/user';
|
||||
mockaccessSync.mockImplementation(() => {
|
||||
throw new Error('error on write file');
|
||||
});
|
||||
|
||||
expect(function () {
|
||||
findConfigFile();
|
||||
}).toThrow(/configuration file does not have enough permissions for reading/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with no env variables', () => {
|
||||
test('with relative location', () => {
|
||||
mockaccessSync.mockImplementation(() => {});
|
||||
delete process.env.XDG_CONFIG_HOME;
|
||||
delete process.env.HOME;
|
||||
process.env.APPDATA = '/app/data/';
|
||||
expect(findConfigFile()).toMatch('packages/config/verdaccio/config.yaml');
|
||||
expect(mockwriteFile).toHaveBeenCalled();
|
||||
expect(mockmkDir).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
test('with windows as directory exist but config file is missing', () => {
|
||||
delete process.env.XDG_CONFIG_HOME;
|
||||
delete process.env.HOME;
|
||||
process.env.APPDATA = '/app/data/';
|
||||
expect(findConfigFile()).toEqual('D:\\app\\data\\verdaccio\\config.yaml');
|
||||
expect(mockwriteFile).toHaveBeenCalledWith('D:\\app\\data\\verdaccio\\config.yaml');
|
||||
expect(mockmkDir).toHaveBeenCalledWith('D:\\app\\data\\verdaccio');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
parseConfigFile,
|
||||
ROLES,
|
||||
WEB_TITLE,
|
||||
getMatchedPackagesSpec,
|
||||
} from '../src';
|
||||
import { parseConfigurationFile } from './utils';
|
||||
|
||||
@@ -23,56 +24,56 @@ const checkDefaultUplink = (config) => {
|
||||
expect(config.uplinks[DEFAULT_UPLINK].url).toMatch(DEFAULT_REGISTRY);
|
||||
};
|
||||
|
||||
const checkDefaultConfPackages = (config) => {
|
||||
// auth
|
||||
expect(_.isObject(config.auth)).toBeTruthy();
|
||||
expect(_.isObject(config.auth.htpasswd)).toBeTruthy();
|
||||
expect(config.auth.htpasswd.file).toMatch(/htpasswd/);
|
||||
|
||||
// web
|
||||
expect(_.isObject(config.web)).toBeTruthy();
|
||||
expect(config.web.title).toBe(WEB_TITLE);
|
||||
expect(config.web.enable).toBeUndefined();
|
||||
|
||||
// packages
|
||||
expect(_.isObject(config.packages)).toBeTruthy();
|
||||
expect(Object.keys(config.packages).join('|')).toBe('@*/*|**');
|
||||
expect(config.packages['@*/*'].access).toBeDefined();
|
||||
expect(config.packages['@*/*'].access).toContainEqual(ROLES.$ALL);
|
||||
expect(config.packages['@*/*'].publish).toBeDefined();
|
||||
expect(config.packages['@*/*'].publish).toContainEqual(ROLES.$AUTH);
|
||||
expect(config.packages['@*/*'].proxy).toBeDefined();
|
||||
expect(config.packages['@*/*'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||
expect(config.packages['**'].access).toBeDefined();
|
||||
expect(config.packages['**'].access).toContainEqual(ROLES.$ALL);
|
||||
expect(config.packages['**'].publish).toBeDefined();
|
||||
expect(config.packages['**'].publish).toContainEqual(ROLES.$AUTH);
|
||||
expect(config.packages['**'].proxy).toBeDefined();
|
||||
expect(config.packages['**'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||
// uplinks
|
||||
expect(config.uplinks[DEFAULT_UPLINK]).toBeDefined();
|
||||
expect(config.uplinks[DEFAULT_UPLINK].url).toEqual(DEFAULT_REGISTRY);
|
||||
// audit
|
||||
expect(config.middlewares).toBeDefined();
|
||||
expect(config.middlewares.audit).toBeDefined();
|
||||
expect(config.middlewares.audit.enabled).toBeTruthy();
|
||||
// logs
|
||||
expect(config.logs).toBeDefined();
|
||||
expect(config.logs.type).toEqual('stdout');
|
||||
expect(config.logs.format).toEqual('pretty');
|
||||
expect(config.logs.level).toEqual('http');
|
||||
// must not be enabled by default
|
||||
expect(config.notify).toBeUndefined();
|
||||
expect(config.store).toBeUndefined();
|
||||
expect(config.publish).toBeUndefined();
|
||||
expect(config.url_prefix).toBeUndefined();
|
||||
expect(config.url_prefix).toBeUndefined();
|
||||
|
||||
expect(config.experiments).toBeUndefined();
|
||||
expect(config.security).toEqual(defaultSecurity);
|
||||
};
|
||||
|
||||
describe('check basic content parsed file', () => {
|
||||
const checkDefaultConfPackages = (config) => {
|
||||
// auth
|
||||
expect(_.isObject(config.auth)).toBeTruthy();
|
||||
expect(_.isObject(config.auth.htpasswd)).toBeTruthy();
|
||||
expect(config.auth.htpasswd.file).toMatch(/htpasswd/);
|
||||
|
||||
// web
|
||||
expect(_.isObject(config.web)).toBeTruthy();
|
||||
expect(config.web.title).toBe(WEB_TITLE);
|
||||
expect(config.web.enable).toBeUndefined();
|
||||
|
||||
// packages
|
||||
expect(_.isObject(config.packages)).toBeTruthy();
|
||||
expect(Object.keys(config.packages).join('|')).toBe('@*/*|**');
|
||||
expect(config.packages['@*/*'].access).toBeDefined();
|
||||
expect(config.packages['@*/*'].access).toContainEqual(ROLES.$ALL);
|
||||
expect(config.packages['@*/*'].publish).toBeDefined();
|
||||
expect(config.packages['@*/*'].publish).toContainEqual(ROLES.$AUTH);
|
||||
expect(config.packages['@*/*'].proxy).toBeDefined();
|
||||
expect(config.packages['@*/*'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||
expect(config.packages['**'].access).toBeDefined();
|
||||
expect(config.packages['**'].access).toContainEqual(ROLES.$ALL);
|
||||
expect(config.packages['**'].publish).toBeDefined();
|
||||
expect(config.packages['**'].publish).toContainEqual(ROLES.$AUTH);
|
||||
expect(config.packages['**'].proxy).toBeDefined();
|
||||
expect(config.packages['**'].proxy).toContainEqual(DEFAULT_UPLINK);
|
||||
// uplinks
|
||||
expect(config.uplinks[DEFAULT_UPLINK]).toBeDefined();
|
||||
expect(config.uplinks[DEFAULT_UPLINK].url).toEqual(DEFAULT_REGISTRY);
|
||||
// audit
|
||||
expect(config.middlewares).toBeDefined();
|
||||
expect(config.middlewares.audit).toBeDefined();
|
||||
expect(config.middlewares.audit.enabled).toBeTruthy();
|
||||
// logs
|
||||
expect(config.logs).toBeDefined();
|
||||
expect(config.logs.type).toEqual('stdout');
|
||||
expect(config.logs.format).toEqual('pretty');
|
||||
expect(config.logs.level).toEqual('http');
|
||||
// must not be enabled by default
|
||||
expect(config.notify).toBeUndefined();
|
||||
expect(config.store).toBeUndefined();
|
||||
expect(config.publish).toBeUndefined();
|
||||
expect(config.url_prefix).toBeUndefined();
|
||||
expect(config.url_prefix).toBeUndefined();
|
||||
|
||||
expect(config.experiments).toBeUndefined();
|
||||
expect(config.security).toEqual(defaultSecurity);
|
||||
};
|
||||
|
||||
test('parse default.yaml', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||
checkDefaultUplink(config);
|
||||
@@ -81,6 +82,57 @@ describe('check basic content parsed file', () => {
|
||||
checkDefaultConfPackages(config);
|
||||
});
|
||||
|
||||
test('parse docker.yaml', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('docker')));
|
||||
checkDefaultUplink(config);
|
||||
expect(config.storage).toBe('/verdaccio/storage/data');
|
||||
expect(config.auth.htpasswd.file).toBe('/verdaccio/storage/htpasswd');
|
||||
checkDefaultConfPackages(config);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkSecretKey', () => {
|
||||
test('with default.yaml and pre selected secret', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||
expect(config.checkSecretKey('12345')).toEqual('12345');
|
||||
});
|
||||
|
||||
test('with default.yaml and void secret', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||
expect(typeof config.checkSecretKey() === 'string').toBeTruthy();
|
||||
});
|
||||
|
||||
test('with default.yaml and emtpy string secret', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('default')));
|
||||
expect(typeof config.checkSecretKey('') === 'string').toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMatchedPackagesSpec', () => {
|
||||
test('should match with react as defined in config file', () => {
|
||||
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
|
||||
const config = new Config(configParsed);
|
||||
expect(config.getMatchedPackagesSpec('react')).toEqual({
|
||||
access: ['admin'],
|
||||
proxy: ['facebook'],
|
||||
publish: ['admin'],
|
||||
unpublish: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('should not match with react as defined in config file', () => {
|
||||
const configParsed = parseConfigFile(parseConfigurationFile('config-getMatchedPackagesSpec'));
|
||||
const config = new Config(configParsed);
|
||||
expect(config.getMatchedPackagesSpec('somePackage')).toEqual({
|
||||
access: [ROLES.$ALL],
|
||||
proxy: ['npmjs'],
|
||||
publish: [ROLES.$AUTH],
|
||||
unpublish: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('VERDACCIO_STORAGE_PATH', () => {
|
||||
test('should set storage to value set in VERDACCIO_STORAGE_PATH environment variable', () => {
|
||||
const storageLocation = '/tmp/verdaccio';
|
||||
process.env.VERDACCIO_STORAGE_PATH = storageLocation;
|
||||
@@ -106,12 +158,4 @@ describe('check basic content parsed file', () => {
|
||||
expect(config.storage).toBe(storageLocation);
|
||||
delete process.env.VERDACCIO_STORAGE_PATH;
|
||||
});
|
||||
|
||||
test('parse docker.yaml', () => {
|
||||
const config = new Config(parseConfigFile(resolveConf('docker')));
|
||||
checkDefaultUplink(config);
|
||||
expect(config.storage).toBe('/verdaccio/storage/data');
|
||||
expect(config.auth.htpasswd.file).toBe('/verdaccio/storage/htpasswd');
|
||||
checkDefaultConfPackages(config);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -88,26 +88,17 @@ describe('Package access utilities', () => {
|
||||
() => {
|
||||
const { packages } = parseConfigFile(parseConfigurationFile('deprecated-pkgs-basic'));
|
||||
const access = normalisePackageAccess(packages);
|
||||
|
||||
expect(access).toBeDefined();
|
||||
|
||||
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
||||
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
||||
const react = access['react-*'];
|
||||
|
||||
expect(react).toBeDefined();
|
||||
expect(react.access).toBeDefined();
|
||||
|
||||
// Intended checks, Typescript should catch this, we test the runtime part
|
||||
// @ts-ignore
|
||||
expect(react.access).toEqual([]);
|
||||
// @ts-ignore
|
||||
expect(react.publish[0]).toBe('admin');
|
||||
expect(react.proxy).toBeDefined();
|
||||
// @ts-ignore
|
||||
expect(react.proxy).toEqual([]);
|
||||
expect(react.storage).toBeDefined();
|
||||
|
||||
expect(react.storage).toBe('react-storage');
|
||||
expect(scoped).toBeDefined();
|
||||
expect(scoped.storage).not.toBeDefined();
|
||||
@@ -126,7 +117,6 @@ describe('Package access utilities', () => {
|
||||
|
||||
const scoped = access[`${PACKAGE_ACCESS.SCOPE}`];
|
||||
expect(scoped).toBeUndefined();
|
||||
|
||||
// ** should be added by default **
|
||||
const all = access[`${PACKAGE_ACCESS.ALL}`];
|
||||
expect(all).toBeDefined();
|
||||
@@ -141,23 +131,23 @@ describe('Package access utilities', () => {
|
||||
describe('getMatchedPackagesSpec', () => {
|
||||
test('should test basic config', () => {
|
||||
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-custom'));
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('vue', packages).proxy).toMatch('npmjs');
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('@scope/vue', packages).proxy).toMatch('npmjs');
|
||||
});
|
||||
|
||||
test('should test no ** wildcard on config', () => {
|
||||
const { packages } = parseConfigFile(parseConfigurationFile('pkgs-nosuper-wildcard-custom'));
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('react', packages).proxy).toMatch('facebook');
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('angular', packages).proxy).toMatch('google');
|
||||
// @ts-ignore
|
||||
// @ts-expect-error
|
||||
expect(getMatchedPackagesSpec('@fake/angular', packages).proxy).toMatch('npmjs');
|
||||
expect(getMatchedPackagesSpec('vue', packages)).toBeUndefined();
|
||||
expect(getMatchedPackagesSpec('@scope/vue', packages)).toBeUndefined();
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
packages:
|
||||
'react':
|
||||
access: admin
|
||||
publish: admin
|
||||
proxy: facebook
|
||||
'angular':
|
||||
access: admin
|
||||
publish: admin
|
||||
proxy: google
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: npmjs
|
||||
@@ -31,7 +31,7 @@ describe('HTPasswd', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = new HTPasswd(getDefaultConfig(), (stuff as unknown) as VerdaccioConfigApp);
|
||||
wrapper = new HTPasswd(getDefaultConfig(), stuff as unknown as VerdaccioConfigApp);
|
||||
jest.resetModules();
|
||||
|
||||
crypto.randomBytes = jest.fn(() => {
|
||||
|
||||
6
packages/core/server/CHANGELOG.md
Normal file
6
packages/core/server/CHANGELOG.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# @verdaccio/fastify-migration
|
||||
|
||||
## 6.0.0-6-next.10
|
||||
### Minor Changes
|
||||
|
||||
- 55ee3fdd: [Fastify] Add ping endpoint
|
||||
39
packages/core/server/debug/fastify-conf.yaml
Normal file
39
packages/core/server/debug/fastify-conf.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
storage: ./storage
|
||||
plugins: ./plugins
|
||||
web:
|
||||
title: Verdaccio
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
|
||||
middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
log: { type: stdout, format: pretty, level: http }
|
||||
flags:
|
||||
token: false
|
||||
search: false
|
||||
|
||||
i18n:
|
||||
web: en-US
|
||||
30
packages/core/server/debug/index.ts
Normal file
30
packages/core/server/debug/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import path from 'path';
|
||||
import buildDebug from 'debug';
|
||||
import { parseConfigFile } from '@verdaccio/config';
|
||||
import { setup, logger } from '@verdaccio/logger';
|
||||
import server from '../src/index';
|
||||
|
||||
const debug = buildDebug('verdaccio:fastify:debug');
|
||||
|
||||
/**
|
||||
* This file is intended for fast development and debug, it should
|
||||
* be removed eventually and the app start from @verdaccio/cli package.
|
||||
*/
|
||||
(async () => {
|
||||
try {
|
||||
const configFile = path.join(__dirname, './fastify-conf.yaml');
|
||||
debug('configFile %s', configFile);
|
||||
const configParsed = parseConfigFile(configFile);
|
||||
setup(configParsed.log);
|
||||
logger.info(`config location ${configFile}`);
|
||||
debug('configParsed %s', configParsed);
|
||||
process.title = 'fastify-verdaccio';
|
||||
const ser = await server({ logger });
|
||||
await ser.listen(4873);
|
||||
logger.info('fastify running on port 4873');
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/fastify-migration",
|
||||
"version": "6.0.0-6-next.9",
|
||||
"version": "6.0.0-6-next.10",
|
||||
"description": "Fastify server migration package",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -34,10 +34,15 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastify": "3.14.2"
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"fastify": "3.15.1",
|
||||
"fastify-plugin": "3.0.0",
|
||||
"debug": "4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7"
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"ts-node": "9.1.1"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
@@ -45,7 +50,8 @@
|
||||
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
||||
"watch": "pnpm build:js -- --watch",
|
||||
"build": "pnpm run build:js && pnpm run build:types"
|
||||
"build": "pnpm run build:js && pnpm run build:types",
|
||||
"start": "ts-node debug/index.ts"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
10
packages/core/server/src/endpoints/ping.ts
Normal file
10
packages/core/server/src/endpoints/ping.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { logger } from '@verdaccio/logger';
|
||||
|
||||
async function pingRoute(fastify) {
|
||||
fastify.get('/-/ping', async () => {
|
||||
logger.http('ping endpoint');
|
||||
return {};
|
||||
});
|
||||
}
|
||||
|
||||
export default pingRoute;
|
||||
@@ -1,12 +1,14 @@
|
||||
import fastify from 'fastify';
|
||||
import buildDebug from 'debug';
|
||||
|
||||
async function startServer() {
|
||||
const app = fastify();
|
||||
import ping from './endpoints/ping';
|
||||
|
||||
app.get('/', async (request, reply) => {
|
||||
return { hello: 'world' };
|
||||
});
|
||||
const debug = buildDebug('verdaccio:fastify');
|
||||
|
||||
async function startServer({ logger }) {
|
||||
debug('start server');
|
||||
const app = fastify({ logger });
|
||||
app.register(ping);
|
||||
return app;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 11.0.0-6-next.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
|
||||
## 11.0.0-6-next.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/tarball",
|
||||
"version": "11.0.0-6-next.5",
|
||||
"version": "11.0.0-6-next.6",
|
||||
"description": "tarball utilities resolver",
|
||||
"keywords": [
|
||||
"private",
|
||||
@@ -38,12 +38,12 @@
|
||||
"lodash": "^4.17.21",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/url": "workspace:11.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4"
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"express": "^4.17.1",
|
||||
"node-mocks-http": "^1.10.1"
|
||||
"express": "4.17.1",
|
||||
"node-mocks-http": "1.10.1"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf ./build",
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
"request": "2.87.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"nock": "^13.0.4"
|
||||
},
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7"
|
||||
},
|
||||
"homepage": "https://verdaccio.org",
|
||||
|
||||
@@ -59,86 +59,84 @@ export function loadPlugin<T extends IPlugin<T>>(
|
||||
sanityCheck: any,
|
||||
prefix: string = 'verdaccio'
|
||||
): any[] {
|
||||
return Object.keys(pluginConfigs).map(
|
||||
(pluginId: string): IPlugin<T> => {
|
||||
let plugin;
|
||||
return Object.keys(pluginConfigs).map((pluginId: string): IPlugin<T> => {
|
||||
let plugin;
|
||||
|
||||
const localPlugin = Path.resolve(__dirname + '/../plugins', pluginId);
|
||||
// try local plugins first
|
||||
plugin = tryLoad(localPlugin);
|
||||
const localPlugin = Path.resolve(__dirname + '/../plugins', pluginId);
|
||||
// try local plugins first
|
||||
plugin = tryLoad(localPlugin);
|
||||
|
||||
// try the external plugin directory
|
||||
if (plugin === null && config.plugins) {
|
||||
const pluginDir = config.plugins;
|
||||
const externalFilePlugin = Path.resolve(pluginDir, pluginId);
|
||||
plugin = tryLoad(externalFilePlugin);
|
||||
|
||||
// npm package
|
||||
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
|
||||
plugin = tryLoad(Path.resolve(pluginDir, `${prefix}-${pluginId}`));
|
||||
// compatibility for old sinopia plugins
|
||||
if (!plugin) {
|
||||
plugin = tryLoad(Path.resolve(pluginDir, `sinopia-${pluginId}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
// try the external plugin directory
|
||||
if (plugin === null && config.plugins) {
|
||||
const pluginDir = config.plugins;
|
||||
const externalFilePlugin = Path.resolve(pluginDir, pluginId);
|
||||
plugin = tryLoad(externalFilePlugin);
|
||||
|
||||
// npm package
|
||||
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
|
||||
plugin = tryLoad(`${prefix}-${pluginId}`);
|
||||
plugin = tryLoad(Path.resolve(pluginDir, `${prefix}-${pluginId}`));
|
||||
// compatibility for old sinopia plugins
|
||||
if (!plugin) {
|
||||
plugin = tryLoad(`sinopia-${pluginId}`);
|
||||
plugin = tryLoad(Path.resolve(pluginDir, `sinopia-${pluginId}`));
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin === null) {
|
||||
plugin = tryLoad(pluginId);
|
||||
}
|
||||
|
||||
// relative to config path
|
||||
if (plugin === null && pluginId.match(/^\.\.?($|\/)/)) {
|
||||
plugin = tryLoad(Path.resolve(Path.dirname(config.config_path), pluginId));
|
||||
}
|
||||
|
||||
if (plugin === null) {
|
||||
logger.error(
|
||||
{ content: pluginId, prefix },
|
||||
'plugin not found. try npm install @{prefix}-@{content}'
|
||||
);
|
||||
throw Error(`
|
||||
${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`);
|
||||
}
|
||||
|
||||
if (!isValid(plugin)) {
|
||||
logger.error(
|
||||
{ content: pluginId },
|
||||
'@{prefix}-@{content} plugin does not have the right code structure'
|
||||
);
|
||||
throw Error(`"${pluginId}" plugin does not have the right code structure`);
|
||||
}
|
||||
|
||||
/* eslint new-cap:off */
|
||||
try {
|
||||
plugin = isES6(plugin)
|
||||
? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params)
|
||||
: plugin(pluginConfigs[pluginId], params);
|
||||
} catch (error) {
|
||||
plugin = null;
|
||||
logger.error({ error, pluginId }, 'error loading a plugin @{pluginId}: @{error}');
|
||||
}
|
||||
/* eslint new-cap:off */
|
||||
|
||||
if (plugin === null || !sanityCheck(plugin)) {
|
||||
logger.error(
|
||||
{ content: pluginId, prefix },
|
||||
"@{prefix}-@{content} doesn't look like a valid plugin"
|
||||
);
|
||||
throw Error(`sanity check has failed, "${pluginId}" is not a valid plugin`);
|
||||
}
|
||||
|
||||
debug('Plugin successfully loaded: %o-%o', pluginId, prefix);
|
||||
return plugin;
|
||||
}
|
||||
);
|
||||
|
||||
// npm package
|
||||
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
|
||||
plugin = tryLoad(`${prefix}-${pluginId}`);
|
||||
// compatibility for old sinopia plugins
|
||||
if (!plugin) {
|
||||
plugin = tryLoad(`sinopia-${pluginId}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin === null) {
|
||||
plugin = tryLoad(pluginId);
|
||||
}
|
||||
|
||||
// relative to config path
|
||||
if (plugin === null && pluginId.match(/^\.\.?($|\/)/)) {
|
||||
plugin = tryLoad(Path.resolve(Path.dirname(config.config_path), pluginId));
|
||||
}
|
||||
|
||||
if (plugin === null) {
|
||||
logger.error(
|
||||
{ content: pluginId, prefix },
|
||||
'plugin not found. try npm install @{prefix}-@{content}'
|
||||
);
|
||||
throw Error(`
|
||||
${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`);
|
||||
}
|
||||
|
||||
if (!isValid(plugin)) {
|
||||
logger.error(
|
||||
{ content: pluginId },
|
||||
'@{prefix}-@{content} plugin does not have the right code structure'
|
||||
);
|
||||
throw Error(`"${pluginId}" plugin does not have the right code structure`);
|
||||
}
|
||||
|
||||
/* eslint new-cap:off */
|
||||
try {
|
||||
plugin = isES6(plugin)
|
||||
? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params)
|
||||
: plugin(pluginConfigs[pluginId], params);
|
||||
} catch (error) {
|
||||
plugin = null;
|
||||
logger.error({ error, pluginId }, 'error loading a plugin @{pluginId}: @{error}');
|
||||
}
|
||||
/* eslint new-cap:off */
|
||||
|
||||
if (plugin === null || !sanityCheck(plugin)) {
|
||||
logger.error(
|
||||
{ content: pluginId, prefix },
|
||||
"@{prefix}-@{content} doesn't look like a valid plugin"
|
||||
);
|
||||
throw Error(`sanity check has failed, "${pluginId}" is not a valid plugin`);
|
||||
}
|
||||
|
||||
debug('Plugin successfully loaded: %o-%o', pluginId, prefix);
|
||||
return plugin;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @verdaccio/middleware
|
||||
|
||||
## 6.0.0-6-next.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/auth@6.0.0-6-next.9
|
||||
|
||||
## 6.0.0-6-next.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/middleware",
|
||||
"version": "6.0.0-6-next.8",
|
||||
"version": "6.0.0-6-next.9",
|
||||
"description": "loaders logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -39,10 +39,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.3.1",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"lodash": "4.17.15"
|
||||
},
|
||||
"funding": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @verdaccio/mock
|
||||
|
||||
## 6.0.0-6-next.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
|
||||
## 6.0.0-6-next.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/mock",
|
||||
"version": "6.0.0-6-next.6",
|
||||
"version": "6.0.0-6-next.7",
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
@@ -40,8 +40,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"debug": "^4.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"lodash": "^4.17.20",
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @verdaccio/node-api
|
||||
|
||||
## 6.0.0-6-next.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/server@6.0.0-6-next.16
|
||||
|
||||
## 6.0.0-6-next.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/node-api",
|
||||
"version": "6.0.0-6-next.16",
|
||||
"version": "6.0.0-6-next.17",
|
||||
"description": "node API",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -40,15 +40,15 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.15",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/server": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"core-js": "^3.6.5",
|
||||
"debug": "^4.2.0",
|
||||
"lodash": "^4.17.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"jest-mock-process": "^1.4.0",
|
||||
"selfsigned": "1.10.7",
|
||||
|
||||
@@ -51,7 +51,7 @@ class ActiveDirectoryPlugin implements IPluginAuth<ActiveDirectoryConfig> {
|
||||
connection.getGroupMembershipForUser(username, (err, groups: object[]): void => {
|
||||
if (err) {
|
||||
this.logger.warn(`AD - Active Directory group check failed with error: ${err}`);
|
||||
return cb(getInternalError((err as unknown) as string));
|
||||
return cb(getInternalError(err as unknown as string));
|
||||
}
|
||||
|
||||
const requestedGroups = Array.isArray(groupName) ? groupName : [groupName];
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('Active Directory Plugin', () => {
|
||||
const errorMessage = 'Unknown error retrieving groups';
|
||||
ActiveDirectory.prototype.authenticate = jest.fn((_1, _2, cb) => cb(null, true));
|
||||
ActiveDirectory.prototype.getGroupMembershipForUser = jest.fn((_, cb) =>
|
||||
cb((errorMessage as unknown) as object, null)
|
||||
cb(errorMessage as unknown as object, null)
|
||||
) as jest.Mock;
|
||||
|
||||
adPluginSingleGroup.authenticate('', '', (error, authUser) => {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## 11.0.0-6-next.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 6b1a28de: Fix the prefix used to delete from s3 when unpublishing packages
|
||||
|
||||
## 11.0.0-6-next.4
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio-aws-s3-storage",
|
||||
"version": "11.0.0-6-next.4",
|
||||
"version": "11.0.0-6-next.5",
|
||||
"description": "AWS S3 storage implementation for Verdaccio",
|
||||
"keywords": [
|
||||
"private",
|
||||
|
||||
@@ -29,14 +29,8 @@ export default class S3PackageManager implements ILocalPackageManager {
|
||||
this.config = config;
|
||||
this.packageName = packageName;
|
||||
this.logger = logger;
|
||||
const {
|
||||
endpoint,
|
||||
region,
|
||||
s3ForcePathStyle,
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
sessionToken,
|
||||
} = config;
|
||||
const { endpoint, region, s3ForcePathStyle, accessKeyId, secretAccessKey, sessionToken } =
|
||||
config;
|
||||
|
||||
this.s3 = new S3({
|
||||
endpoint,
|
||||
@@ -172,7 +166,7 @@ export default class S3PackageManager implements ILocalPackageManager {
|
||||
this.s3,
|
||||
{
|
||||
Bucket: this.config.bucket,
|
||||
Prefix: `${this.packagePath}`,
|
||||
Prefix: addTrailingSlash(this.packagePath),
|
||||
},
|
||||
function (err) {
|
||||
if (err && is404Error(err as VerdaccioError)) {
|
||||
|
||||
@@ -79,7 +79,7 @@ describe.skip('S3 package manager', () => {
|
||||
|
||||
describe('savePackage() group', () => {
|
||||
test('savePackage()', (done) => {
|
||||
const data = ('{data:5}' as unknown) as Package;
|
||||
const data = '{data:5}' as unknown as Package;
|
||||
const packageManager = new S3PackageManager(config, 'first-package', logger);
|
||||
|
||||
packageManager.savePackage('pkg.1.0.0.tar.gz', data, (err) => {
|
||||
|
||||
@@ -231,7 +231,7 @@ describe('S3PackageManager with mocked s3', function () {
|
||||
expect(mockListObject).toHaveBeenCalledWith(
|
||||
{
|
||||
Bucket: 'test-bucket',
|
||||
Prefix: 'testKeyPrefix/@company/test-package',
|
||||
Prefix: 'testKeyPrefix/@company/test-package/',
|
||||
},
|
||||
expect.any(Function)
|
||||
);
|
||||
@@ -270,7 +270,7 @@ describe('S3PackageManager with mocked s3', function () {
|
||||
expect(mockListObject).toHaveBeenCalledWith(
|
||||
{
|
||||
Bucket: 'test-bucket',
|
||||
Prefix: 'testKeyPrefix/customFolder/@company/test-package',
|
||||
Prefix: 'testKeyPrefix/customFolder/@company/test-package/',
|
||||
},
|
||||
expect.any(Function)
|
||||
);
|
||||
|
||||
@@ -118,14 +118,12 @@ class GoogleCloudDatabase implements IPluginStorage<VerdaccioConfigGoogleStorage
|
||||
// "{\"secret\":\"181bc38698078f880564be1e4d7ec107ac8a3b344a924c6d86cea4a84a885ae0\"}"
|
||||
return entities.secret;
|
||||
})
|
||||
.catch(
|
||||
(err: Error): Promise<string> => {
|
||||
const error: VerdaccioError = getInternalError(err.message);
|
||||
.catch((err: Error): Promise<string> => {
|
||||
const error: VerdaccioError = getInternalError(err.message);
|
||||
|
||||
this.logger.warn({ error }, 'gcloud: [datastore getSecret] init error @{error}');
|
||||
return Promise.reject(getServiceUnavailable('[getSecret] permissions error'));
|
||||
}
|
||||
);
|
||||
this.logger.warn({ error }, 'gcloud: [datastore getSecret] init error @{error}');
|
||||
return Promise.reject(getServiceUnavailable('[getSecret] permissions error'));
|
||||
});
|
||||
}
|
||||
|
||||
public setSecret(secret: string): Promise<CommitResponse> {
|
||||
@@ -194,17 +192,15 @@ class GoogleCloudDatabase implements IPluginStorage<VerdaccioConfigGoogleStorage
|
||||
// };
|
||||
this.helper
|
||||
.getEntities(this.kind)
|
||||
.then(
|
||||
async (entities: any): Promise<void> => {
|
||||
for (const item of entities) {
|
||||
if (item.name === name) {
|
||||
await this._deleteItem(name, item);
|
||||
// deletedItems.push(deletedItem);
|
||||
}
|
||||
.then(async (entities: any): Promise<void> => {
|
||||
for (const item of entities) {
|
||||
if (item.name === name) {
|
||||
await this._deleteItem(name, item);
|
||||
// deletedItems.push(deletedItem);
|
||||
}
|
||||
cb(null);
|
||||
}
|
||||
)
|
||||
cb(null);
|
||||
})
|
||||
.catch((err: Error): void => {
|
||||
cb(getInternalError(err.message));
|
||||
});
|
||||
|
||||
@@ -90,16 +90,14 @@ class GoogleCloudStorageHandler implements IPackageStorageManager {
|
||||
onEnd(getInternalError(err.message));
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
(err: Error): Callback => {
|
||||
this.logger.error(
|
||||
{ name, error: err },
|
||||
'gcloud: trying to update @{name} and was not found on storage err: @{error}'
|
||||
);
|
||||
// @ts-ignore
|
||||
return onEnd(getNotFound());
|
||||
}
|
||||
);
|
||||
.catch((err: Error): Callback => {
|
||||
this.logger.error(
|
||||
{ name, error: err },
|
||||
'gcloud: trying to update @{name} and was not found on storage err: @{error}'
|
||||
);
|
||||
// @ts-ignore
|
||||
return onEnd(getNotFound());
|
||||
});
|
||||
}
|
||||
|
||||
public deletePackage(fileName: string, cb: CallbackAction): void {
|
||||
@@ -197,28 +195,26 @@ class GoogleCloudStorageHandler implements IPackageStorageManager {
|
||||
|
||||
/* eslint-disable no-async-promise-executor */
|
||||
private _savePackage(name: string, metadata: Package): Promise<null | VerdaccioError> {
|
||||
return new Promise(
|
||||
async (resolve, reject): Promise<void> => {
|
||||
const file = this.helper.buildFilePath(name, pkgFileName);
|
||||
try {
|
||||
await file.save(this._convertToString(metadata), {
|
||||
validation: this.config.validation || defaultValidation,
|
||||
/**
|
||||
* When resumable is `undefined` - it will default to `true`as
|
||||
* per GC Storage documentation:
|
||||
* `Resumable uploads are automatically enabled and must be shut
|
||||
* off explicitly by setting options.resumable to false`
|
||||
* @see
|
||||
* https://cloud.google.com/nodejs/docs/reference/storage/2.5.x/File#createWriteStream
|
||||
*/
|
||||
resumable: this.config.resumable,
|
||||
});
|
||||
resolve(null);
|
||||
} catch (err) {
|
||||
reject(getInternalError(err.message));
|
||||
}
|
||||
return new Promise(async (resolve, reject): Promise<void> => {
|
||||
const file = this.helper.buildFilePath(name, pkgFileName);
|
||||
try {
|
||||
await file.save(this._convertToString(metadata), {
|
||||
validation: this.config.validation || defaultValidation,
|
||||
/**
|
||||
* When resumable is `undefined` - it will default to `true`as
|
||||
* per GC Storage documentation:
|
||||
* `Resumable uploads are automatically enabled and must be shut
|
||||
* off explicitly by setting options.resumable to false`
|
||||
* @see
|
||||
* https://cloud.google.com/nodejs/docs/reference/storage/2.5.x/File#createWriteStream
|
||||
*/
|
||||
resumable: this.config.resumable,
|
||||
});
|
||||
resolve(null);
|
||||
} catch (err) {
|
||||
reject(getInternalError(err.message));
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
/* eslint-enable no-async-promise-executor */
|
||||
|
||||
@@ -244,48 +240,44 @@ class GoogleCloudStorageHandler implements IPackageStorageManager {
|
||||
|
||||
/* eslint-disable no-async-promise-executor */
|
||||
private _fileExist(name: string, fileName: string): Promise<boolean> {
|
||||
return new Promise(
|
||||
async (resolve, reject): Promise<void> => {
|
||||
const file: File = this.helper.buildFilePath(name, fileName);
|
||||
try {
|
||||
// @ts-ignore
|
||||
const data = await file.exists();
|
||||
const exist = data[0];
|
||||
return new Promise(async (resolve, reject): Promise<void> => {
|
||||
const file: File = this.helper.buildFilePath(name, fileName);
|
||||
try {
|
||||
// @ts-ignore
|
||||
const data = await file.exists();
|
||||
const exist = data[0];
|
||||
|
||||
resolve(exist);
|
||||
this.logger.debug(
|
||||
{ name: name, exist },
|
||||
'gcloud: check whether @{name} exist successfully: @{exist}'
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error(
|
||||
{ name: file.name, err: err.message },
|
||||
'gcloud: check exist package @{name} has failed, cause: @{err}'
|
||||
);
|
||||
resolve(exist);
|
||||
this.logger.debug(
|
||||
{ name: name, exist },
|
||||
'gcloud: check whether @{name} exist successfully: @{exist}'
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error(
|
||||
{ name: file.name, err: err.message },
|
||||
'gcloud: check exist package @{name} has failed, cause: @{err}'
|
||||
);
|
||||
|
||||
reject(getInternalError(err.message));
|
||||
}
|
||||
reject(getInternalError(err.message));
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private async _readPackage(name: string): Promise<Package> {
|
||||
return new Promise(
|
||||
async (resolve, reject): Promise<void> => {
|
||||
const file = this.helper.buildFilePath(name, pkgFileName);
|
||||
return new Promise(async (resolve, reject): Promise<void> => {
|
||||
const file = this.helper.buildFilePath(name, pkgFileName);
|
||||
|
||||
try {
|
||||
const content: DownloadResponse = await file.download();
|
||||
this.logger.debug({ name: this.name }, 'gcloud: @{name} was found on storage');
|
||||
const response: Package = JSON.parse(content[0].toString('utf8'));
|
||||
try {
|
||||
const content: DownloadResponse = await file.download();
|
||||
this.logger.debug({ name: this.name }, 'gcloud: @{name} was found on storage');
|
||||
const response: Package = JSON.parse(content[0].toString('utf8'));
|
||||
|
||||
resolve(response);
|
||||
} catch (err) {
|
||||
this.logger.debug({ name: this.name }, 'gcloud: @{name} package not found on storage');
|
||||
reject(getNotFound());
|
||||
}
|
||||
resolve(response);
|
||||
} catch (err) {
|
||||
this.logger.debug({ name: this.name }, 'gcloud: @{name} package not found on storage');
|
||||
reject(getNotFound());
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
/* eslint-disable no-async-promise-executor */
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"@testing-library/dom": "^7.29.0",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/react": "10.4.9",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.17",
|
||||
"autosuggest-highlight": "3.1.1",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
|
||||
@@ -21,8 +21,13 @@ export interface FilterOptionsState<Option> {
|
||||
}
|
||||
|
||||
function createFilterOptions(config?: CreateFilterOptionsConfig) {
|
||||
const { ignoreAccents = true, ignoreCase = true, trim = false, limit, matchFrom = 'any' } =
|
||||
config || {};
|
||||
const {
|
||||
ignoreAccents = true,
|
||||
ignoreCase = true,
|
||||
trim = false,
|
||||
limit,
|
||||
matchFrom = 'any',
|
||||
} = config || {};
|
||||
|
||||
return <Option extends {}>(
|
||||
options: Option[],
|
||||
|
||||
@@ -6,9 +6,10 @@ import { Theme } from './theme';
|
||||
const resetStyles = makeStyles(({ theme }: { theme?: Theme }) => ({
|
||||
'@global': {
|
||||
// eslint-disable-next-line max-len
|
||||
'html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video': {
|
||||
fontFamily: '"Roboto", Helvetica Neue, Arial, sans-serif',
|
||||
},
|
||||
'html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video':
|
||||
{
|
||||
fontFamily: '"Roboto", Helvetica Neue, Arial, sans-serif',
|
||||
},
|
||||
strong: {
|
||||
fontWeight: theme && theme.fontWeight.semiBold,
|
||||
},
|
||||
|
||||
@@ -22,18 +22,8 @@ const cache = new CellMeasurerCache({
|
||||
/* eslint-disable verdaccio/jsx-no-style */
|
||||
const PackageList: React.FC<Props> = ({ packages }) => {
|
||||
const renderRow = ({ index, key, parent, style }: ListRowProps) => {
|
||||
const {
|
||||
name,
|
||||
version,
|
||||
description,
|
||||
time,
|
||||
keywords,
|
||||
dist,
|
||||
homepage,
|
||||
bugs,
|
||||
author,
|
||||
license,
|
||||
} = packages[index];
|
||||
const { name, version, description, time, keywords, dist, homepage, bugs, author, license } =
|
||||
packages[index];
|
||||
// TODO: move format license to API side.
|
||||
const formattedLicense = formatLicense(license);
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import { SyntheticEvent } from 'react';
|
||||
|
||||
export const copyToClipBoardUtility = (str: string): ((e: SyntheticEvent<HTMLElement>) => void) => (
|
||||
event: SyntheticEvent<HTMLElement>
|
||||
): void => {
|
||||
event.preventDefault();
|
||||
export const copyToClipBoardUtility =
|
||||
(str: string): ((e: SyntheticEvent<HTMLElement>) => void) =>
|
||||
(event: SyntheticEvent<HTMLElement>): void => {
|
||||
event.preventDefault();
|
||||
|
||||
const node = document.createElement('div');
|
||||
node.innerText = str;
|
||||
if (document.body) {
|
||||
document.body.appendChild(node);
|
||||
const node = document.createElement('div');
|
||||
node.innerText = str;
|
||||
if (document.body) {
|
||||
document.body.appendChild(node);
|
||||
|
||||
const range = document.createRange();
|
||||
const selection = window.getSelection() as Selection;
|
||||
range.selectNodeContents(node);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(node);
|
||||
}
|
||||
};
|
||||
const range = document.createRange();
|
||||
const selection = window.getSelection() as Selection;
|
||||
range.selectNodeContents(node);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(node);
|
||||
}
|
||||
};
|
||||
|
||||
export function getCLISetConfigRegistry(
|
||||
command: string,
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @verdaccio/proxy
|
||||
|
||||
## 6.0.0-6-next.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
|
||||
## 6.0.0-6-next.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/proxy",
|
||||
"version": "6.0.0-6-next.8",
|
||||
"version": "6.0.0-6-next.9",
|
||||
"description": "verdaccio proxy fetcher",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -40,17 +40,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/local-storage": "workspace:11.0.0-6-next.6",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/streams": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"JSONStream": "1.3.5",
|
||||
"lodash": "^4.17.20",
|
||||
"lodash": "4.17.20",
|
||||
"request": "2.87.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7"
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7",
|
||||
"nock": "13.0.11",
|
||||
"node-mocks-http": "1.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './up-storage';
|
||||
export * from './uplink-util';
|
||||
|
||||
@@ -64,7 +64,6 @@ export interface IProxy {
|
||||
fail_timeout: number;
|
||||
upname: string;
|
||||
fetchTarball(url: string): IReadTarball;
|
||||
isUplinkValid(url: string): boolean;
|
||||
search(options: any);
|
||||
getRemoteMetadata(name: string, options: any, callback: Callback): void;
|
||||
}
|
||||
@@ -436,27 +435,6 @@ class ProxyStorage implements IProxy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether can fetch from the provided URL
|
||||
* @param {*} url
|
||||
* @return {Boolean}
|
||||
*/
|
||||
public isUplinkValid(url: string): boolean {
|
||||
// $FlowFixMe
|
||||
const urlParsed: UrlWithStringQuery = URL.parse(url);
|
||||
const isHTTPS = (urlDomainParsed: URL): boolean =>
|
||||
urlDomainParsed.protocol === 'https:' &&
|
||||
(urlParsed.port === null || urlParsed.port === '443');
|
||||
const getHost = (urlDomainParsed): boolean =>
|
||||
isHTTPS(urlDomainParsed) ? urlDomainParsed.hostname : urlDomainParsed.host;
|
||||
const isMatchProtocol: boolean = urlParsed.protocol === this.url.protocol;
|
||||
const isMatchHost: boolean = getHost(urlParsed) === getHost(this.url);
|
||||
// @ts-ignore
|
||||
const isMatchPath: boolean = urlParsed.path.indexOf(this.url.path) === 0;
|
||||
|
||||
return isMatchProtocol && isMatchHost && isMatchPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a remote package metadata
|
||||
* @param {*} name package name
|
||||
|
||||
31
packages/proxy/test/conf/proxy1.yaml
Normal file
31
packages/proxy/test/conf/proxy1.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
storage: ./storage
|
||||
plugins: ./plugins
|
||||
web:
|
||||
title: Verdaccio
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
'**':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
unpublish: $authenticated
|
||||
proxy: npmjs
|
||||
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
|
||||
middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
logs: { type: stdout, format: pretty, level: http }
|
||||
@@ -19,6 +19,7 @@ function createUplink(config) {
|
||||
|
||||
function setHeaders(config: unknown = {}, headers: unknown = {}) {
|
||||
const uplink = createUplink(config);
|
||||
// @ts-expect-error
|
||||
return uplink._setHeaders({
|
||||
headers,
|
||||
});
|
||||
|
||||
BIN
packages/proxy/test/partials/jquery-0.0.1.tgz
Normal file
BIN
packages/proxy/test/partials/jquery-0.0.1.tgz
Normal file
Binary file not shown.
567
packages/proxy/test/partials/search-v1.json
Normal file
567
packages/proxy/test/partials/search-v1.json
Normal file
@@ -0,0 +1,567 @@
|
||||
{
|
||||
"verdaccio": {
|
||||
"name": "verdaccio",
|
||||
"description": "A lightweight private npm proxy registry",
|
||||
"maintainers": [
|
||||
"=jotadeveloper",
|
||||
"=ayusharma",
|
||||
"=trentearl",
|
||||
"=jmwilkinson",
|
||||
"=sergiohgz",
|
||||
"=verdaccio.npm"
|
||||
],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "5.0.4",
|
||||
"time": "2021-04-28 ",
|
||||
"words": "verdaccio a lightweight private npm proxy registry =jotadeveloper =ayusharma =trentearl =jmwilkinson =sergiohgz =verdaccio.npm"
|
||||
},
|
||||
"verdaccio-bitbucket": {
|
||||
"name": "verdaccio-bitbucket",
|
||||
"description": "Verdaccio module to authenticate users via Bitbucket",
|
||||
"maintainers": ["=idangozlan"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "3.0.1",
|
||||
"time": "2020-11-17 ",
|
||||
"words": "verdaccio-bitbucket verdaccio module to authenticate users via bitbucket =idangozlan"
|
||||
},
|
||||
"@verdaccio/streams": {
|
||||
"name": "@verdaccio/streams",
|
||||
"description": "Stream extension for Verdaccio",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/streams stream extension for verdaccio =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"@verdaccio/commons-api": {
|
||||
"name": "@verdaccio/commons-api",
|
||||
"description": "Commons API utilities for Verdaccio",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/commons-api commons api utilities for verdaccio =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-auth-bitbucket": {
|
||||
"name": "verdaccio-auth-bitbucket",
|
||||
"description": "Verdaccio module to authenticate users via Bitbucket",
|
||||
"maintainers": ["=tomamatics"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "2.0.3",
|
||||
"time": "2020-11-12 ",
|
||||
"words": "verdaccio-auth-bitbucket verdaccio module to authenticate users via bitbucket =tomamatics"
|
||||
},
|
||||
"verdaccio-audit": {
|
||||
"name": "verdaccio-audit",
|
||||
"description": "Verdaccio Middleware plugin to bypass npmjs audit",
|
||||
"maintainers": ["=jotadeveloper", "=ayusharma", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "verdaccio-audit verdaccio middleware plugin to bypass npmjs audit =jotadeveloper =ayusharma =verdaccio.npm"
|
||||
},
|
||||
"@verdaccio/ui-theme": {
|
||||
"name": "@verdaccio/ui-theme",
|
||||
"description": "Verdaccio User Interface",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "3.1.0",
|
||||
"time": "2021-04-27 ",
|
||||
"words": "@verdaccio/ui-theme verdaccio user interface =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"@verdaccio/local-storage": {
|
||||
"name": "@verdaccio/local-storage",
|
||||
"description": "Local storage implementation",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.6",
|
||||
"time": "2021-05-01 ",
|
||||
"words": "@verdaccio/local-storage local storage implementation =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"@verdaccio/file-locking": {
|
||||
"name": "@verdaccio/file-locking",
|
||||
"description": "library that handle file locking",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/file-locking library that handle file locking =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-htpasswd": {
|
||||
"name": "verdaccio-htpasswd",
|
||||
"description": "htpasswd auth plugin for Verdaccio",
|
||||
"maintainers": ["=jotadeveloper", "=ayusharma", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "verdaccio-htpasswd htpasswd auth plugin for verdaccio =jotadeveloper =ayusharma =verdaccio.npm"
|
||||
},
|
||||
"verdaccio-badger": {
|
||||
"name": "verdaccio-badger",
|
||||
"description": "verdaccio middleware plugin to serve svg badges",
|
||||
"maintainers": ["=paddek"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.0",
|
||||
"time": "2020-08-02 ",
|
||||
"words": "verdaccio-badger verdaccio middleware plugin to serve svg badges =paddek"
|
||||
},
|
||||
"@verdaccio/readme": {
|
||||
"name": "@verdaccio/readme",
|
||||
"description": "Readme markdown parser",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/readme readme markdown parser =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-dynamodb": {
|
||||
"name": "verdaccio-dynamodb",
|
||||
"description": "Verdaccio DynamoDB Auth Plugin",
|
||||
"maintainers": ["=cwilson"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.1.8",
|
||||
"time": "2020-06-24 ",
|
||||
"words": "verdaccio-dynamodb verdaccio dynamodb auth plugin =cwilson"
|
||||
},
|
||||
"@outcome-co/verdaccio-github-auth": {
|
||||
"name": "@outcome-co/verdaccio-github-auth",
|
||||
"description": "Verdaccio Github Authentication Plugin",
|
||||
"maintainers": ["=d-tw"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "2.0.9",
|
||||
"time": "2021-05-05 ",
|
||||
"words": "@outcome-co/verdaccio-github-auth verdaccio github authentication plugin =d-tw"
|
||||
},
|
||||
"verdaccio-memory": {
|
||||
"name": "verdaccio-memory",
|
||||
"description": "Storage implementation in memory",
|
||||
"maintainers": ["=jotadeveloper", "=ayusharma", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "verdaccio-memory storage implementation in memory =jotadeveloper =ayusharma =verdaccio.npm"
|
||||
},
|
||||
"@verdaccio/types": {
|
||||
"name": "@verdaccio/types",
|
||||
"description": "verdaccio types definitions",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/types verdaccio types definitions =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-auth-memory": {
|
||||
"name": "verdaccio-auth-memory",
|
||||
"description": "Auth plugin for Verdaccio that keeps users in memory",
|
||||
"maintainers": ["=jotadeveloper", "=ayusharma", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "verdaccio-auth-memory auth plugin for verdaccio that keeps users in memory =jotadeveloper =ayusharma =verdaccio.npm"
|
||||
},
|
||||
"generator-verdaccio-plugin": {
|
||||
"name": "generator-verdaccio-plugin",
|
||||
"description": "plugin generator for verdaccio",
|
||||
"maintainers": ["=jotadeveloper", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "3.0.1",
|
||||
"time": "2020-12-23 ",
|
||||
"words": "generator-verdaccio-plugin plugin generator for verdaccio =jotadeveloper =verdaccio.npm"
|
||||
},
|
||||
"verdaccio-bitbucket-server": {
|
||||
"name": "verdaccio-bitbucket-server",
|
||||
"description": "Verdaccio Authentication Plugin via Bitbucket Server",
|
||||
"maintainers": ["=oeph"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.3.1",
|
||||
"time": "2020-09-24 ",
|
||||
"words": "verdaccio-bitbucket-server verdaccio authentication plugin via bitbucket server =oeph"
|
||||
},
|
||||
"verdaccio-theme-hilio": {
|
||||
"name": "verdaccio-theme-hilio",
|
||||
"description": "Verdaccio User Interface",
|
||||
"maintainers": ["=joebnb"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.14.5",
|
||||
"time": "2021-01-12 ",
|
||||
"words": "verdaccio-theme-hilio verdaccio user interface =joebnb"
|
||||
},
|
||||
"verdaccio-aws-s3-storage": {
|
||||
"name": "verdaccio-aws-s3-storage",
|
||||
"description": "AWS S3 storage implementation for Verdaccio",
|
||||
"maintainers": ["=jotadeveloper", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.1.0",
|
||||
"time": "2021-05-02 ",
|
||||
"words": "verdaccio-aws-s3-storage aws s3 storage implementation for verdaccio =jotadeveloper =verdaccio.npm"
|
||||
},
|
||||
"verdaccio-minio": {
|
||||
"name": "verdaccio-minio",
|
||||
"description": "A verdaccio plugin for storing data in Minio",
|
||||
"maintainers": ["=barolab"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "0.2.5",
|
||||
"time": "2020-03-16 ",
|
||||
"words": "verdaccio-minio a verdaccio plugin for storing data in minio =barolab"
|
||||
},
|
||||
"p3x-verdaccio-cli": {
|
||||
"name": "p3x-verdaccio-cli",
|
||||
"description": "🍶 Verdaccio CLI",
|
||||
"maintainers": ["=patrikx3"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "2021.4.113",
|
||||
"time": "2021-03-07 ",
|
||||
"words": "p3x-verdaccio-cli 🍶 verdaccio cli =patrikx3"
|
||||
},
|
||||
"verdaccio-theme-xdf": {
|
||||
"name": "verdaccio-theme-xdf",
|
||||
"description": "Verdaccio User Interface",
|
||||
"maintainers": ["=likaizhu"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.0",
|
||||
"time": "2020-11-25 ",
|
||||
"words": "verdaccio-theme-xdf verdaccio user interface =likaizhu"
|
||||
},
|
||||
"kiss-verdaccio-types": {
|
||||
"name": "kiss-verdaccio-types",
|
||||
"description": "verdaccio types definitions",
|
||||
"maintainers": ["=qd397"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "9.7.3",
|
||||
"time": "2021-02-22 ",
|
||||
"words": "kiss-verdaccio-types verdaccio types definitions =qd397"
|
||||
},
|
||||
"@verdaccio/testing-utilities": {
|
||||
"name": "@verdaccio/testing-utilities",
|
||||
"description": "Utils for Verdaccio",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/testing-utilities utils for verdaccio =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-git": {
|
||||
"name": "verdaccio-git",
|
||||
"description": "Publish packages to git repositories.",
|
||||
"maintainers": ["=amazeelabs"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "0.1.29",
|
||||
"time": "2021-03-01 ",
|
||||
"words": "verdaccio-git publish packages to git repositories. =amazeelabs"
|
||||
},
|
||||
"eslint-plugin-verdaccio": {
|
||||
"name": "eslint-plugin-verdaccio",
|
||||
"description": "Verdaccio code guidelines",
|
||||
"maintainers": ["=jotadeveloper", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "eslint-plugin-verdaccio verdaccio code guidelines =jotadeveloper =verdaccio.npm"
|
||||
},
|
||||
"@verdaccio/active-directory": {
|
||||
"name": "@verdaccio/active-directory",
|
||||
"description": "Active Directory authentication plugin for Verdaccio",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/active-directory active directory authentication plugin for verdaccio =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-google-cloud": {
|
||||
"name": "verdaccio-google-cloud",
|
||||
"description": "Google Cloud storage implementation for Verdaccio",
|
||||
"maintainers": ["=jotadeveloper", "=verdaccio.npm"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "verdaccio-google-cloud google cloud storage implementation for verdaccio =jotadeveloper =verdaccio.npm"
|
||||
},
|
||||
"verdaccio-pacman": {
|
||||
"name": "verdaccio-pacman",
|
||||
"description": "Verdaccio Middleware Plugin to manage tags and versions of packages",
|
||||
"maintainers": ["=paddek"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.1.1",
|
||||
"time": "2020-10-07 ",
|
||||
"words": "verdaccio-pacman verdaccio middleware plugin to manage tags and versions of packages =paddek"
|
||||
},
|
||||
"verdaccio-ldap-memcached": {
|
||||
"name": "verdaccio-ldap-memcached",
|
||||
"description": "LDAP auth plugin for verdaccio",
|
||||
"maintainers": ["=therippa"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.4.1",
|
||||
"time": "2018-02-02 ",
|
||||
"words": "verdaccio-ldap-memcached ldap auth plugin for verdaccio =therippa"
|
||||
},
|
||||
"@verdaccio/eslint-config": {
|
||||
"name": "@verdaccio/eslint-config",
|
||||
"description": "Verdaccio ESLint shareable config",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/eslint-config verdaccio eslint shareable config =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"uino-verdaccio": {
|
||||
"name": "uino-verdaccio",
|
||||
"description": "A lightweight private npm proxy registry",
|
||||
"maintainers": ["=qd397"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "4.8.5",
|
||||
"time": "2021-02-22 ",
|
||||
"words": "uino-verdaccio a lightweight private npm proxy registry =qd397"
|
||||
},
|
||||
"@verdaccio/babel-preset": {
|
||||
"name": "@verdaccio/babel-preset",
|
||||
"description": "A common preset for Verdaccio projects",
|
||||
"maintainers": ["=sergiohgz", "=verdaccio.npm", "=jotadeveloper", "=ayusharma"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "10.0.0",
|
||||
"time": "2021-03-29 ",
|
||||
"words": "@verdaccio/babel-preset a common preset for verdaccio projects =sergiohgz =verdaccio.npm =jotadeveloper =ayusharma"
|
||||
},
|
||||
"verdaccio-gitlab-hilio": {
|
||||
"name": "verdaccio-gitlab-hilio",
|
||||
"description": "private npm registry (Verdaccio) using gitlab-ce as authentication and authorization provider",
|
||||
"maintainers": ["=joebnb"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.1.17",
|
||||
"time": "2021-04-07 ",
|
||||
"words": "verdaccio-gitlab-hilio private npm registry (verdaccio) using gitlab-ce as authentication and authorization provider =joebnb"
|
||||
},
|
||||
"verdaccio-ldap": {
|
||||
"name": "verdaccio-ldap",
|
||||
"description": "LDAP auth plugin for verdaccio",
|
||||
"maintainers": ["=alexandre-io"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "4.2.0",
|
||||
"time": "2020-08-15 ",
|
||||
"words": "verdaccio-ldap ldap auth plugin for verdaccio =alexandre-io"
|
||||
},
|
||||
"verdaccio-github-oauth-ui": {
|
||||
"name": "verdaccio-github-oauth-ui",
|
||||
"description": "<h1 align=\"center\"> 📦🔐 Verdaccio GitHub OAuth - With UI Support </h1>",
|
||||
"maintainers": ["=abraham-schilling"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "3.0.0",
|
||||
"time": "2021-05-02 ",
|
||||
"words": "verdaccio-github-oauth-ui <h1 align=\"center\"> 📦🔐 verdaccio github oauth - with ui support </h1> =abraham-schilling"
|
||||
},
|
||||
"verdaccio-https": {
|
||||
"name": "verdaccio-https",
|
||||
"description": "verdaccio middleware plugin to redirect to https",
|
||||
"maintainers": ["=honzahommer"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.11",
|
||||
"time": "2019-10-19 ",
|
||||
"words": "verdaccio-https verdaccio middleware plugin to redirect to https =honzahommer"
|
||||
},
|
||||
"mlc-verdaccio-s3-archiver": {
|
||||
"name": "mlc-verdaccio-s3-archiver",
|
||||
"description": "Builds an archive of your verdaccio instance, then backup it to AWS S3.",
|
||||
"maintainers": ["=moonlight-coding"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.3",
|
||||
"time": "2020-05-17 ",
|
||||
"words": "mlc-verdaccio-s3-archiver builds an archive of your verdaccio instance, then backup it to aws s3. =moonlight-coding"
|
||||
},
|
||||
"verdaccio-pg-storage": {
|
||||
"name": "verdaccio-pg-storage",
|
||||
"description": "Storage plugin to host packages PostgreSQL",
|
||||
"maintainers": ["=yckao"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.3",
|
||||
"time": "2020-06-24 ",
|
||||
"words": "verdaccio-pg-storage storage plugin to host packages postgresql =yckao"
|
||||
},
|
||||
"verdaccio-openmetrics": {
|
||||
"name": "verdaccio-openmetrics",
|
||||
"description": "Verdaccio plugin exposing an OpenMetrics/Prometheus endpoint with health and traffic metrics",
|
||||
"maintainers": ["=freightbot"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.1.0",
|
||||
"time": "2021-03-22 ",
|
||||
"words": "verdaccio-openmetrics verdaccio plugin exposing an openmetrics/prometheus endpoint with health and traffic metrics =freightbot"
|
||||
},
|
||||
"verdaccio-apm-server": {
|
||||
"name": "verdaccio-apm-server",
|
||||
"description": "An amazing verdaccio plugin",
|
||||
"maintainers": ["=soul741"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.14",
|
||||
"time": "2020-09-28 ",
|
||||
"words": "verdaccio-apm-server an amazing verdaccio plugin =soul741"
|
||||
},
|
||||
"verdaccio-local-storage-with-cache-db": {
|
||||
"name": "verdaccio-local-storage-with-cache-db",
|
||||
"description": "Local storage implementation",
|
||||
"maintainers": ["=joebnb"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "9.7.5",
|
||||
"time": "2020-11-28 ",
|
||||
"words": "verdaccio-local-storage-with-cache-db local storage implementation =joebnb"
|
||||
},
|
||||
"verdaccio-azure-ad-login": {
|
||||
"name": "verdaccio-azure-ad-login",
|
||||
"description": "Let your users authenticate into Verdaccio using Azure AD OAuth",
|
||||
"maintainers": ["=ihton"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.5",
|
||||
"time": "2021-02-25 ",
|
||||
"words": "verdaccio-azure-ad-login let your users authenticate into verdaccio using azure ad oauth =ihton"
|
||||
},
|
||||
"@freighthub/verdaccio-openmetrics": {
|
||||
"name": "@freighthub/verdaccio-openmetrics",
|
||||
"description": "Verdaccio plugin exposing an OpenMetrics/Prometheus endpoint with health and traffic metrics",
|
||||
"maintainers": [
|
||||
"=pallavimalik",
|
||||
"=lydia.seidlitz",
|
||||
"=michelle.chua",
|
||||
"=rodmatos",
|
||||
"=danopia",
|
||||
"=diogocostaferraz",
|
||||
"=namit1211",
|
||||
"=matang.dave",
|
||||
"=wes.lim",
|
||||
"=orinelin",
|
||||
"=beheim",
|
||||
"=erikmuttersbach",
|
||||
"=justgoscha",
|
||||
"=firellon",
|
||||
"=l-oris",
|
||||
"=artfwo",
|
||||
"=pravinbashyal",
|
||||
"=freightbot",
|
||||
"=milos.mircov",
|
||||
"=unsal.gokdag",
|
||||
"=norocketscientist",
|
||||
"=sid23",
|
||||
"=vedpbharti",
|
||||
"=fr-yp",
|
||||
"=prabhakalaivani",
|
||||
"=baptlesta",
|
||||
"=luisantunesdeveloper",
|
||||
"=blueyedgeek",
|
||||
"=rashidfh",
|
||||
"=ulymarins",
|
||||
"=pedrock",
|
||||
"=jose.suero",
|
||||
"=anup.dev",
|
||||
"=sidoshi",
|
||||
"=mridulmeh",
|
||||
"=dhayanand",
|
||||
"=avijit.gupta",
|
||||
"=dijia",
|
||||
"=batuhandirek",
|
||||
"=dayemsiddiqui",
|
||||
"=eruditespirit",
|
||||
"=ajayvarghese003",
|
||||
"=ortserga",
|
||||
"=fmueller_bln",
|
||||
"=imartyn",
|
||||
"=sabbir.ahmmed",
|
||||
"=aditya337",
|
||||
"=ranyardmforto",
|
||||
"=mtrabelsi",
|
||||
"=lsamayoa-forto",
|
||||
"=nitesh-forto",
|
||||
"=albertvp",
|
||||
"=aliasgarhada",
|
||||
"=ruizmurcia",
|
||||
"=micszym",
|
||||
"=b3nshi",
|
||||
"=dawidmf"
|
||||
],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.1",
|
||||
"time": "2021-01-12 ",
|
||||
"words": "@freighthub/verdaccio-openmetrics verdaccio plugin exposing an openmetrics/prometheus endpoint with health and traffic metrics =pallavimalik =lydia.seidlitz =michelle.chua =rodmatos =danopia =diogocostaferraz =namit1211 =matang.dave =wes.lim =orinelin =beheim =erikmuttersbach =justgoscha =firellon =l-oris =artfwo =pravinbashyal =freightbot =milos.mircov =unsal.gokdag =norocketscientist =sid23 =vedpbharti =fr-yp =prabhakalaivani =baptlesta =luisantunesdeveloper =blueyedgeek =rashidfh =ulymarins =pedrock =jose.suero =anup.dev =sidoshi =mridulmeh =dhayanand =avijit.gupta =dijia =batuhandirek =dayemsiddiqui =eruditespirit =ajayvarghese003 =ortserga =fmueller_bln =imartyn =sabbir.ahmmed =aditya337 =ranyardmforto =mtrabelsi =lsamayoa-forto =nitesh-forto =albertvp =aliasgarhada =ruizmurcia =micszym =b3nshi =dawidmf"
|
||||
},
|
||||
"bulk-npm-publish": {
|
||||
"name": "bulk-npm-publish",
|
||||
"description": "Publish Multiple NPM packages from verdaccio storage",
|
||||
"maintainers": ["=rluvaton"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "3.0.2",
|
||||
"time": "2021-03-15 ",
|
||||
"words": "bulk-npm-publish publish multiple npm packages from verdaccio storage =rluvaton"
|
||||
},
|
||||
"verdaccio-acl-plugin": {
|
||||
"name": "verdaccio-acl-plugin",
|
||||
"description": "Plugin to simplify group permissions management",
|
||||
"maintainers": ["=t3o-it"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.1",
|
||||
"time": "2021-02-01 ",
|
||||
"words": "verdaccio-acl-plugin plugin to simplify group permissions management =t3o-it"
|
||||
},
|
||||
"verdaccio-openid-connect": {
|
||||
"name": "verdaccio-openid-connect",
|
||||
"description": "Verdaccio authentication plugin for OpenID Connect. When installed, `npm login --registry ...` command will open the browser to start login flow.",
|
||||
"maintainers": ["=aikoven"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.2",
|
||||
"time": "2021-01-31 ",
|
||||
"words": "verdaccio-openid-connect verdaccio authentication plugin for openid connect. when installed, `npm login --registry ...` command will open the browser to start login flow. =aikoven"
|
||||
},
|
||||
"verdaccio-groups2": {
|
||||
"name": "verdaccio-groups2",
|
||||
"description": "- 一个verdaccio group管理插件(auth插件)",
|
||||
"maintainers": ["=jeffery0211"],
|
||||
"url": null,
|
||||
"keywords": [],
|
||||
"version": "1.0.2",
|
||||
"time": "2021-01-02 ",
|
||||
"words": "verdaccio-groups2 - 一个verdaccio group管理插件(auth插件) =jeffery0211"
|
||||
}
|
||||
}
|
||||
744
packages/proxy/test/partials/search-v2.json
Normal file
744
packages/proxy/test/partials/search-v2.json
Normal file
@@ -0,0 +1,744 @@
|
||||
[
|
||||
{
|
||||
"name": "verdaccio",
|
||||
"scope": "unscoped",
|
||||
"version": "5.0.4",
|
||||
"description": "A lightweight private npm proxy registry",
|
||||
"keywords": [
|
||||
"private",
|
||||
"package",
|
||||
"repository",
|
||||
"registry",
|
||||
"enterprise",
|
||||
"modules",
|
||||
"proxy",
|
||||
"server",
|
||||
"verdaccio"
|
||||
],
|
||||
"date": "2021-04-28T05:24:23.696Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/verdaccio",
|
||||
"bugs": "https://github.com/verdaccio/verdaccio/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Verdaccio Maintainers",
|
||||
"email": "verdaccio.npm@gmail.com",
|
||||
"username": "verdaccio.npm"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "trentearl",
|
||||
"email": "trent@trentearl.com"
|
||||
},
|
||||
{
|
||||
"username": "jmwilkinson",
|
||||
"email": "J.Wilkinson@f5.com"
|
||||
},
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-bitbucket",
|
||||
"scope": "unscoped",
|
||||
"version": "3.0.1",
|
||||
"description": "Verdaccio module to authenticate users via Bitbucket",
|
||||
"keywords": [
|
||||
"sinopia",
|
||||
"verdaccio",
|
||||
"bitbucket",
|
||||
"atlassian",
|
||||
"auth",
|
||||
"node",
|
||||
"nodejs",
|
||||
"js",
|
||||
"javascript"
|
||||
],
|
||||
"date": "2020-11-17T18:31:50.893Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-bitbucket",
|
||||
"homepage": "https://github.com/idangozlan/verdaccio-bitbucket#readme",
|
||||
"repository": "https://github.com/idangozlan/verdaccio-bitbucket",
|
||||
"bugs": "https://github.com/idangozlan/verdaccio-bitbucket/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Idan Gozlan",
|
||||
"email": "idangozlan@gmail.com",
|
||||
"username": "idangozlan"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "idangozlan",
|
||||
"email": "idangozlan@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "idangozlan",
|
||||
"email": "idangozlan@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-auth-bitbucket",
|
||||
"scope": "unscoped",
|
||||
"version": "2.0.3",
|
||||
"description": "Verdaccio module to authenticate users via Bitbucket",
|
||||
"keywords": [
|
||||
"sinopia",
|
||||
"verdaccio",
|
||||
"bitbucket",
|
||||
"atlassian",
|
||||
"auth",
|
||||
"node",
|
||||
"nodejs",
|
||||
"js",
|
||||
"javascript"
|
||||
],
|
||||
"date": "2020-11-12T16:44:32.807Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-auth-bitbucket",
|
||||
"homepage": "https://github.com/tomamatics/verdaccio-bitbucket#readme",
|
||||
"repository": "https://github.com/tomamatics/verdaccio-bitbucket",
|
||||
"bugs": "https://github.com/tomamatics/verdaccio-bitbucket/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Tom Pachtner",
|
||||
"email": "tompachtner@gmail.com"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "tomamatics",
|
||||
"email": "tom@pachtner.net"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "tomamatics",
|
||||
"email": "tom@pachtner.net"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-badger",
|
||||
"scope": "unscoped",
|
||||
"version": "1.0.0",
|
||||
"description": "verdaccio middleware plugin to serve svg badges",
|
||||
"keywords": ["verdaccio", "plugin", "middleware", "badge", "badges"],
|
||||
"date": "2020-08-02T18:08:10.321Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-badger",
|
||||
"homepage": "https://github.com/PaddeK/verdaccio-badger",
|
||||
"repository": "https://github.com/PaddeK/verdaccio-badger",
|
||||
"bugs": "https://github.com/PaddeK/verdaccio-badger/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Patrick Klös",
|
||||
"email": "pkloes@web.de",
|
||||
"username": "paddek"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "paddek",
|
||||
"email": "pkloes@web.de"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "paddek",
|
||||
"email": "pkloes@web.de"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/streams",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.0",
|
||||
"description": "Stream extension for Verdaccio",
|
||||
"keywords": ["verdaccio", "streams"],
|
||||
"date": "2021-03-29T13:01:49.263Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Fstreams",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/commons-api",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.0",
|
||||
"description": "Commons API utilities for Verdaccio",
|
||||
"keywords": ["http", "verdaccio", "api"],
|
||||
"date": "2021-03-29T13:01:51.477Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Fcommons-api",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-audit",
|
||||
"scope": "unscoped",
|
||||
"version": "10.0.0",
|
||||
"description": "Verdaccio Middleware plugin to bypass npmjs audit",
|
||||
"keywords": ["verdaccio", "plugin", "middleware", "audit"],
|
||||
"date": "2021-03-29T13:01:49.126Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-audit",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/ui-theme",
|
||||
"scope": "verdaccio",
|
||||
"version": "3.1.0",
|
||||
"description": "Verdaccio User Interface",
|
||||
"keywords": ["verdaccio", "verdaccio-plugin", "verdaccio-theme"],
|
||||
"date": "2021-04-27T20:14:01.392Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Fui-theme",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/ui",
|
||||
"bugs": "https://github.com/verdaccio/ui/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Verdaccio Core Team",
|
||||
"email": "verdaccio.npm@gmail.com",
|
||||
"username": "verdaccio.npm"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/local-storage",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.6",
|
||||
"description": "Local storage implementation",
|
||||
"keywords": ["plugin", "verdaccio", "storage", "local-storage"],
|
||||
"date": "2021-05-01T07:51:30.546Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Flocal-storage",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/file-locking",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.0",
|
||||
"description": "library that handle file locking",
|
||||
"keywords": ["verdaccio", "lock", "fs"],
|
||||
"date": "2021-03-29T13:01:49.338Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Ffile-locking",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-htpasswd",
|
||||
"scope": "unscoped",
|
||||
"version": "10.0.0",
|
||||
"description": "htpasswd auth plugin for Verdaccio",
|
||||
"keywords": ["verdaccio", "plugin", "auth", "htpasswd"],
|
||||
"date": "2021-03-29T13:01:56.726Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-htpasswd",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Ayush Sharma",
|
||||
"email": "ayush.aceit@gmail.com",
|
||||
"username": "ayusharma"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/readme",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.0",
|
||||
"description": "Readme markdown parser",
|
||||
"keywords": ["verdaccio", "readme", "markdown"],
|
||||
"date": "2021-03-29T13:01:49.184Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Freadme",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-dynamodb",
|
||||
"scope": "unscoped",
|
||||
"version": "1.1.8",
|
||||
"description": "Verdaccio DynamoDB Auth Plugin",
|
||||
"keywords": ["aws", "auth-plugin", "verdaccio", "dynamodb", "verdaccio-plugin"],
|
||||
"date": "2020-06-24T00:27:56.073Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-dynamodb",
|
||||
"homepage": "https://github.com/pusherman/verdaccio-dynamodb#readme",
|
||||
"repository": "https://github.com/pusherman/verdaccio-dynamodb",
|
||||
"bugs": "https://github.com/pusherman/verdaccio-dynamodb/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Corey Wilson",
|
||||
"email": "corey@eastcodes.com",
|
||||
"username": "cwilson"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "cwilson",
|
||||
"email": "corey@eastcodes.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "cwilson",
|
||||
"email": "corey@eastcodes.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@outcome-co/verdaccio-github-auth",
|
||||
"scope": "outcome-co",
|
||||
"version": "2.0.9",
|
||||
"description": "Verdaccio Github Authentication Plugin",
|
||||
"date": "2021-05-05T09:20:40.658Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40outcome-co%2Fverdaccio-github-auth",
|
||||
"homepage": "https://github.com/outcome-co/verdaccio-github-auth-js",
|
||||
"repository": "https://github.com/outcome-co/verdaccio-github-auth-js",
|
||||
"bugs": "https://github.com/outcome-co/verdaccio-github-auth-js/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Outcome Engineering",
|
||||
"email": "engineering@outcome.co",
|
||||
"url": "https://outcome.co"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "d-tw",
|
||||
"email": "douglas@outcome.co"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "d-tw",
|
||||
"email": "douglas@outcome.co"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-bitbucket-server",
|
||||
"scope": "unscoped",
|
||||
"version": "1.3.1",
|
||||
"description": "Verdaccio Authentication Plugin via Bitbucket Server",
|
||||
"keywords": ["verdaccio", "verdaccio-plugin", "bitbucket", "bitbucket-server"],
|
||||
"date": "2020-09-24T18:02:25.638Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-bitbucket-server",
|
||||
"homepage": "https://github.com/oeph/verdaccio-bitbucket-server#readme",
|
||||
"repository": "https://github.com/oeph/verdaccio-bitbucket-server",
|
||||
"bugs": "https://github.com/oeph/verdaccio-bitbucket-server/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "oeph"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "oeph",
|
||||
"email": "npm@philippoeh.me"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "oeph",
|
||||
"email": "npm@philippoeh.me"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-memory",
|
||||
"scope": "unscoped",
|
||||
"version": "10.0.0",
|
||||
"description": "Storage implementation in memory",
|
||||
"keywords": ["verdaccio", "plugin", "storage", "memory"],
|
||||
"date": "2021-03-29T13:01:59.285Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-memory",
|
||||
"homepage": "https://verdaccio.org"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@verdaccio/types",
|
||||
"scope": "verdaccio",
|
||||
"version": "10.0.0",
|
||||
"description": "verdaccio types definitions",
|
||||
"keywords": ["verdaccio", "typescript", "types"],
|
||||
"date": "2021-03-29T13:01:49.294Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/%40verdaccio%2Ftypes",
|
||||
"homepage": "https://verdaccio.org",
|
||||
"repository": "https://github.com/verdaccio/monorepo",
|
||||
"bugs": "https://github.com/verdaccio/monorepo/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "sergiohgz",
|
||||
"email": "sergio@sergiohgz.eu"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-auth-memory",
|
||||
"scope": "unscoped",
|
||||
"version": "10.0.0",
|
||||
"description": "Auth plugin for Verdaccio that keeps users in memory",
|
||||
"keywords": ["verdaccio", "plugin", "auth", "memory"],
|
||||
"date": "2021-03-29T13:02:02.215Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-auth-memory",
|
||||
"homepage": "https://verdaccio.org"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com",
|
||||
"username": "jotadeveloper"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "ayusharma",
|
||||
"email": "ayush.aceit@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "generator-verdaccio-plugin",
|
||||
"scope": "unscoped",
|
||||
"version": "3.0.1",
|
||||
"description": "plugin generator for verdaccio",
|
||||
"keywords": ["verdaccio-plugin", "yeoman-generator"],
|
||||
"date": "2020-12-23T10:31:29.150Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/generator-verdaccio-plugin",
|
||||
"homepage": "https://github.com/verdaccio",
|
||||
"repository": "https://github.com/verdaccio/generator-verdaccio-plugin",
|
||||
"bugs": "https://github.com/verdaccio/generator-verdaccio-plugin/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "@jotadeveloper",
|
||||
"url": "https://github.com/verdaccio/generator-verdaccio-plugin"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "jotadeveloper",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
{
|
||||
"username": "verdaccio.npm",
|
||||
"email": "verdaccio.npm@gmail.com"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "verdaccio-minio",
|
||||
"scope": "unscoped",
|
||||
"version": "0.2.5",
|
||||
"description": "A verdaccio plugin for storing data in Minio",
|
||||
"keywords": ["Verdaccio", "S3", "Minio"],
|
||||
"date": "2020-03-16T08:49:58.248Z",
|
||||
"links": {
|
||||
"npm": "https://www.npmjs.com/package/verdaccio-minio",
|
||||
"homepage": "https://github.com/barolab/verdaccio-minio#readme",
|
||||
"repository": "https://github.com/barolab/verdaccio-minio",
|
||||
"bugs": "https://github.com/barolab/verdaccio-minio/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "Romain Bailly",
|
||||
"email": "rbailly17000@gmail.com",
|
||||
"username": "barolab"
|
||||
},
|
||||
"publisher": {
|
||||
"username": "barolab",
|
||||
"email": "rbailly17000@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"username": "barolab",
|
||||
"email": "rbailly17000@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
348
packages/proxy/test/proxy.spec.ts
Normal file
348
packages/proxy/test/proxy.spec.ts
Normal file
@@ -0,0 +1,348 @@
|
||||
import path from 'path';
|
||||
import nock from 'nock';
|
||||
import * as httpMocks from 'node-mocks-http';
|
||||
import { Config, parseConfigFile } from '@verdaccio/config';
|
||||
import { ErrorCode } from '@verdaccio/utils';
|
||||
import {
|
||||
API_ERROR,
|
||||
HEADERS,
|
||||
HEADER_TYPE,
|
||||
HTTP_STATUS,
|
||||
VerdaccioError,
|
||||
} from '@verdaccio/commons-api';
|
||||
import { ProxyStorage } from '../src/up-storage';
|
||||
|
||||
const getConf = (name) => path.join(__dirname, '/conf', name);
|
||||
|
||||
const mockDebug = jest.fn();
|
||||
const mockInfo = jest.fn();
|
||||
const mockHttp = jest.fn();
|
||||
const mockError = jest.fn();
|
||||
const mockWarn = jest.fn();
|
||||
jest.mock('@verdaccio/logger', () => {
|
||||
const originalLogger = jest.requireActual('@verdaccio/logger');
|
||||
return {
|
||||
...originalLogger,
|
||||
logger: {
|
||||
child: () => ({
|
||||
debug: (arg) => mockDebug(arg),
|
||||
info: (arg) => mockInfo(arg),
|
||||
http: (arg) => mockHttp(arg),
|
||||
error: (arg) => mockError(arg),
|
||||
warn: (arg) => mockWarn(arg),
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const domain = 'https://registry.npmjs.org';
|
||||
|
||||
describe('proxy', () => {
|
||||
beforeEach(() => {
|
||||
nock.cleanAll();
|
||||
});
|
||||
const defaultRequestOptions = {
|
||||
url: 'https://registry.npmjs.org',
|
||||
};
|
||||
const proxyPath = getConf('proxy1.yaml');
|
||||
const conf = new Config(parseConfigFile(proxyPath));
|
||||
|
||||
describe('search', () => {
|
||||
test('get file from v1 endpoint', (done) => {
|
||||
const url = '/-/v1/search';
|
||||
nock(domain).get(url).replyWithFile(200, path.join(__dirname, 'partials/search-v1.json'));
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const req = httpMocks.createRequest({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
referer: 'some.org',
|
||||
['x-forwarded-for']: '10.0.0.1',
|
||||
},
|
||||
connection: {
|
||||
remoteAddress: 'localhost',
|
||||
},
|
||||
url,
|
||||
});
|
||||
const stream = prox1.search({ req });
|
||||
stream.on('data', (data) => {
|
||||
expect(data).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('abort search from v1 endpoint', (done) => {
|
||||
const url = '/-/v1/search';
|
||||
nock(domain).get(url).delay(20000);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const req = httpMocks.createRequest({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
referer: 'some.org',
|
||||
['x-forwarded-for']: '10.0.0.1',
|
||||
},
|
||||
connection: {
|
||||
remoteAddress: 'localhost',
|
||||
},
|
||||
url,
|
||||
});
|
||||
const stream = prox1.search({ req });
|
||||
stream.on('end', () => {
|
||||
done();
|
||||
});
|
||||
// TODO: apply correct types here
|
||||
// @ts-ignore
|
||||
stream.abort();
|
||||
});
|
||||
|
||||
// TODO: we should test the gzip deflate here, but is hard to test
|
||||
// fix me if you can deal with Incorrect Header Check issue
|
||||
test.todo('get file from v1 endpoint with gzip headers');
|
||||
|
||||
test('search v1 endpoint fails', (done) => {
|
||||
const url = '/-/v1/search';
|
||||
nock(domain).get(url).replyWithError('search endpoint is down');
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const req = httpMocks.createRequest({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
referer: 'some.org',
|
||||
['x-forwarded-for']: '10.0.0.1',
|
||||
},
|
||||
connection: {
|
||||
remoteAddress: 'localhost',
|
||||
},
|
||||
url,
|
||||
});
|
||||
const stream = prox1.search({ req });
|
||||
stream.on('error', (error) => {
|
||||
expect(error).toEqual(Error('search endpoint is down'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('search v1 endpoint bad status code', (done) => {
|
||||
const url = '/-/v1/search';
|
||||
nock(domain).get(url).reply(409);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const req = httpMocks.createRequest({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
referer: 'some.org',
|
||||
['x-forwarded-for']: '10.0.0.1',
|
||||
},
|
||||
connection: {
|
||||
remoteAddress: 'localhost',
|
||||
},
|
||||
url,
|
||||
});
|
||||
const stream = prox1.search({ req });
|
||||
stream.on('error', (error) => {
|
||||
expect(error).toEqual(ErrorCode.getInternalError(`bad status code 409 from uplink`));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchTarball', () => {
|
||||
test('get file tarball no content-length', (done) => {
|
||||
nock(domain)
|
||||
.get('/jquery/-/jquery-0.0.1.tgz')
|
||||
.replyWithFile(201, path.join(__dirname, 'partials/jquery-0.0.1.tgz'));
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on('data', (data) => {
|
||||
expect(data).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('get file tarball correct content-length', (done) => {
|
||||
nock(domain)
|
||||
.get('/jquery/-/jquery-0.0.1.tgz')
|
||||
// types does not match here with documentation
|
||||
// @ts-expect-error
|
||||
.replyWithFile(201, path.join(__dirname, 'partials/jquery-0.0.1.tgz'), {
|
||||
[HEADER_TYPE.CONTENT_LENGTH]: 277,
|
||||
});
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on(HEADER_TYPE.CONTENT_LENGTH, (data) => {
|
||||
expect(data).toEqual('277');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('error handling', () => {
|
||||
test('should be offline uplink', (done) => {
|
||||
const tarball = 'https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz';
|
||||
nock(domain).get('/jquery/-/jquery-0.0.1.tgz').times(100).replyWithError('some error');
|
||||
const proxy = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = proxy.fetchTarball(tarball);
|
||||
// to test a uplink is offline we have to be try 3 times
|
||||
// the default failed request are set to 2
|
||||
process.nextTick(function () {
|
||||
stream.on('error', function (err) {
|
||||
expect(err).not.toBeNull();
|
||||
// expect(err.statusCode).toBe(404);
|
||||
expect(proxy.failed_requests).toBe(1);
|
||||
|
||||
const streamSecondTry = proxy.fetchTarball(tarball);
|
||||
streamSecondTry.on('error', function (err) {
|
||||
expect(err).not.toBeNull();
|
||||
/*
|
||||
code: 'ENOTFOUND',
|
||||
errno: 'ENOTFOUND',
|
||||
*/
|
||||
// expect(err.statusCode).toBe(404);
|
||||
expect(proxy.failed_requests).toBe(2);
|
||||
const streamThirdTry = proxy.fetchTarball(tarball);
|
||||
streamThirdTry.on('error', function (err: VerdaccioError) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toBe(HTTP_STATUS.INTERNAL_ERROR);
|
||||
expect(proxy.failed_requests).toBe(2);
|
||||
expect(err.message).toMatch(API_ERROR.UPLINK_OFFLINE);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('not found tarball', (done) => {
|
||||
nock(domain).get('/jquery/-/jquery-0.0.1.tgz').reply(404);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on('error', (response) => {
|
||||
expect(response).toEqual(ErrorCode.getNotFound(API_ERROR.NOT_FILE_UPLINK));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('fail tarball request', (done) => {
|
||||
nock(domain).get('/jquery/-/jquery-0.0.1.tgz').replyWithError('boom file');
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on('error', (response) => {
|
||||
expect(response).toEqual(Error('boom file'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('bad uplink request', (done) => {
|
||||
nock(domain).get('/jquery/-/jquery-0.0.1.tgz').reply(409);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on('error', (response) => {
|
||||
expect(response).toEqual(ErrorCode.getInternalError(`bad uplink status code: 409`));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('content length header mismatch', (done) => {
|
||||
nock(domain)
|
||||
.get('/jquery/-/jquery-0.0.1.tgz')
|
||||
// types does not match here with documentation
|
||||
// @ts-expect-error
|
||||
.replyWithFile(201, path.join(__dirname, 'partials/jquery-0.0.1.tgz'), {
|
||||
[HEADER_TYPE.CONTENT_LENGTH]: 0,
|
||||
});
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
const stream = prox1.fetchTarball('https://registry.npmjs.org/jquery/-/jquery-0.0.1.tgz');
|
||||
stream.on('error', (response) => {
|
||||
expect(response).toEqual(ErrorCode.getInternalError(API_ERROR.CONTENT_MISMATCH));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRemoteMetadata', () => {
|
||||
describe('basic requests', () => {
|
||||
test('proxy call with etag', (done) => {
|
||||
nock(domain)
|
||||
.get('/jquery')
|
||||
.reply(
|
||||
200,
|
||||
{ body: 'test' },
|
||||
{
|
||||
etag: () => `_ref_4444`,
|
||||
}
|
||||
);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', {}, (_error, body, etag) => {
|
||||
expect(etag).toEqual('_ref_4444');
|
||||
expect(body).toEqual({ body: 'test' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('proxy call with etag as option', (done) => {
|
||||
nock(domain)
|
||||
.get('/jquery')
|
||||
.reply(
|
||||
200,
|
||||
{ body: 'test' },
|
||||
{
|
||||
etag: () => `_ref_4444`,
|
||||
}
|
||||
);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', { etag: 'rev_3333' }, (_error, body, etag) => {
|
||||
expect(etag).toEqual('_ref_4444');
|
||||
expect(body).toEqual({ body: 'test' });
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('proxy not found', (done) => {
|
||||
nock(domain).get('/jquery').reply(404);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', { etag: 'rev_3333' }, (error) => {
|
||||
expect(error).toEqual(ErrorCode.getNotFound(API_ERROR.NOT_PACKAGE_UPLINK));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('error handling', () => {
|
||||
test('reply with error', (done) => {
|
||||
nock(domain).get('/jquery').replyWithError('something awful happened');
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', {}, (error) => {
|
||||
expect(error).toEqual(new Error('something awful happened'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('reply with bad body json format', (done) => {
|
||||
nock(domain).get('/jquery').reply(200, 'some-text');
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', {}, (error) => {
|
||||
expect(error).toEqual(new SyntaxError('Unexpected token s in JSON at position 0'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('400 error proxy call', (done) => {
|
||||
nock(domain).get('/jquery').reply(409);
|
||||
const prox1 = new ProxyStorage(defaultRequestOptions, conf);
|
||||
prox1.getRemoteMetadata('jquery', {}, (error) => {
|
||||
expect(error.statusCode).toEqual(500);
|
||||
expect(mockInfo).toHaveBeenCalled();
|
||||
expect(mockHttp).toHaveBeenCalledWith({
|
||||
request: { method: 'GET', url: 'https://registry.npmjs.org/jquery' },
|
||||
status: 409,
|
||||
});
|
||||
expect(mockHttp).toHaveBeenCalledWith({
|
||||
bytes: { in: 0, out: 0 },
|
||||
err: undefined,
|
||||
error: undefined,
|
||||
request: { method: 'GET', url: 'https://registry.npmjs.org/jquery' },
|
||||
status: 409,
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,19 @@
|
||||
# @verdaccio/server
|
||||
|
||||
## 6.0.0-6-next.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/api@6.0.0-6-next.12
|
||||
- @verdaccio/auth@6.0.0-6-next.9
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/middleware@6.0.0-6-next.9
|
||||
- @verdaccio/store@6.0.0-6-next.10
|
||||
- @verdaccio/web@6.0.0-6-next.15
|
||||
- @verdaccio/loaders@6.0.0-6-next.4
|
||||
|
||||
## 6.0.0-6-next.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/server",
|
||||
"version": "6.0.0-6-next.15",
|
||||
"version": "6.0.0-6-next.16",
|
||||
"description": "server logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -30,16 +30,16 @@
|
||||
"npm": ">=6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/api": "workspace:6.0.0-6-next.11",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/api": "workspace:6.0.0-6-next.12",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/web": "workspace:6.0.0-6-next.14",
|
||||
"@verdaccio/middleware": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.10",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"@verdaccio/web": "workspace:6.0.0-6-next.15",
|
||||
"verdaccio-audit": "workspace:11.0.0-alpha.4",
|
||||
"compression": "1.7.4",
|
||||
"cors": "2.8.5",
|
||||
@@ -48,8 +48,8 @@
|
||||
"lodash": "4.17.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/proxy": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/proxy": "workspace:6.0.0-6-next.9",
|
||||
"http-errors": "1.7.3",
|
||||
"request": "2.87.0"
|
||||
},
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
import path from 'path';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Config as AppConfig } from '@verdaccio/config';
|
||||
import { Config, UpLinkConf } from '@verdaccio/types';
|
||||
import { VerdaccioError } from '@verdaccio/commons-api';
|
||||
import { IProxy } from '@verdaccio/proxy';
|
||||
import { API_ERROR, HTTP_STATUS } from '@verdaccio/commons-api';
|
||||
import { mockServer, configExample, DOMAIN_SERVERS } from '@verdaccio/mock';
|
||||
import { ProxyStorage } from '@verdaccio/proxy';
|
||||
import { setup, logger } from '@verdaccio/logger';
|
||||
|
||||
setup([]);
|
||||
|
||||
describe('UpStorge', () => {
|
||||
const mockServerPort = 55547;
|
||||
let mockRegistry;
|
||||
const uplinkDefault = {
|
||||
url: `http://0.0.0.0:${mockServerPort}`,
|
||||
};
|
||||
const generateProxy = (config: UpLinkConf = uplinkDefault) => {
|
||||
const appConfig: Config = new AppConfig(configExample());
|
||||
|
||||
return new ProxyStorage(config, appConfig);
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
const binPath = require.resolve('verdaccio/bin/verdaccio');
|
||||
const storePath = path.join(__dirname, '/mock/store');
|
||||
mockRegistry = await mockServer(mockServerPort, { storePath, silence: true }).init(binPath);
|
||||
});
|
||||
|
||||
afterAll(function (done) {
|
||||
const [registry, pid] = mockRegistry;
|
||||
registry.stop();
|
||||
logger.info(`registry ${pid} has been stopped`);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
test('should be defined', () => {
|
||||
const proxy = generateProxy();
|
||||
|
||||
expect(proxy).toBeDefined();
|
||||
});
|
||||
|
||||
describe('UpStorge::getRemoteMetadata', () => {
|
||||
test('should be get remote metadata', (done) => {
|
||||
const proxy = generateProxy();
|
||||
|
||||
proxy.getRemoteMetadata('jquery', {}, (err, data, etag) => {
|
||||
expect(err).toBeNull();
|
||||
expect(_.isString(etag)).toBeTruthy();
|
||||
expect(data.name).toBe('jquery');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should be get remote metadata with etag', (done) => {
|
||||
const proxy = generateProxy();
|
||||
|
||||
proxy.getRemoteMetadata('jquery', { etag: '123456' }, (err, data, etag) => {
|
||||
expect(err).toBeNull();
|
||||
expect(_.isString(etag)).toBeTruthy();
|
||||
expect(data.name).toBe('jquery');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should be get remote metadata package does not exist', (done) => {
|
||||
const proxy = generateProxy();
|
||||
|
||||
proxy.getRemoteMetadata('@verdaccio/fake-package', { etag: '123456' }, (err) => {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
|
||||
expect(err.message).toMatch(API_ERROR.NOT_PACKAGE_UPLINK);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UpStorge::fetchTarball', () => {
|
||||
test('should fetch a tarball from uplink', (done) => {
|
||||
const proxy = generateProxy();
|
||||
const tarball = `http://${DOMAIN_SERVERS}:${mockServerPort}/jquery/-/jquery-1.5.1.tgz`;
|
||||
const stream = proxy.fetchTarball(tarball);
|
||||
|
||||
stream.on('error', function (err) {
|
||||
expect(err).toBeNull();
|
||||
done();
|
||||
});
|
||||
|
||||
stream.on('content-length', function (contentLength) {
|
||||
expect(contentLength).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should throw a 404 on fetch a tarball from uplink', (done) => {
|
||||
const proxy = generateProxy();
|
||||
const tarball = `http://${DOMAIN_SERVERS}:${mockServerPort}/jquery/-/no-exist-1.5.1.tgz`;
|
||||
const stream = proxy.fetchTarball(tarball);
|
||||
|
||||
stream.on('error', function (err: VerdaccioError) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
|
||||
expect(err.message).toMatch(API_ERROR.NOT_FILE_UPLINK);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
stream.on('content-length', function (contentLength) {
|
||||
expect(contentLength).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should be offline uplink', (done) => {
|
||||
const proxy = generateProxy();
|
||||
const tarball = 'http://404.verdaccioo.com';
|
||||
const stream = proxy.fetchTarball(tarball);
|
||||
expect(proxy.failed_requests).toBe(0);
|
||||
|
||||
// to test a uplink is offline we have to be try 3 times
|
||||
// the default failed request are set to 2
|
||||
process.nextTick(function () {
|
||||
stream.on('error', function (err) {
|
||||
expect(err).not.toBeNull();
|
||||
// expect(err.statusCode).toBe(404);
|
||||
expect(proxy.failed_requests).toBe(1);
|
||||
|
||||
const streamSecondTry = proxy.fetchTarball(tarball);
|
||||
streamSecondTry.on('error', function (err) {
|
||||
expect(err).not.toBeNull();
|
||||
/*
|
||||
code: 'ENOTFOUND',
|
||||
errno: 'ENOTFOUND',
|
||||
*/
|
||||
// expect(err.statusCode).toBe(404);
|
||||
expect(proxy.failed_requests).toBe(2);
|
||||
const streamThirdTry = proxy.fetchTarball(tarball);
|
||||
streamThirdTry.on('error', function (err: VerdaccioError) {
|
||||
expect(err).not.toBeNull();
|
||||
expect(err.statusCode).toBe(HTTP_STATUS.INTERNAL_ERROR);
|
||||
expect(proxy.failed_requests).toBe(2);
|
||||
expect(err.message).toMatch(API_ERROR.UPLINK_OFFLINE);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UpStorge::isUplinkValid', () => {
|
||||
describe('valid use cases', () => {
|
||||
const validateUpLink = (
|
||||
url: string,
|
||||
tarBallUrl = `${url}/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`
|
||||
) => {
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
return proxy.isUplinkValid(tarBallUrl);
|
||||
};
|
||||
|
||||
test('should validate tarball path against uplink', () => {
|
||||
expect(validateUpLink('https://artifactory.mydomain.com')).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#2', () => {
|
||||
expect(validateUpLink('https://artifactory.mydomain.com:443')).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#3', () => {
|
||||
expect(validateUpLink('http://localhost')).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#4', () => {
|
||||
expect(validateUpLink('http://my.domain.test')).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#5', () => {
|
||||
expect(validateUpLink('http://my.domain.test:3000')).toBe(true);
|
||||
});
|
||||
|
||||
// corner case https://github.com/verdaccio/verdaccio/issues/571
|
||||
test('should validate tarball path against uplink case#6', () => {
|
||||
// same protocol, same domain, port === 443 which is also the standard for https
|
||||
expect(
|
||||
validateUpLink(
|
||||
'https://my.domain.test',
|
||||
`https://my.domain.test:443/artifactory/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz`
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#7', () => {
|
||||
expect(validateUpLink('https://artifactory.mydomain.com:5569')).toBe(true);
|
||||
});
|
||||
|
||||
test('should validate tarball path against uplink case#8', () => {
|
||||
expect(validateUpLink('https://localhost:5539')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('invalid use cases', () => {
|
||||
test('should fails on validate tarball path against uplink', () => {
|
||||
const url = 'https://artifactory.mydomain.com';
|
||||
const tarBallUrl = 'https://localhost/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
||||
});
|
||||
|
||||
test('should fails on validate tarball path against uplink case#2', () => {
|
||||
// different domain same, same port, same protocol
|
||||
const url = 'https://domain';
|
||||
const tarBallUrl = 'https://localhost/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
||||
});
|
||||
|
||||
test('should fails on validate tarball path against uplink case#3', () => {
|
||||
// same domain, different protocol, different port
|
||||
const url = 'http://localhost:5001';
|
||||
const tarBallUrl = 'https://localhost:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
||||
});
|
||||
|
||||
test('should fails on validate tarball path against uplink case#4', () => {
|
||||
// same domain, same protocol, different port
|
||||
const url = 'https://subdomain.domain:5001';
|
||||
const tarBallUrl =
|
||||
'https://subdomain.domain:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
||||
});
|
||||
|
||||
test('should fails on validate tarball path against uplink case#5', () => {
|
||||
// different protocol, different domain, different port
|
||||
const url = 'https://subdomain.my:5001';
|
||||
const tarBallUrl = 'http://subdomain.domain:4000/api/npm/npm/pk1-juan/-/pk1-juan-1.0.7.tgz';
|
||||
const uplinkConf = { url };
|
||||
const proxy: IProxy = generateProxy(uplinkConf);
|
||||
|
||||
expect(proxy.isUplinkValid(tarBallUrl)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,20 +0,0 @@
|
||||
storage: ./storage
|
||||
plugins: ./plugins
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
security:
|
||||
api:
|
||||
jwt:
|
||||
sign:
|
||||
expiresIn: 10m
|
||||
notBefore: 0
|
||||
packages:
|
||||
'@*/*':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
'**':
|
||||
access: $authenticated
|
||||
publish: $authenticated
|
||||
logs:
|
||||
- { type: stdout, format: pretty, level: warn }
|
||||
@@ -41,8 +41,7 @@ const json = {
|
||||
_attachments: {
|
||||
'forbidden-place-1.0.6.tgz': {
|
||||
content_type: 'application/octet-stream',
|
||||
data:
|
||||
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
data: 'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
length: 512,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -41,8 +41,7 @@ const json = {
|
||||
_attachments: {
|
||||
'@scope/pk1-test-1.0.6.tgz': {
|
||||
content_type: 'application/octet-stream',
|
||||
data:
|
||||
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
data: 'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
length: 512,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"homepage": "https://verdaccio.org",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@verdaccio/cli": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/cli": "workspace:6.0.0-6-next.17",
|
||||
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.8",
|
||||
"fs-extra": "9.0.1",
|
||||
"webpack": "^5.11.1",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @verdaccio/store
|
||||
|
||||
## 6.0.0-6-next.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/config@6.0.0-6-next.7
|
||||
- @verdaccio/proxy@6.0.0-6-next.9
|
||||
- @verdaccio/loaders@6.0.0-6-next.4
|
||||
|
||||
## 6.0.0-6-next.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/store",
|
||||
"version": "6.0.0-6-next.9",
|
||||
"version": "6.0.0-6-next.10",
|
||||
"description": "loaders logic",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -40,13 +40,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/loaders": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/local-storage": "workspace:11.0.0-6-next.6",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/proxy": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/proxy": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/streams": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"async": "3.1.1",
|
||||
"debug": "^4.1.1",
|
||||
"lodash": "4.17.15",
|
||||
@@ -55,7 +55,7 @@
|
||||
"semver": "7.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/types": "workspace:11.0.0-6-next.7"
|
||||
},
|
||||
"funding": {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ProxyStorage } from '@verdaccio/proxy';
|
||||
import { API_ERROR, HTTP_STATUS, DIST_TAGS } from '@verdaccio/commons-api';
|
||||
import { ReadTarball } from '@verdaccio/streams';
|
||||
import { ErrorCode, normalizeDistTags, validateMetadata, isObject } from '@verdaccio/utils';
|
||||
import { setupUpLinks, updateVersionsHiddenUpLink, ProxyList, IProxy } from '@verdaccio/proxy';
|
||||
import { ProxyList, IProxy } from '@verdaccio/proxy';
|
||||
import {
|
||||
IReadTarball,
|
||||
IUploadTarball,
|
||||
@@ -38,6 +38,7 @@ import { SearchInstance } from './search';
|
||||
|
||||
import { LocalStorage } from './local-storage';
|
||||
import { mergeVersions } from './metadata-utils';
|
||||
import { setupUpLinks, updateVersionsHiddenUpLink } from './uplink-util';
|
||||
import {
|
||||
checkPackageLocal,
|
||||
publishPackage,
|
||||
@@ -308,6 +309,7 @@ class Storage {
|
||||
let uplink: any = null;
|
||||
|
||||
for (const uplinkId in self.uplinks) {
|
||||
// https://github.com/verdaccio/verdaccio/issues/1642
|
||||
if (hasProxyTo(name, uplinkId, self.config.packages)) {
|
||||
uplink = self.uplinks[uplinkId];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Versions, Config } from '@verdaccio/types';
|
||||
|
||||
import { ProxyStorage, IProxy, ProxyList } from './up-storage';
|
||||
import { ProxyStorage, IProxy, ProxyList } from '@verdaccio/proxy';
|
||||
|
||||
/**
|
||||
* Set up the Up Storage for each link.
|
||||
@@ -27,7 +27,6 @@ export function updateVersionsHiddenUpLink(versions: Versions, upLink: IProxy):
|
||||
const version = versions[i];
|
||||
|
||||
// holds a "hidden" value to be used by the package storage.
|
||||
// $FlowFixMe
|
||||
version[Symbol.for('__verdaccio_uplink')] = upLink.upname;
|
||||
}
|
||||
}
|
||||
20
packages/tools/eslint/package.json
Normal file
20
packages/tools/eslint/package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@verdaccio/eslint-config",
|
||||
"version": "1.0.0",
|
||||
"private": "true",
|
||||
"description": "verdaccio eslint config",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext .js"
|
||||
},
|
||||
"author": {
|
||||
"name": "Juan Picado",
|
||||
"email": "juanpicado19@gmail.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "https",
|
||||
"url": "https://github.com/verdaccio/verdaccio"
|
||||
},
|
||||
"homepage": "https://verdaccio.org",
|
||||
"license": "MIT"
|
||||
}
|
||||
27
packages/tools/eslint/src/index.js
Normal file
27
packages/tools/eslint/src/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
extends: ['./rules/base.js', './rules/prettier.js', './rules/react.js', './rules/jest.js'],
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
globals: {
|
||||
__APP_VERSION__: true,
|
||||
},
|
||||
parserOptions: {
|
||||
allowImportExportEverywhere: true,
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 11,
|
||||
ecmaFeatures: {
|
||||
impliedStrict: true,
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
},
|
||||
},
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
};
|
||||
64
packages/tools/eslint/src/rules/base.js
Normal file
64
packages/tools/eslint/src/rules/base.js
Normal file
@@ -0,0 +1,64 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'google',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/typescript',
|
||||
],
|
||||
plugins: ['import'],
|
||||
rules: {
|
||||
curly: ['error', 'all'],
|
||||
'keyword-spacing': 'off',
|
||||
'no-tabs': 'off',
|
||||
'no-useless-escape': 'off',
|
||||
'padded-blocks': 'off',
|
||||
'require-jsdoc': 'off',
|
||||
'valid-jsdoc': 'off',
|
||||
'import/order': ['error'],
|
||||
'eol-last': 'error',
|
||||
'no-irregular-whitespace': 'error',
|
||||
'no-mixed-spaces-and-tabs': ['error', 'smart-tabs'],
|
||||
'no-trailing-spaces': 'error',
|
||||
camelcase: 'off',
|
||||
'guard-for-in': 'error',
|
||||
'new-cap': 'error',
|
||||
'max-len': ['error', 100],
|
||||
'no-console': ['error', { allow: ['warn'] }],
|
||||
'no-constant-condition': 'error',
|
||||
'no-debugger': 'error',
|
||||
'no-empty': 'error',
|
||||
'no-fallthrough': 'error',
|
||||
'no-invalid-this': 'error',
|
||||
'no-new-require': 'error',
|
||||
'no-undef': 'error',
|
||||
'no-unreachable': 'error',
|
||||
'no-var': 'error',
|
||||
'one-var': 'error',
|
||||
'prefer-rest-params': 'error',
|
||||
'prefer-spread': 'error',
|
||||
'handle-callback-err': 0,
|
||||
'prefer-const': 0,
|
||||
// typescript
|
||||
'@typescript-eslint/camelcase': 0,
|
||||
'@typescript-eslint/ban-ts-ignore': 0,
|
||||
'@typescript-eslint/no-var-requires': 0,
|
||||
'@typescript-eslint/no-inferrable-types': 0,
|
||||
'@typescript-eslint/no-empty-function': 0,
|
||||
'@typescript-eslint/no-this-alias': 0,
|
||||
'@typescript-eslint/no-use-before-define': 0,
|
||||
'@typescript-eslint/array-type': ['error'],
|
||||
'@typescript-eslint/no-explicit-any': 0,
|
||||
'@typescript-eslint/indent': 0,
|
||||
'@typescript-eslint/ban-ts-comment': 0,
|
||||
'@typescript-eslint/ban-types': 0,
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0,
|
||||
// rules to fix
|
||||
'no-unused-vars': ['warn', { vars: 'all', args: 'none' }],
|
||||
'prefer-promise-reject-errors': ['warn'],
|
||||
|
||||
'@typescript-eslint/prefer-optional-chain': ['warn'],
|
||||
'@typescript-eslint/explicit-member-accessibility': ['warn'],
|
||||
'@typescript-eslint/no-unused-vars': ['warn'],
|
||||
},
|
||||
};
|
||||
19
packages/tools/eslint/src/rules/jest.js
Normal file
19
packages/tools/eslint/src/rules/jest.js
Normal file
@@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
extends: ['plugin:jest/recommended'],
|
||||
plugins: ['jest'],
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
rules: {
|
||||
'jest/no-export': 0,
|
||||
'jest/no-test-callback': 0,
|
||||
'jest/expect-expect': 0,
|
||||
'jest/no-try-expect': 0,
|
||||
'jest/no-done-callback': 'off',
|
||||
'jest/no-conditional-expect': 'off',
|
||||
// rules to fix
|
||||
'jest/no-identical-title': ['warn'],
|
||||
'jest/no-disabled-tests': ['warn'],
|
||||
'jest/no-commented-out-tests': ['warn'],
|
||||
},
|
||||
};
|
||||
4
packages/tools/eslint/src/rules/prettier.js
Normal file
4
packages/tools/eslint/src/rules/prettier.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
extends: ['plugin:prettier/recommended'],
|
||||
plugins: ['prettier'],
|
||||
};
|
||||
15
packages/tools/eslint/src/rules/react.js
vendored
Normal file
15
packages/tools/eslint/src/rules/react.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
],
|
||||
plugins: ['import'],
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
rules: {
|
||||
'react/prop-types': 0,
|
||||
},
|
||||
};
|
||||
@@ -1,5 +1,11 @@
|
||||
# @verdaccio/utils
|
||||
|
||||
## 6.0.0-6-next.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- d2c65da9: Fixed the validation of the name when searching for a tarball that have scoped package name
|
||||
|
||||
## 6.0.0-6-next.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/utils",
|
||||
"version": "6.0.0-6-next.4",
|
||||
"version": "6.0.0-6-next.5",
|
||||
"description": "verdaccio utilities",
|
||||
"main": "./build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
|
||||
@@ -25,8 +25,14 @@ export function validateName(name: string): boolean {
|
||||
if (_.isString(name) === false) {
|
||||
return false;
|
||||
}
|
||||
let normalizedName: string = name.toLowerCase();
|
||||
|
||||
const normalizedName: string = name.toLowerCase();
|
||||
const isScoped: boolean = name.startsWith('@') && name.includes('/');
|
||||
const scopedName = name.split('/', 2)[1];
|
||||
|
||||
if (isScoped && !_.isUndefined(scopedName)) {
|
||||
normalizedName = scopedName.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some context about the first regex
|
||||
|
||||
@@ -118,6 +118,7 @@ describe('Utilities', () => {
|
||||
expect(validateName('old-package@0.1.2.tgz')).toBeTruthy();
|
||||
// fix https://github.com/verdaccio/verdaccio/issues/1400
|
||||
expect(validateName('-build-infra')).toBeTruthy();
|
||||
expect(validateName('@pkg-scoped/without-extension')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should be valid using uppercase', () => {
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# verdaccio
|
||||
|
||||
## 6.0.0-6-next.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d2c65da9]
|
||||
- Updated dependencies [55ee3fdd]
|
||||
- @verdaccio/utils@6.0.0-6-next.5
|
||||
- @verdaccio/cli@6.0.0-6-next.17
|
||||
- @verdaccio/mock@6.0.0-6-next.7
|
||||
- @verdaccio/hooks@6.0.0-6-next.4
|
||||
- @verdaccio/node-api@6.0.0-6-next.17
|
||||
- @verdaccio/ui-theme@6.0.0-6-next.8
|
||||
|
||||
## 6.0.0-6-next.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "verdaccio",
|
||||
"version": "6.0.0-6-next.17",
|
||||
"version": "6.0.0-6-next.18",
|
||||
"description": "A lightweight private npm proxy registry",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
@@ -36,21 +36,21 @@
|
||||
},
|
||||
"homepage": "https://verdaccio.org",
|
||||
"dependencies": {
|
||||
"@verdaccio/cli": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/cli": "workspace:6.0.0-6-next.17",
|
||||
"@verdaccio/hooks": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/logger": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.16",
|
||||
"@verdaccio/mock": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/node-api": "workspace:6.0.0-6-next.17",
|
||||
"@verdaccio/ui-theme": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.4",
|
||||
"@verdaccio/utils": "workspace:6.0.0-6-next.5",
|
||||
"verdaccio-audit": "11.0.0-alpha.4",
|
||||
"verdaccio-htpasswd": "11.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.8",
|
||||
"@verdaccio/auth": "workspace:6.0.0-6-next.9",
|
||||
"@verdaccio/commons-api": "workspace:11.0.0-alpha.3",
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.6",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.9"
|
||||
"@verdaccio/config": "workspace:6.0.0-6-next.7",
|
||||
"@verdaccio/store": "workspace:6.0.0-6-next.10"
|
||||
},
|
||||
"keywords": [
|
||||
"private",
|
||||
|
||||
@@ -41,8 +41,7 @@ const json = {
|
||||
_attachments: {
|
||||
'forbidden-place-1.0.6.tgz': {
|
||||
content_type: 'application/octet-stream',
|
||||
data:
|
||||
'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
data: 'H4sIAAAAAAAAE+2W32vbMBDH85y/QnjQp9qxLEeBMsbGlocNBmN7bFdQ5WuqxJaEpGQdo//79KPeQsnIw5KUDX/9IOvurLuz/DHSjK/YAiY6jcXSKjk6sMqypHWNdtmD6hlBI0wqQmo8nVbVqMR4OsNoVB66kF1aW8eML+Vv10m9oF/jP6IfY4QyyTrILlD2eqkcm+gVzpdrJrPz4NuAsULJ4MZFWdBkbcByI7R79CRjx0ScCdnAvf+SkjUFWu8IubzBgXUhDPidQlfZ3BhlLpBUKDiQ1cDFrYDmKkNnZwjuhUM4808+xNVW8P2bMk1Y7vJrtLC1u1MmLPjBF40+Cc4ahV6GDmI/DWygVRpMwVX3KtXUCg7Sxp7ff3nbt6TBFy65gK1iffsN41yoEHtdFbOiisWMH8bPvXUH0SP3k+KG3UBr+DFy7OGfEJr4x5iWVeS/pLQe+D+FIv/agIWI6GX66kFuIhT+1gDjrp/4d7WAvAwEJPh0u14IufWkM0zaW2W6nLfM2lybgJ4LTJ0/jWiAK8OcMjt8MW3OlfQppcuhhQ6k+2OgkK2Q8DssFPi/IHpU9fz3/+xj5NjDf8QFE39VmE4JDfzPCBn4P4X6/f88f/Pu47zomiPk2Lv/dOv8h+P/34/D/p9CL+Kp67mrGDRo0KBBp9ZPsETQegASAAA=',
|
||||
length: 512,
|
||||
},
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user