mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-08 23:25:51 +01:00
chore: re-stablished deprecated support (#3385)
* chore: re-stablished deprecated support * chore: add e2e * chore: add more tests * chore: improve setup * chore: improve buildcache * Update e2e-ci.yml * Update e2e-ci.yml * Update e2e-ci.yml * Update e2e-ci.yml * chore: add more steps * chore: improve speed * chore: fix ci * chore: improve cache * Update ci.yml * Update registry.ts * Update ci.yml * Update ci.yml
This commit is contained in:
parent
62c24b6321
commit
a249ab7b5a
58
.github/workflows/ci.yml
vendored
58
.github/workflows/ci.yml
vendored
@ -24,12 +24,14 @@ jobs:
|
||||
image: verdaccio/verdaccio:nightly-master
|
||||
ports:
|
||||
- 4873:4873
|
||||
env:
|
||||
NODE_ENV: production
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
- name: Node
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- name: set store
|
||||
@ -51,10 +53,10 @@ jobs:
|
||||
needs: prepare
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
- name: Node
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
@ -62,7 +64,7 @@ jobs:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile --ignore-scripts
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --ignore-scripts
|
||||
- name: Lint
|
||||
run: pnpm lint
|
||||
format:
|
||||
@ -71,10 +73,10 @@ jobs:
|
||||
needs: prepare
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
- name: Use Node
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
@ -82,7 +84,7 @@ jobs:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile --ignore-scripts
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --ignore-scripts
|
||||
- name: Lint
|
||||
run: pnpm format:check
|
||||
build:
|
||||
@ -90,7 +92,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
os: [ubuntu-latest]
|
||||
node_version: [16, 18]
|
||||
name: ${{ matrix.os }} / Node ${{ matrix.node_version }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
@ -107,7 +109,7 @@ jobs:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile --ignore-scripts
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --ignore-scripts --registry http://localhost:4873
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Test
|
||||
@ -115,12 +117,12 @@ jobs:
|
||||
ci-e2e-ui:
|
||||
needs: [format, lint]
|
||||
runs-on: ubuntu-latest
|
||||
name: UI Test E2E Node 16
|
||||
name: UI Test E2E
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
@ -128,39 +130,15 @@ jobs:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --registry http://localhost:4873
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Test UI
|
||||
run: pnpm test:e2e:ui
|
||||
# env:
|
||||
# DEBUG: verdaccio:e2e*
|
||||
ci-e2e-cli:
|
||||
needs: [format, lint]
|
||||
runs-on: ubuntu-latest
|
||||
name: CLI Test E2E Node 16
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
## we need scripts, pupetter downloads aditional content
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Test CLI
|
||||
run: pnpm test:e2e:cli
|
||||
# env:
|
||||
# DEBUG: verdaccio*
|
||||
sync-translations:
|
||||
needs: [ci-e2e-cli, ci-e2e-ui]
|
||||
needs: [ci-e2e-ui]
|
||||
runs-on: ubuntu-latest
|
||||
name: synchronize translations
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'workflow_dispatch'
|
||||
@ -168,7 +146,7 @@ jobs:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
@ -177,7 +155,7 @@ jobs:
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
## we need scripts, pupetter downloads aditional content
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
run: pnpm recursive install --frozen-lockfile --registry http://localhost:4873
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: generate website translations
|
||||
|
113
.github/workflows/e2e-ci.yml
vendored
Normal file
113
.github/workflows/e2e-ci.yml
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
name: E2E CLI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- .changeset/**
|
||||
- .github/workflows/e2e-ci.yml
|
||||
- 'packages/**'
|
||||
- 'test/**'
|
||||
- 'jest/**'
|
||||
- 'package.json'
|
||||
- 'pnpm-workspace.yaml'
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-latest
|
||||
name: setup e2e verdaccio
|
||||
services:
|
||||
verdaccio:
|
||||
image: verdaccio/verdaccio:nightly-master
|
||||
ports:
|
||||
- 4873:4873
|
||||
env:
|
||||
NODE_ENV: production
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- name: set store
|
||||
run: |
|
||||
mkdir ~/.pnpm-store
|
||||
pnpm config set store-dir ~/.pnpm-store
|
||||
- name: Install
|
||||
run: pnpm recursive install --frozen-lockfile --reporter=silence --ignore-scripts --registry http://localhost:4873
|
||||
- name: Cache .pnpm-store
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-
|
||||
build:
|
||||
needs: [prepare]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- name: Use Node 16
|
||||
uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --ignore-scripts --registry http://localhost:4873
|
||||
- name: build
|
||||
run: pnpm build
|
||||
- name: Cache packages
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
id: cache-packages
|
||||
with:
|
||||
path: ./packages/
|
||||
key: pkg-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
packages-
|
||||
- name: Cache test
|
||||
uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
id: cache-test
|
||||
with:
|
||||
path: ./test/
|
||||
key: test-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
test-
|
||||
|
||||
e2e-cli:
|
||||
needs: [prepare, build]
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
pkg: [npm6, npm7, npm8, pnpm6, pnpm7, yarn1, yarn2, yarn3, yarn4]
|
||||
name: E2E / ${{ matrix.pkg }} / ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
- name: Install pnpm
|
||||
run: npm i pnpm@6.32.15 -g
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Install
|
||||
run: pnpm recursive install --offline --frozen-lockfile --reporter=silence --ignore-scripts --registry http://localhost:4873
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ./packages/
|
||||
key: pkg-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- uses: actions/cache@fd5de65bc895cf536527842281bea11763fefd77 # tag=v3
|
||||
with:
|
||||
path: ./test/
|
||||
key: test-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
- name: Test CLI
|
||||
run: NODE_ENV=production pnpm test --filter ...@verdaccio/e2e-cli-${{matrix.pkg}}
|
@ -95,22 +95,20 @@ const debug = buildDebug('verdaccio:api:publish');
|
||||
*/
|
||||
export default function publish(router: Router, auth: IAuth, storage: Storage): void {
|
||||
const can = allow(auth);
|
||||
// publish (update manifest) v6
|
||||
router.put(
|
||||
'/:package',
|
||||
can('publish'),
|
||||
media(mime.getType('json')),
|
||||
expectJson,
|
||||
publishPackageNext(storage)
|
||||
publishPackage(storage)
|
||||
);
|
||||
|
||||
// unpublish a pacakge v6
|
||||
router.put(
|
||||
'/:package/-rev/:revision',
|
||||
can('unpublish'),
|
||||
media(mime.getType('json')),
|
||||
expectJson,
|
||||
publishPackageNext(storage)
|
||||
publishPackage(storage)
|
||||
);
|
||||
|
||||
/**
|
||||
@ -121,7 +119,6 @@ export default function publish(router: Router, auth: IAuth, storage: Storage):
|
||||
* npm http fetch GET 304 http://localhost:4873/package-name?write=true 1076ms (from cache)
|
||||
* npm http fetch DELETE 201 http://localhost:4873/package-name/-rev/18-d8ebe3020bd4ac9c 22ms
|
||||
*/
|
||||
// v6
|
||||
router.delete(
|
||||
'/:package/-rev/:revision',
|
||||
can('unpublish'),
|
||||
@ -177,7 +174,7 @@ export default function publish(router: Router, auth: IAuth, storage: Storage):
|
||||
);
|
||||
}
|
||||
|
||||
export function publishPackageNext(storage: Storage): any {
|
||||
export function publishPackage(storage: Storage): any {
|
||||
return async function (
|
||||
req: $RequestExtend,
|
||||
_res: $ResponseExtend,
|
||||
|
@ -155,7 +155,7 @@ export async function initServer(
|
||||
process.exitCode = 1;
|
||||
});
|
||||
function handleShutdownGracefully() {
|
||||
logger.warn('received shutdown signal - closing server gracefully...');
|
||||
logger.info('received shutdown signal - closing server gracefully...');
|
||||
serverFactory.close(() => {
|
||||
logger.info('server closed.');
|
||||
process.exit(0);
|
||||
|
@ -4,9 +4,9 @@ module.exports = Object.assign({}, config, {
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// FIXME: increase to 90
|
||||
branches: 55,
|
||||
functions: 81,
|
||||
lines: 71,
|
||||
branches: 51,
|
||||
functions: 69,
|
||||
lines: 66,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -103,11 +103,7 @@ class Storage {
|
||||
Function changes a package info from local storage and all uplinks with write access./
|
||||
Used storages: local (write)
|
||||
*/
|
||||
public async changePackageNext(
|
||||
name: string,
|
||||
metadata: Manifest,
|
||||
revision: string
|
||||
): Promise<void> {
|
||||
public async changePackage(name: string, metadata: Manifest, revision: string): Promise<void> {
|
||||
debug('change existing package for package %o revision %o', name, revision);
|
||||
debug(`change manifest tags for %o revision %s`, name, revision);
|
||||
if (
|
||||
@ -119,7 +115,7 @@ class Storage {
|
||||
}
|
||||
|
||||
debug(`change manifest udapting manifest for %o`, name);
|
||||
await this.updatePackageNext(name, async (localData: Manifest): Promise<Manifest> => {
|
||||
await this.updatePackage(name, async (localData: Manifest): Promise<Manifest> => {
|
||||
// eslint-disable-next-line guard-for-in
|
||||
for (const version in localData.versions) {
|
||||
const incomingVersion = metadata.versions[version];
|
||||
@ -194,14 +190,11 @@ class Storage {
|
||||
throw err;
|
||||
}
|
||||
|
||||
const manifest = await this.updatePackageNext(
|
||||
name,
|
||||
async (data: Manifest): Promise<Manifest> => {
|
||||
let newData: Manifest = { ...data };
|
||||
delete data._attachments[filename];
|
||||
return newData;
|
||||
}
|
||||
);
|
||||
const manifest = await this.updatePackage(name, async (data: Manifest): Promise<Manifest> => {
|
||||
let newData: Manifest = { ...data };
|
||||
delete data._attachments[filename];
|
||||
return newData;
|
||||
});
|
||||
|
||||
try {
|
||||
const storage: IPackageStorage = this.getPrivatePackageStorage(name);
|
||||
@ -879,7 +872,7 @@ class Storage {
|
||||
* @param tags list of dist-tags
|
||||
*/
|
||||
public async mergeTagsNext(name: string, tags: MergeTags): Promise<Manifest> {
|
||||
return await this.updatePackageNext(name, async (data: Manifest): Promise<Manifest> => {
|
||||
return await this.updatePackage(name, async (data: Manifest): Promise<Manifest> => {
|
||||
let newData: Manifest = { ...data };
|
||||
for (const tag of Object.keys(tags)) {
|
||||
// this handle dist-tag rm command
|
||||
@ -922,14 +915,6 @@ class Storage {
|
||||
return uplink;
|
||||
}
|
||||
|
||||
public async updateLocalMetadata(pkgName: string) {
|
||||
const storage = this.getPrivatePackageStorage(pkgName);
|
||||
|
||||
if (!storage) {
|
||||
throw errorUtils.getNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
public async updateManifest(manifest: Manifest, options: UpdateManifestOptions): Promise<void> {
|
||||
if (isDeprecatedManifest(manifest)) {
|
||||
// if the manifest is deprecated, we need to update the package.json
|
||||
@ -968,14 +953,10 @@ class Storage {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
private async deprecate(_body: Manifest, _options: PublishOptions): Promise<void> {
|
||||
// // const storage: IPackageStorage = this.getPrivatePackageStorage(opname);
|
||||
|
||||
// if (typeof storage === 'undefined') {
|
||||
// throw errorUtils.getNotFound();
|
||||
// }
|
||||
throw errorUtils.getInternalError('no implementation ready for npm deprecate');
|
||||
private async deprecate(manifest: Manifest, options: UpdateManifestOptions): Promise<void> {
|
||||
const { name } = manifest;
|
||||
debug('deprecating %s', name);
|
||||
return this.changePackage(name, manifest, options.revision as string);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
@ -1253,7 +1234,7 @@ class Storage {
|
||||
try {
|
||||
debug('uploaded tarball %o for %o', filename, pkgName);
|
||||
// update the package metadata
|
||||
await this.updatePackageNext(pkgName, async (data: Manifest): Promise<Manifest> => {
|
||||
await this.updatePackage(pkgName, async (data: Manifest): Promise<Manifest> => {
|
||||
const newData: Manifest = { ...data };
|
||||
debug('added _attachment for %o', pkgName);
|
||||
newData._attachments[filename] = {
|
||||
@ -1301,7 +1282,7 @@ class Storage {
|
||||
tag: StringValue
|
||||
): Promise<void> {
|
||||
debug(`add version %s package for %s`, version, name);
|
||||
await this.updatePackageNext(name, async (data: Manifest): Promise<Manifest> => {
|
||||
await this.updatePackage(name, async (data: Manifest): Promise<Manifest> => {
|
||||
// keep only one readme per package
|
||||
data.readme = metadata.readme;
|
||||
debug('%s` readme mutated', name);
|
||||
@ -1460,13 +1441,15 @@ class Storage {
|
||||
|
||||
// this is intended in debug mode we do not want modify the store revision
|
||||
if (_.isNil(this.config._debug)) {
|
||||
const prev = json._rev;
|
||||
json._rev = generateRevision(json._rev);
|
||||
debug('revision metadata for %s updated from %s to %s', json.name, prev, json._rev);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
private async writePackageNext(name: string, json: Manifest): Promise<void> {
|
||||
private async writePackage(name: string, json: Manifest): Promise<void> {
|
||||
const storage: any = this.getPrivatePackageStorage(name);
|
||||
if (_.isNil(storage)) {
|
||||
// TODO: replace here 500 error
|
||||
@ -1481,7 +1464,7 @@ class Storage {
|
||||
* @param {*} callback callback that gets invoked after it's all updated
|
||||
* @return {Function}
|
||||
*/
|
||||
private async updatePackageNext(
|
||||
private async updatePackage(
|
||||
name: string,
|
||||
updateHandler: (manifest: Manifest) => Promise<Manifest>
|
||||
): Promise<Manifest> {
|
||||
@ -1495,7 +1478,7 @@ class Storage {
|
||||
const updatedManifest: Manifest = await storage.updatePackage(name, updateHandler);
|
||||
// after correctly updated write to the storage
|
||||
try {
|
||||
await this.writePackageNext(name, normalizePackage(updatedManifest));
|
||||
await this.writePackage(name, normalizePackage(updatedManifest));
|
||||
return updatedManifest;
|
||||
} catch (err: any) {
|
||||
if (err.code === resourceNotAvailable) {
|
||||
@ -1913,7 +1896,7 @@ class Storage {
|
||||
|
||||
if (change) {
|
||||
debug('updating package info %o', name);
|
||||
await this.writePackageNext(name, cacheManifest);
|
||||
await this.writePackage(name, cacheManifest);
|
||||
return cacheManifest;
|
||||
} else {
|
||||
return cacheManifest;
|
||||
|
15
packages/store/test/fixtures/config/deprecate.yaml
vendored
Normal file
15
packages/store/test/fixtures/config/deprecate.yaml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
packages:
|
||||
'@scope/foo':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: ver
|
||||
'foo':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
'*':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
@ -14,8 +14,9 @@ import {
|
||||
generateLocalPackageMetadata,
|
||||
generatePackageMetadata,
|
||||
generateRemotePackageMetadata,
|
||||
getDeprecatedPackageMetadata,
|
||||
} from '@verdaccio/test-helper';
|
||||
import { AbbreviatedManifest, Manifest, Version } from '@verdaccio/types';
|
||||
import { AbbreviatedManifest, ConfigYaml, Manifest, Version } from '@verdaccio/types';
|
||||
|
||||
import { Storage } from '../src';
|
||||
import manifestFooRemoteNpmjs from './fixtures/manifests/foo-npmjs.json';
|
||||
@ -34,6 +35,27 @@ const domain = 'https://registry.npmjs.org';
|
||||
const fakeHost = 'localhost:4873';
|
||||
const fooManifest = generatePackageMetadata('foo', '1.0.0');
|
||||
|
||||
const getConfig = (file, override: Partial<ConfigYaml> = {}): Config => {
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
...getDefaultConfig(),
|
||||
storage: generateRandomStorage(),
|
||||
...override,
|
||||
},
|
||||
`./fixtures/config/${file}`,
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
return config;
|
||||
};
|
||||
|
||||
const defaultRequestOptions = {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
};
|
||||
|
||||
describe('storage', () => {
|
||||
beforeEach(() => {
|
||||
nock.cleanAll();
|
||||
@ -42,79 +64,95 @@ describe('storage', () => {
|
||||
});
|
||||
|
||||
describe('updateManifest', () => {
|
||||
test('create private package', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const pkgName = 'upstream';
|
||||
const requestOptions = {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
};
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
...getDefaultConfig(),
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions,
|
||||
});
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest._id).toEqual(pkgName);
|
||||
expect(Object.keys(manifest.versions)).toEqual(['1.0.0']);
|
||||
expect(manifest.time).toEqual({
|
||||
'1.0.0': mockDate,
|
||||
created: mockDate,
|
||||
modified: mockDate,
|
||||
});
|
||||
expect(manifest[DIST_TAGS]).toEqual({ latest: '1.0.0' });
|
||||
expect(manifest.readme).toEqual('# test');
|
||||
expect(manifest._attachments).toEqual({});
|
||||
expect(typeof manifest._rev).toBeTruthy();
|
||||
});
|
||||
|
||||
// TODO: Review triggerUncaughtException exception on abort
|
||||
test.skip('abort creating a private package', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const pkgName = 'upstream';
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const ac = new AbortController();
|
||||
setTimeout(() => {
|
||||
ac.abort();
|
||||
}, 10);
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await expect(
|
||||
storage.updateManifest(bodyNewManifest, {
|
||||
signal: ac.signal,
|
||||
describe('publishing', () => {
|
||||
test('create private package', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const pkgName = 'upstream';
|
||||
const requestOptions = {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
};
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
...getDefaultConfig(),
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions,
|
||||
});
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest._id).toEqual(pkgName);
|
||||
expect(Object.keys(manifest.versions)).toEqual(['1.0.0']);
|
||||
expect(manifest.time).toEqual({
|
||||
'1.0.0': mockDate,
|
||||
created: mockDate,
|
||||
modified: mockDate,
|
||||
});
|
||||
expect(manifest[DIST_TAGS]).toEqual({ latest: '1.0.0' });
|
||||
expect(manifest.readme).toEqual('# test');
|
||||
expect(manifest._attachments).toEqual({});
|
||||
expect(typeof manifest._rev).toBeTruthy();
|
||||
});
|
||||
|
||||
// TODO: Review triggerUncaughtException exception on abort
|
||||
test.skip('abort creating a private package', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const pkgName = 'upstream';
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const ac = new AbortController();
|
||||
setTimeout(() => {
|
||||
ac.abort();
|
||||
}, 10);
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await expect(
|
||||
storage.updateManifest(bodyNewManifest, {
|
||||
signal: ac.signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})
|
||||
).rejects.toThrow('should throw here');
|
||||
});
|
||||
|
||||
test('create private package with multiple consecutive versions', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const settings = {
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: {
|
||||
@ -122,136 +160,245 @@ describe('storage', () => {
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})
|
||||
).rejects.toThrow('should throw here');
|
||||
});
|
||||
|
||||
test('create private package with multiple consecutive versions', async () => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const settings = {
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
const pkgName = 'upstream';
|
||||
// const storage = generateRandomStorage();
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: await fileUtils.createTempStorageFolder('storage-test'),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
// create a package
|
||||
const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest1, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
});
|
||||
// publish second version
|
||||
const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.1');
|
||||
await storage.updateManifest(bodyNewManifest2, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
});
|
||||
// retrieve package metadata
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest._id).toEqual(pkgName);
|
||||
expect(Object.keys(manifest.versions)).toEqual(['1.0.0', '1.0.1']);
|
||||
expect(manifest.time).toEqual({
|
||||
'1.0.0': mockDate,
|
||||
'1.0.1': mockDate,
|
||||
created: mockDate,
|
||||
modified: mockDate,
|
||||
});
|
||||
expect(manifest[DIST_TAGS]).toEqual({ latest: '1.0.1' });
|
||||
expect(manifest.readme).toEqual('# test');
|
||||
expect(manifest._attachments).toEqual({});
|
||||
expect(typeof manifest._rev).toBeTruthy();
|
||||
// verify the version structure is correct
|
||||
const manifestVersion = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
version: '1.0.1',
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})) as Version;
|
||||
expect(manifestVersion.name).toEqual(pkgName);
|
||||
expect(manifestVersion.version).toEqual('1.0.1');
|
||||
expect(manifestVersion._id).toEqual(`${pkgName}@1.0.1`);
|
||||
expect(manifestVersion.description).toEqual('package generated');
|
||||
expect(manifestVersion.dist).toEqual({
|
||||
integrity:
|
||||
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
|
||||
shasum: '2c03764f651a9f016ca0b7620421457b619151b9',
|
||||
tarball: 'http://localhost:5555/upstream/-/upstream-1.0.1.tgz',
|
||||
});
|
||||
|
||||
expect(manifestVersion.contributors).toEqual([]);
|
||||
expect(manifestVersion.main).toEqual('index.js');
|
||||
expect(manifestVersion.author).toEqual({ name: 'User NPM', email: 'user@domain.com' });
|
||||
expect(manifestVersion.dependencies).toEqual({ verdaccio: '^2.7.2' });
|
||||
});
|
||||
|
||||
test('fails if version already exist', async () => {
|
||||
const settings = {
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
const pkgName = 'upstream';
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/getTarballNext-getupstream.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest1, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
});
|
||||
await expect(
|
||||
storage.updateManifest(bodyNewManifest2, {
|
||||
};
|
||||
const pkgName = 'upstream';
|
||||
// const storage = generateRandomStorage();
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: await fileUtils.createTempStorageFolder('storage-test'),
|
||||
},
|
||||
'./fixtures/config/updateManifest-1.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
// create a package
|
||||
const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest1, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
})
|
||||
).rejects.toThrow(API_ERROR.PACKAGE_EXIST);
|
||||
});
|
||||
// publish second version
|
||||
const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.1');
|
||||
await storage.updateManifest(bodyNewManifest2, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
});
|
||||
// retrieve package metadata
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest._id).toEqual(pkgName);
|
||||
expect(Object.keys(manifest.versions)).toEqual(['1.0.0', '1.0.1']);
|
||||
expect(manifest.time).toEqual({
|
||||
'1.0.0': mockDate,
|
||||
'1.0.1': mockDate,
|
||||
created: mockDate,
|
||||
modified: mockDate,
|
||||
});
|
||||
expect(manifest[DIST_TAGS]).toEqual({ latest: '1.0.1' });
|
||||
expect(manifest.readme).toEqual('# test');
|
||||
expect(manifest._attachments).toEqual({});
|
||||
expect(typeof manifest._rev).toBeTruthy();
|
||||
// verify the version structure is correct
|
||||
const manifestVersion = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
version: '1.0.1',
|
||||
uplinksLook: true,
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
})) as Version;
|
||||
expect(manifestVersion.name).toEqual(pkgName);
|
||||
expect(manifestVersion.version).toEqual('1.0.1');
|
||||
expect(manifestVersion._id).toEqual(`${pkgName}@1.0.1`);
|
||||
expect(manifestVersion.description).toEqual('package generated');
|
||||
expect(manifestVersion.dist).toEqual({
|
||||
integrity:
|
||||
'sha512-6gHiERpiDgtb3hjqpQH5/i7zRmvYi9pmCjQf2ZMy3QEa9wVk9RgdZaPWUt7ZOnWUPFjcr9cmE6dUBf+XoPoH4g==',
|
||||
shasum: '2c03764f651a9f016ca0b7620421457b619151b9',
|
||||
tarball: 'http://localhost:5555/upstream/-/upstream-1.0.1.tgz',
|
||||
});
|
||||
|
||||
expect(manifestVersion.contributors).toEqual([]);
|
||||
expect(manifestVersion.main).toEqual('index.js');
|
||||
expect(manifestVersion.author).toEqual({ name: 'User NPM', email: 'user@domain.com' });
|
||||
expect(manifestVersion.dependencies).toEqual({ verdaccio: '^2.7.2' });
|
||||
});
|
||||
|
||||
test('fails if version already exist', async () => {
|
||||
const settings = {
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: {
|
||||
host: 'localhost',
|
||||
protocol: 'http',
|
||||
headers: {},
|
||||
},
|
||||
};
|
||||
const pkgName = 'upstream';
|
||||
const config = new Config(
|
||||
configExample(
|
||||
{
|
||||
storage: generateRandomStorage(),
|
||||
},
|
||||
'./fixtures/config/getTarballNext-getupstream.yaml',
|
||||
__dirname
|
||||
)
|
||||
);
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const bodyNewManifest1 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
const bodyNewManifest2 = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest1, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
});
|
||||
await expect(
|
||||
storage.updateManifest(bodyNewManifest2, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
...settings,
|
||||
})
|
||||
).rejects.toThrow(API_ERROR.PACKAGE_EXIST);
|
||||
});
|
||||
});
|
||||
describe('deprecate', () => {
|
||||
test.each([['foo'], ['@scope/foo']])('deprecate package %s', async (pkgName) => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const config = getConfig('deprecate.yaml');
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: defaultRequestOptions,
|
||||
});
|
||||
const manifest1 = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: defaultRequestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest1.versions['1.0.0'].deprecated).toBeUndefined();
|
||||
|
||||
const deprecatedManifest = getDeprecatedPackageMetadata(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
{
|
||||
['latest']: '1.0.0',
|
||||
},
|
||||
'some deprecation message',
|
||||
manifest1._rev
|
||||
);
|
||||
await storage.updateManifest(deprecatedManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: defaultRequestOptions,
|
||||
});
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: defaultRequestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest.versions['1.0.0'].deprecated).toEqual('some deprecation message');
|
||||
// important revision is updated
|
||||
expect(manifest._rev !== deprecatedManifest._rev).toBeTruthy();
|
||||
});
|
||||
test.each([['foo'], ['@scope/foo']])('undeprecate package %s', async (pkgName) => {
|
||||
const mockDate = '2018-01-14T11:17:40.712Z';
|
||||
MockDate.set(mockDate);
|
||||
const config = getConfig('deprecate.yaml');
|
||||
const storage = new Storage(config);
|
||||
await storage.init(config);
|
||||
// publish new package
|
||||
const bodyNewManifest = generatePackageMetadata(pkgName, '1.0.0');
|
||||
await storage.updateManifest(bodyNewManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: defaultRequestOptions,
|
||||
});
|
||||
|
||||
// verify not deprecated
|
||||
const manifest1 = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: defaultRequestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest1.versions['1.0.0'].deprecated).toBeUndefined();
|
||||
|
||||
// deprecate version
|
||||
const deprecatedManifest = getDeprecatedPackageMetadata(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
{
|
||||
['latest']: '1.0.0',
|
||||
},
|
||||
'some deprecation message',
|
||||
manifest1._rev
|
||||
);
|
||||
await storage.updateManifest(deprecatedManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: defaultRequestOptions,
|
||||
});
|
||||
const manifest = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: defaultRequestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest.name).toEqual(pkgName);
|
||||
expect(manifest.versions['1.0.0'].deprecated).toEqual('some deprecation message');
|
||||
// important revision is updated
|
||||
expect(manifest._rev !== deprecatedManifest._rev).toBeTruthy();
|
||||
|
||||
// un deprecated the previous deprecated
|
||||
const undeprecatedManifest = {
|
||||
...manifest,
|
||||
};
|
||||
undeprecatedManifest.versions['1.0.0'].deprecated = '';
|
||||
await storage.updateManifest(undeprecatedManifest, {
|
||||
signal: new AbortController().signal,
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
revision: '1',
|
||||
requestOptions: defaultRequestOptions,
|
||||
});
|
||||
|
||||
const manifest3 = (await storage.getPackageByOptions({
|
||||
name: pkgName,
|
||||
uplinksLook: true,
|
||||
requestOptions: defaultRequestOptions,
|
||||
})) as Manifest;
|
||||
expect(manifest3.name).toEqual(pkgName);
|
||||
expect(manifest3.versions['1.0.0'].deprecated).toBeUndefined();
|
||||
// important revision is updated
|
||||
expect(manifest3._rev !== deprecatedManifest._rev).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -724,7 +871,7 @@ describe('storage', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLocalDatabaseNext', () => {
|
||||
describe('getLocalDatabase', () => {
|
||||
test('should return 0 local packages', async () => {
|
||||
const config = new Config(
|
||||
configExample({
|
||||
@ -902,7 +1049,7 @@ describe('storage', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('get packages getPackageByOptions()', () => {
|
||||
describe('getPackageByOptions()', () => {
|
||||
describe('with uplinks', () => {
|
||||
test('should get 201 and merge from uplink', async () => {
|
||||
nock(domain).get('/foo').reply(201, fooManifest);
|
||||
|
@ -4,7 +4,7 @@ module.exports = Object.assign({}, config, {
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
// FIXME: increase to 90
|
||||
lines: 48,
|
||||
lines: 40,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -217,6 +217,21 @@ export function generateRemotePackageMetadata(
|
||||
};
|
||||
}
|
||||
|
||||
export function getDeprecatedPackageMetadata(
|
||||
pkgName: string,
|
||||
version = '1.0.0',
|
||||
distTags: DistTags = { ['latest']: version },
|
||||
deprecated = 'default deprecated message',
|
||||
rev = 'rev-foo'
|
||||
): Manifest {
|
||||
const manifest = generatePackageMetadata(pkgName, version, distTags);
|
||||
// deprecated message requires empty attachments
|
||||
manifest._attachments = {};
|
||||
manifest._rev = rev;
|
||||
manifest.versions[version].deprecated = deprecated;
|
||||
return manifest;
|
||||
}
|
||||
|
||||
export function generatePackageMetadata(
|
||||
pkgName: string,
|
||||
version = '1.0.0',
|
||||
|
@ -3,6 +3,7 @@ export {
|
||||
addNewVersion,
|
||||
generateLocalPackageMetadata,
|
||||
generateRemotePackageMetadata,
|
||||
getDeprecatedPackageMetadata,
|
||||
} from './generatePackageMetadata';
|
||||
export { generatePublishNewVersionManifest } from './generatePublishNewVersionManifest';
|
||||
export { initializeServer } from './initializeServer';
|
||||
|
@ -7,12 +7,17 @@
|
||||
|
||||
### Commands Tested
|
||||
|
||||
| cmd | npm6 | npm7 | npm8 | pnpm6 | pnpm7 | yarn1 | yarn2 | yarn3 | yarn4 |
|
||||
| ------- | ---- | ---- | ---- | ----- | ----- | ----- | ----- | ----- | ----- |
|
||||
| publish | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||
| info | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| audit | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| install | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| cmd | npm6 | npm7 | npm8 | pnpm6 | pnpm7 | yarn1 | yarn2 | yarn3 | yarn4 |
|
||||
| --------- | ---- | ---- | ---- | ----- | ----- | ----- | ----- | ----- | ----- |
|
||||
| publish | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||
| info | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| audit | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| install | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| deprecate | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
||||
|
||||
❌ = no tested
|
||||
✅ = tested
|
||||
⛔ = no supported
|
||||
|
||||
## How it works?
|
||||
|
||||
|
@ -21,7 +21,7 @@ export async function exec(options: SpawnOptions, cmd, args): Promise<ExecOutput
|
||||
const spawnOptions = {
|
||||
cwd: options.cwd,
|
||||
stdio: options.stdio || 'pipe',
|
||||
...(env ? { env } : {}),
|
||||
env: process.env,
|
||||
};
|
||||
|
||||
if (process.platform.startsWith('win')) {
|
||||
|
@ -12,9 +12,24 @@ export type Setup = {
|
||||
tempFolder: string;
|
||||
};
|
||||
|
||||
const log =
|
||||
process.env.NODE_ENV === 'production'
|
||||
? { type: 'stdout', format: 'json', level: 'warn' }
|
||||
: { type: 'stdout', format: 'pretty', level: 'warn' };
|
||||
const defaultConfig = {
|
||||
...getDefaultConfig(),
|
||||
log,
|
||||
};
|
||||
|
||||
export async function initialSetup(customConfig?: ConfigYaml): Promise<Setup> {
|
||||
// @ts-ignore
|
||||
const { configPath, tempFolder } = await Registry.fromConfigToPath({
|
||||
...(customConfig ? customConfig : { ...getDefaultConfig(), _debug: true }),
|
||||
...(customConfig
|
||||
? customConfig
|
||||
: {
|
||||
...defaultConfig,
|
||||
_debug: true,
|
||||
}),
|
||||
});
|
||||
debug(`configPath %o`, configPath);
|
||||
debug(`tempFolder %o`, tempFolder);
|
||||
|
137
test/cli/e2e-npm6/deprecate.spec.ts
Normal file
137
test/cli/e2e-npm6/deprecate.spec.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdaccio/test-cli-commons';
|
||||
|
||||
import { npm } from './utils';
|
||||
|
||||
describe('deprecate a package', () => {
|
||||
jest.setTimeout(15000);
|
||||
let registry;
|
||||
|
||||
async function bumbUp(tempFolder, registry) {
|
||||
await npm({ cwd: tempFolder }, 'version', 'minor', ...addRegistry(registry.getRegistryUrl()));
|
||||
}
|
||||
|
||||
async function publish(tempFolder, pkgName, registry) {
|
||||
const resp = await npm(
|
||||
{ cwd: tempFolder },
|
||||
'publish',
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual(pkgName);
|
||||
}
|
||||
|
||||
async function deprecate(tempFolder, packageVersion, registry, message) {
|
||||
await npm(
|
||||
{ cwd: tempFolder },
|
||||
'deprecate',
|
||||
packageVersion,
|
||||
message,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
}
|
||||
|
||||
async function getInfoVersions(pkgName, registry) {
|
||||
const infoResp = await npm(
|
||||
{},
|
||||
'info',
|
||||
pkgName,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const infoBody = JSON.parse(infoResp.stdout as string);
|
||||
return infoBody;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const setup = await initialSetup();
|
||||
registry = setup.registry;
|
||||
await registry.init();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-1']])(
|
||||
'should deprecate a single package %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.name).toEqual(pkgName);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['@verdaccio/deprecated-2']])('should un-deprecate a package %s', async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
// empty string is same as undeprecate
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, '');
|
||||
const infoBody2 = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody2.deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-3']])(
|
||||
'should deprecate a multiple packages %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
// publish 1.0.0
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.1.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.2.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.3.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// // deprecate all version
|
||||
await deprecate(tempFolder, pkgName, registry, message);
|
||||
// verify is deprecated
|
||||
for (let v of ['1.0.0', '1.1.0', '1.2.0', '1.3.0']) {
|
||||
const infoResp = await getInfoVersions(`${pkgName}@${v}`, registry);
|
||||
expect(infoResp.deprecated).toEqual(message);
|
||||
}
|
||||
// publish normal version
|
||||
// publish 1.4.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
const infoResp = await getInfoVersions(`${pkgName}@1.4.0`, registry);
|
||||
// must be not deprecated
|
||||
expect(infoResp.deprecated).toBeUndefined();
|
||||
}
|
||||
);
|
||||
|
||||
afterAll(async () => {
|
||||
registry.stop();
|
||||
});
|
||||
});
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
@ -2,7 +2,7 @@ import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdacci
|
||||
|
||||
import { npm } from './utils';
|
||||
|
||||
describe('install a package', () => {
|
||||
describe('publish a package', () => {
|
||||
jest.setTimeout(10000);
|
||||
let registry;
|
||||
|
||||
|
137
test/cli/e2e-npm7/deprecate.spec.ts
Normal file
137
test/cli/e2e-npm7/deprecate.spec.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdaccio/test-cli-commons';
|
||||
|
||||
import { npm } from './utils';
|
||||
|
||||
describe('deprecate a package', () => {
|
||||
jest.setTimeout(15000);
|
||||
let registry;
|
||||
|
||||
async function bumbUp(tempFolder, registry) {
|
||||
await npm({ cwd: tempFolder }, 'version', 'minor', ...addRegistry(registry.getRegistryUrl()));
|
||||
}
|
||||
|
||||
async function publish(tempFolder, pkgName, registry) {
|
||||
const resp = await npm(
|
||||
{ cwd: tempFolder },
|
||||
'publish',
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual(pkgName);
|
||||
}
|
||||
|
||||
async function deprecate(tempFolder, packageVersion, registry, message) {
|
||||
await npm(
|
||||
{ cwd: tempFolder },
|
||||
'deprecate',
|
||||
packageVersion,
|
||||
message,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
}
|
||||
|
||||
async function getInfoVersions(pkgName, registry) {
|
||||
const infoResp = await npm(
|
||||
{},
|
||||
'info',
|
||||
pkgName,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const infoBody = JSON.parse(infoResp.stdout as string);
|
||||
return infoBody;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const setup = await initialSetup();
|
||||
registry = setup.registry;
|
||||
await registry.init();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-1']])(
|
||||
'should deprecate a single package %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.name).toEqual(pkgName);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['@verdaccio/deprecated-2']])('should un-deprecate a package %s', async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
// empty string is same as undeprecate
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, '');
|
||||
const infoBody2 = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody2.deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-3']])(
|
||||
'should deprecate a multiple packages %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
// publish 1.0.0
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.1.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.2.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.3.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// // deprecate all version
|
||||
await deprecate(tempFolder, pkgName, registry, message);
|
||||
// verify is deprecated
|
||||
for (let v of ['1.0.0', '1.1.0', '1.2.0', '1.3.0']) {
|
||||
const infoResp = await getInfoVersions(`${pkgName}@${v}`, registry);
|
||||
expect(infoResp.deprecated).toEqual(message);
|
||||
}
|
||||
// publish normal version
|
||||
// publish 1.4.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
const infoResp = await getInfoVersions(`${pkgName}@1.4.0`, registry);
|
||||
// must be not deprecated
|
||||
expect(infoResp.deprecated).toBeUndefined();
|
||||
}
|
||||
);
|
||||
|
||||
afterAll(async () => {
|
||||
registry.stop();
|
||||
});
|
||||
});
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
137
test/cli/e2e-npm8/deprecate.spec.ts
Normal file
137
test/cli/e2e-npm8/deprecate.spec.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdaccio/test-cli-commons';
|
||||
|
||||
import { npm } from './utils';
|
||||
|
||||
describe('deprecate a package', () => {
|
||||
jest.setTimeout(15000);
|
||||
let registry;
|
||||
|
||||
async function bumbUp(tempFolder, registry) {
|
||||
await npm({ cwd: tempFolder }, 'version', 'minor', ...addRegistry(registry.getRegistryUrl()));
|
||||
}
|
||||
|
||||
async function publish(tempFolder, pkgName, registry) {
|
||||
const resp = await npm(
|
||||
{ cwd: tempFolder },
|
||||
'publish',
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual(pkgName);
|
||||
}
|
||||
|
||||
async function deprecate(tempFolder, packageVersion, registry, message) {
|
||||
await npm(
|
||||
{ cwd: tempFolder },
|
||||
'deprecate',
|
||||
packageVersion,
|
||||
message,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
}
|
||||
|
||||
async function getInfoVersions(pkgName, registry) {
|
||||
const infoResp = await npm(
|
||||
{},
|
||||
'info',
|
||||
pkgName,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const infoBody = JSON.parse(infoResp.stdout as string);
|
||||
return infoBody;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const setup = await initialSetup();
|
||||
registry = setup.registry;
|
||||
await registry.init();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-1']])(
|
||||
'should deprecate a single package %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.name).toEqual(pkgName);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['@verdaccio/deprecated-2']])('should un-deprecate a package %s', async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
// empty string is same as undeprecate
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, '');
|
||||
const infoBody2 = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody2.deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-3']])(
|
||||
'should deprecate a multiple packages %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
// publish 1.0.0
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.1.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.2.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.3.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// // deprecate all version
|
||||
await deprecate(tempFolder, pkgName, registry, message);
|
||||
// verify is deprecated
|
||||
for (let v of ['1.0.0', '1.1.0', '1.2.0', '1.3.0']) {
|
||||
const infoResp = await getInfoVersions(`${pkgName}@${v}`, registry);
|
||||
expect(infoResp.deprecated).toEqual(message);
|
||||
}
|
||||
// publish normal version
|
||||
// publish 1.4.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
const infoResp = await getInfoVersions(`${pkgName}@1.4.0`, registry);
|
||||
// must be not deprecated
|
||||
expect(infoResp.deprecated).toBeUndefined();
|
||||
}
|
||||
);
|
||||
|
||||
afterAll(async () => {
|
||||
registry.stop();
|
||||
});
|
||||
});
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
137
test/cli/e2e-pnpm6/deprecate.spec.ts
Normal file
137
test/cli/e2e-pnpm6/deprecate.spec.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdaccio/test-cli-commons';
|
||||
|
||||
import { pnpm } from './utils';
|
||||
|
||||
describe('deprecate a package', () => {
|
||||
jest.setTimeout(15000);
|
||||
let registry;
|
||||
|
||||
async function bumbUp(tempFolder, registry) {
|
||||
await pnpm({ cwd: tempFolder }, 'version', 'minor', ...addRegistry(registry.getRegistryUrl()));
|
||||
}
|
||||
|
||||
async function publish(tempFolder, pkgName, registry) {
|
||||
const resp = await pnpm(
|
||||
{ cwd: tempFolder },
|
||||
'publish',
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual(pkgName);
|
||||
}
|
||||
|
||||
async function deprecate(tempFolder, packageVersion, registry, message) {
|
||||
await pnpm(
|
||||
{ cwd: tempFolder },
|
||||
'deprecate',
|
||||
packageVersion,
|
||||
message,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
}
|
||||
|
||||
async function getInfoVersions(pkgName, registry) {
|
||||
const infoResp = await pnpm(
|
||||
{},
|
||||
'info',
|
||||
pkgName,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const infoBody = JSON.parse(infoResp.stdout as string);
|
||||
return infoBody;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const setup = await initialSetup();
|
||||
registry = setup.registry;
|
||||
await registry.init();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-1']])(
|
||||
'should deprecate a single package %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.name).toEqual(pkgName);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['@verdaccio/deprecated-2']])('should un-deprecate a package %s', async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
// empty string is same as undeprecate
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, '');
|
||||
const infoBody2 = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody2.deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-3']])(
|
||||
'should deprecate a multiple packages %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
// publish 1.0.0
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.1.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.2.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.3.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// // deprecate all version
|
||||
await deprecate(tempFolder, pkgName, registry, message);
|
||||
// verify is deprecated
|
||||
for (let v of ['1.0.0', '1.1.0', '1.2.0', '1.3.0']) {
|
||||
const infoResp = await getInfoVersions(`${pkgName}@${v}`, registry);
|
||||
expect(infoResp.deprecated).toEqual(message);
|
||||
}
|
||||
// publish normal version
|
||||
// publish 1.4.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
const infoResp = await getInfoVersions(`${pkgName}@1.4.0`, registry);
|
||||
// must be not deprecated
|
||||
expect(infoResp.deprecated).toBeUndefined();
|
||||
}
|
||||
);
|
||||
|
||||
afterAll(async () => {
|
||||
registry.stop();
|
||||
});
|
||||
});
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
137
test/cli/e2e-pnpm7/deprecate.spec.ts
Normal file
137
test/cli/e2e-pnpm7/deprecate.spec.ts
Normal file
@ -0,0 +1,137 @@
|
||||
import { addRegistry, initialSetup, prepareGenericEmptyProject } from '@verdaccio/test-cli-commons';
|
||||
|
||||
import { pnpm } from './utils';
|
||||
|
||||
describe('deprecate a package', () => {
|
||||
jest.setTimeout(15000);
|
||||
let registry;
|
||||
|
||||
async function bumbUp(tempFolder, registry) {
|
||||
await pnpm({ cwd: tempFolder }, 'version', 'minor', ...addRegistry(registry.getRegistryUrl()));
|
||||
}
|
||||
|
||||
async function publish(tempFolder, pkgName, registry) {
|
||||
const resp = await pnpm(
|
||||
{ cwd: tempFolder },
|
||||
'publish',
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual(pkgName);
|
||||
}
|
||||
|
||||
async function deprecate(tempFolder, packageVersion, registry, message) {
|
||||
await pnpm(
|
||||
{ cwd: tempFolder },
|
||||
'deprecate',
|
||||
packageVersion,
|
||||
message,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
}
|
||||
|
||||
async function getInfoVersions(pkgName, registry) {
|
||||
const infoResp = await pnpm(
|
||||
{},
|
||||
'info',
|
||||
pkgName,
|
||||
'--json',
|
||||
...addRegistry(registry.getRegistryUrl())
|
||||
);
|
||||
const infoBody = JSON.parse(infoResp.stdout as string);
|
||||
return infoBody;
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const setup = await initialSetup();
|
||||
registry = setup.registry;
|
||||
await registry.init();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-1']])(
|
||||
'should deprecate a single package %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.name).toEqual(pkgName);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
}
|
||||
);
|
||||
|
||||
test.each([['@verdaccio/deprecated-2']])('should un-deprecate a package %s', async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// deprecate one version
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, message);
|
||||
// verify is deprecated
|
||||
const infoBody = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody.deprecated).toEqual(message);
|
||||
// empty string is same as undeprecate
|
||||
await deprecate(tempFolder, `${pkgName}@1.0.0`, registry, '');
|
||||
const infoBody2 = await getInfoVersions(`${pkgName}`, registry);
|
||||
expect(infoBody2.deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
test.each([['@verdaccio/deprecated-3']])(
|
||||
'should deprecate a multiple packages %s',
|
||||
async (pkgName) => {
|
||||
const message = 'some message';
|
||||
const { tempFolder } = await prepareGenericEmptyProject(
|
||||
pkgName,
|
||||
'1.0.0',
|
||||
registry.port,
|
||||
registry.getToken(),
|
||||
registry.getRegistryUrl()
|
||||
);
|
||||
// publish 1.0.0
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.1.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.2.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// publish 1.3.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
// // deprecate all version
|
||||
await deprecate(tempFolder, pkgName, registry, message);
|
||||
// verify is deprecated
|
||||
for (let v of ['1.0.0', '1.1.0', '1.2.0', '1.3.0']) {
|
||||
const infoResp = await getInfoVersions(`${pkgName}@${v}`, registry);
|
||||
expect(infoResp.deprecated).toEqual(message);
|
||||
}
|
||||
// publish normal version
|
||||
// publish 1.4.0
|
||||
await bumbUp(tempFolder, registry);
|
||||
await publish(tempFolder, pkgName, registry);
|
||||
const infoResp = await getInfoVersions(`${pkgName}@1.4.0`, registry);
|
||||
// must be not deprecated
|
||||
expect(infoResp.deprecated).toBeUndefined();
|
||||
}
|
||||
);
|
||||
|
||||
afterAll(async () => {
|
||||
registry.stop();
|
||||
});
|
||||
});
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
@ -1,14 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
name: 'verdaccio-e2e-cli-jest',
|
||||
// verbose: true,
|
||||
// collectCoverage: false,
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
// testEnvironment: './env_babel.js',
|
||||
// globalSetup: './env_setup.js',
|
||||
// globalTeardown: './env_teardown.js',
|
||||
// testRegex: '(/test/e2e.*\\.spec)\\.ts',
|
||||
testRegex: '(/test/*.*.spec)\\.ts',
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
@ -23,9 +23,9 @@ describe('install a package', () => {
|
||||
});
|
||||
|
||||
test('should run yarn 2 info json body', async () => {
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'verdaccio', '--json');
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'react', '--json');
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual('verdaccio');
|
||||
expect(parsedBody.name).toEqual('react');
|
||||
expect(parsedBody.dependencies).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { initialSetup, prepareYarnModernProject } from '@verdaccio/test-cli-comm
|
||||
import { getYarnCommand, yarn } from './utils';
|
||||
|
||||
describe('install a packages', () => {
|
||||
jest.setTimeout(10000);
|
||||
jest.setTimeout(20000);
|
||||
let registry;
|
||||
let projectFolder;
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
@ -24,9 +24,9 @@ describe('install a package', () => {
|
||||
|
||||
test('should run yarn 3 info json body', async () => {
|
||||
await yarn(projectFolder, 'install');
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'verdaccio', '--json');
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'react', '--json');
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual('verdaccio');
|
||||
expect(parsedBody.name).toEqual('react');
|
||||
expect(parsedBody.dependencies).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { initialSetup, prepareYarnModernProject } from '@verdaccio/test-cli-comm
|
||||
import { getYarnCommand, yarn } from './utils';
|
||||
|
||||
describe('install a packages', () => {
|
||||
jest.setTimeout(10000);
|
||||
jest.setTimeout(20000);
|
||||
let registry;
|
||||
let projectFolder;
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
@ -23,9 +23,9 @@ describe('install a package', () => {
|
||||
});
|
||||
|
||||
test('should run yarn 4 info json body', async () => {
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'verdaccio', '--json');
|
||||
const resp = await yarn(projectFolder, 'npm', 'info', 'react', '--json');
|
||||
const parsedBody = JSON.parse(resp.stdout as string);
|
||||
expect(parsedBody.name).toEqual('verdaccio');
|
||||
expect(parsedBody.name).toEqual('react');
|
||||
expect(parsedBody.dependencies).toBeDefined();
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { initialSetup, prepareYarnModernProject } from '@verdaccio/test-cli-comm
|
||||
import { getYarnCommand, yarn } from './utils';
|
||||
|
||||
describe('install a packages', () => {
|
||||
jest.setTimeout(10000);
|
||||
jest.setTimeout(20000);
|
||||
let registry;
|
||||
let projectFolder;
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../../jest/config');
|
||||
const config = require('../jest.config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
||||
module.exports = { ...config };
|
||||
|
8
test/cli/jest.config.js
Normal file
8
test/cli/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
const { defaults } = require('jest-config');
|
||||
const config = require('../../jest/config');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
collectCoverage: false,
|
||||
coverageReporters: ['text'],
|
||||
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'],
|
||||
});
|
Loading…
Reference in New Issue
Block a user