mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-13 03:35:52 +01:00
chore: list stars of an user (#3451)
* chore: list stars of user * chore: add pnpm test e2e
This commit is contained in:
parent
aecad09c6a
commit
a8e1ffd72f
@ -20,6 +20,7 @@
|
|||||||
| ping | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
| ping | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
||||||
| search | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
| search | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
||||||
| star | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
| star | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
||||||
|
| stars | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
|
||||||
| dist-tag | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
| dist-tag | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
|
||||||
|
|
||||||
> notes:
|
> notes:
|
||||||
|
@ -63,6 +63,22 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await npmUtils.publish(npm, tempFolder, pkgName, registry);
|
||||||
|
await npm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await npm({ cwd: tempFolder }, 'stars', ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,22 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await npmUtils.publish(npm, tempFolder, pkgName, registry);
|
||||||
|
await npm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await npm({ cwd: tempFolder }, 'stars', ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,22 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await npmUtils.publish(npm, tempFolder, pkgName, registry);
|
||||||
|
await npm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await npm({ cwd: tempFolder }, 'stars', ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,22 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await npmUtils.publish(npm, tempFolder, pkgName, registry);
|
||||||
|
await npm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await npm({ cwd: tempFolder }, 'stars', ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,26 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await pnpmUtils.publish(pnpm, tempFolder, pkgName, registry);
|
||||||
|
await pnpm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await pnpm(
|
||||||
|
{ cwd: tempFolder },
|
||||||
|
'stars',
|
||||||
|
...addRegistry(registry.getRegistryUrl())
|
||||||
|
);
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,26 @@ describe('star a package', () => {
|
|||||||
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
expect(resp1.stdout).toEqual(`☆ ${pkgName}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should list stars of a user %s', async () => {
|
||||||
|
const pkgName = '@verdaccio/stars';
|
||||||
|
const { tempFolder } = await prepareGenericEmptyProject(
|
||||||
|
pkgName,
|
||||||
|
'1.0.0-patch',
|
||||||
|
registry.port,
|
||||||
|
registry.getToken(),
|
||||||
|
registry.getRegistryUrl()
|
||||||
|
);
|
||||||
|
await pnpmUtils.publish(pnpm, tempFolder, pkgName, registry);
|
||||||
|
await pnpm({ cwd: tempFolder }, 'star', pkgName, ...addRegistry(registry.getRegistryUrl()));
|
||||||
|
const resp = await pnpm(
|
||||||
|
{ cwd: tempFolder },
|
||||||
|
'stars',
|
||||||
|
...addRegistry(registry.getRegistryUrl())
|
||||||
|
);
|
||||||
|
// side effects: this result is affected the the package published in the previous step
|
||||||
|
expect(resp.stdout).toEqual(`@verdaccio/foo@verdaccio/stars`);
|
||||||
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
registry.stop();
|
registry.stop();
|
||||||
});
|
});
|
||||||
|
@ -98,24 +98,4 @@ export default function (route: Router, auth: Auth, storage: Storage): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
route.post(
|
|
||||||
'/-/package/:package/dist-tags',
|
|
||||||
can('publish'),
|
|
||||||
async function (
|
|
||||||
req: $RequestExtend,
|
|
||||||
res: $ResponseExtend,
|
|
||||||
next: $NextFunctionVer
|
|
||||||
): Promise<void> {
|
|
||||||
try {
|
|
||||||
await storage.mergeTagsNext(req.params.package, req.body);
|
|
||||||
res.status(constants.HTTP_STATUS.CREATED);
|
|
||||||
return next({
|
|
||||||
ok: constants.API_MESSAGE.TAG_UPDATED,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import buildDebug from 'debug';
|
|
||||||
import { Response } from 'express';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
|
||||||
import { Storage } from '@verdaccio/store';
|
|
||||||
|
|
||||||
import { $NextFunctionVer, $RequestExtend } from '../types/custom';
|
|
||||||
|
|
||||||
const debug = buildDebug('verdaccio:api:publish:star');
|
|
||||||
|
|
||||||
export default function (
|
|
||||||
storage: Storage
|
|
||||||
): (req: $RequestExtend, res: Response, next: $NextFunctionVer) => void {
|
|
||||||
const validateInputs = (newUsers, localUsers, username, isStar): boolean => {
|
|
||||||
const isExistlocalUsers = _.isNil(localUsers[username]) === false;
|
|
||||||
if (isStar && isExistlocalUsers && localUsers[username]) {
|
|
||||||
return true;
|
|
||||||
} else if (!isStar && isExistlocalUsers) {
|
|
||||||
return false;
|
|
||||||
} else if (!isStar && !isExistlocalUsers) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
|
|
||||||
const name = req.params.package;
|
|
||||||
debug('starring a package for %o', name);
|
|
||||||
// const afterChangePackage = function (err?: Error) {
|
|
||||||
// if (err) {
|
|
||||||
// debug('error on update package for %o', name);
|
|
||||||
// return next(err);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// debug('succes update package for %o', name);
|
|
||||||
// res.status(HTTP_STATUS.OK);
|
|
||||||
// next({
|
|
||||||
// success: true,
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
debug('get package info package for %o', name);
|
|
||||||
// @ts-ignore
|
|
||||||
// storage.getPackage({
|
|
||||||
// name,
|
|
||||||
// req,
|
|
||||||
// callback: function (err, info) {
|
|
||||||
// if (err) {
|
|
||||||
// debug('error on get package info package for %o', name);
|
|
||||||
// return next(err);
|
|
||||||
// }
|
|
||||||
// const newStarUser = req.body[USERS];
|
|
||||||
// const remoteUsername = req.remote_user.name;
|
|
||||||
// const localStarUsers = info[USERS];
|
|
||||||
// // Check is star or unstar
|
|
||||||
// const isStar = Object.keys(newStarUser).includes(remoteUsername);
|
|
||||||
// debug('is start? %o', isStar);
|
|
||||||
// if (
|
|
||||||
// _.isNil(localStarUsers) === false &&
|
|
||||||
// validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)
|
|
||||||
// ) {
|
|
||||||
// return afterChangePackage();
|
|
||||||
// }
|
|
||||||
// const users = isStar
|
|
||||||
// ? {
|
|
||||||
// ...localStarUsers,
|
|
||||||
// [remoteUsername]: true,
|
|
||||||
// }
|
|
||||||
// : _.reduce(
|
|
||||||
// localStarUsers,
|
|
||||||
// (users, value, key) => {
|
|
||||||
// if (key !== remoteUsername) {
|
|
||||||
// users[key] = value;
|
|
||||||
// }
|
|
||||||
// return users;
|
|
||||||
// },
|
|
||||||
// {}
|
|
||||||
// );
|
|
||||||
// debug('update package for %o', name);
|
|
||||||
// storage.changePackage(name, { ...info, users }, req.body._rev, function (err) {
|
|
||||||
// afterChangePackage(err);
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
import { Response, Router } from 'express';
|
import { Response, Router } from 'express';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { HTTP_STATUS, USERS } from '@verdaccio/core';
|
import { HTTP_STATUS, USERS, errorUtils } from '@verdaccio/core';
|
||||||
import { Storage } from '@verdaccio/store';
|
import { Storage } from '@verdaccio/store';
|
||||||
import { Version } from '@verdaccio/types';
|
import { Version } from '@verdaccio/types';
|
||||||
|
|
||||||
@ -11,13 +11,15 @@ export default function (route: Router, storage: Storage): void {
|
|||||||
route.get(
|
route.get(
|
||||||
'/-/_view/starredByUser',
|
'/-/_view/starredByUser',
|
||||||
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
|
async (req: $RequestExtend, res: Response, next: $NextFunctionVer): Promise<void> => {
|
||||||
const remoteUsername = req.remote_user.name;
|
const query: { key: string } = req.query;
|
||||||
|
if (typeof query?.key !== 'string') {
|
||||||
|
return next(errorUtils.getBadRequest('missing query key username'));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const localPackages: Version[] = await storage.getLocalDatabaseNext();
|
const localPackages: Version[] = await storage.getLocalDatabase();
|
||||||
|
|
||||||
const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
|
const filteredPackages: Version[] = localPackages.filter((localPackage: Version) =>
|
||||||
_.keys(localPackage[USERS]).includes(remoteUsername)
|
_.keys(localPackage[USERS]).includes(query?.key.toString().replace(/['"]+/g, ''))
|
||||||
);
|
);
|
||||||
|
|
||||||
res.status(HTTP_STATUS.OK);
|
res.status(HTTP_STATUS.OK);
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
generatePackageMetadata,
|
generatePackageMetadata,
|
||||||
initializeServer as initializeServerHelper,
|
initializeServer as initializeServerHelper,
|
||||||
} from '@verdaccio/test-helper';
|
} from '@verdaccio/test-helper';
|
||||||
import { GenericBody } from '@verdaccio/types';
|
import { GenericBody, PackageUsers } from '@verdaccio/types';
|
||||||
import { buildToken, generateRandomHexString } from '@verdaccio/utils';
|
import { buildToken, generateRandomHexString } from '@verdaccio/utils';
|
||||||
|
|
||||||
import apiMiddleware from '../../src';
|
import apiMiddleware from '../../src';
|
||||||
@ -91,16 +91,54 @@ export function publishVersion(
|
|||||||
app,
|
app,
|
||||||
pkgName: string,
|
pkgName: string,
|
||||||
version: string,
|
version: string,
|
||||||
distTags?: GenericBody
|
distTags?: GenericBody,
|
||||||
|
token?: string
|
||||||
): supertest.Test {
|
): supertest.Test {
|
||||||
const pkgMetadata = generatePackageMetadata(pkgName, version, distTags);
|
const pkgMetadata = generatePackageMetadata(pkgName, version, distTags);
|
||||||
|
|
||||||
return supertest(app)
|
const test = supertest(app)
|
||||||
.put(`/${encodeURIComponent(pkgName)}`)
|
.put(`/${encodeURIComponent(pkgName)}`)
|
||||||
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||||
.send(JSON.stringify(pkgMetadata))
|
.send(JSON.stringify(pkgMetadata))
|
||||||
.set('accept', HEADERS.GZIP)
|
.set('accept', HEADERS.GZIP)
|
||||||
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
||||||
|
|
||||||
|
if (typeof token === 'string') {
|
||||||
|
test.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token));
|
||||||
|
}
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function starPackage(
|
||||||
|
app,
|
||||||
|
options: {
|
||||||
|
users: PackageUsers;
|
||||||
|
name: string;
|
||||||
|
_rev: string;
|
||||||
|
_id?: string;
|
||||||
|
},
|
||||||
|
token?: string
|
||||||
|
): supertest.Test {
|
||||||
|
const { _rev, _id, users } = options;
|
||||||
|
const starManifest = {
|
||||||
|
_rev,
|
||||||
|
_id,
|
||||||
|
users,
|
||||||
|
};
|
||||||
|
|
||||||
|
const test = supertest(app)
|
||||||
|
.put(`/${encodeURIComponent(options.name)}`)
|
||||||
|
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
|
||||||
|
.send(JSON.stringify(starManifest))
|
||||||
|
.set('accept', HEADERS.GZIP)
|
||||||
|
.set(HEADER_TYPE.ACCEPT_ENCODING, HEADERS.JSON);
|
||||||
|
|
||||||
|
if (typeof token === 'string') {
|
||||||
|
test.set(HEADERS.AUTHORIZATION, buildToken(TOKEN_BEARER, token));
|
||||||
|
}
|
||||||
|
|
||||||
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDisTags(app, pkgName) {
|
export function getDisTags(app, pkgName) {
|
||||||
|
26
packages/api/test/integration/config/star.yaml
Normal file
26
packages/api/test/integration/config/star.yaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
auth:
|
||||||
|
htpasswd:
|
||||||
|
file: ./htpasswd-star
|
||||||
|
web:
|
||||||
|
enable: true
|
||||||
|
title: verdaccio
|
||||||
|
|
||||||
|
uplinks:
|
||||||
|
npmjs:
|
||||||
|
url: https://registry.npmjs.org/
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: info }
|
||||||
|
|
||||||
|
packages:
|
||||||
|
'@*/*':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
unpublish: $authenticated
|
||||||
|
proxy: npmjs
|
||||||
|
'**':
|
||||||
|
access: $all
|
||||||
|
publish: $authenticated
|
||||||
|
unpublish: $authenticated
|
||||||
|
proxy: npmjs
|
||||||
|
|
||||||
|
_debug: true
|
@ -6,38 +6,8 @@ import { HTTP_STATUS } from '@verdaccio/core';
|
|||||||
import { API_ERROR, API_MESSAGE, HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
import { API_ERROR, API_MESSAGE, HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||||
import { generatePackageMetadata, generateRemotePackageMetadata } from '@verdaccio/test-helper';
|
import { generatePackageMetadata, generateRemotePackageMetadata } from '@verdaccio/test-helper';
|
||||||
|
|
||||||
import { $RequestExtend, $ResponseExtend } from '../../types/custom';
|
|
||||||
import { getPackage, initializeServer, publishVersion } from './_helper';
|
import { getPackage, initializeServer, publishVersion } from './_helper';
|
||||||
|
|
||||||
const mockApiJWTmiddleware = jest.fn(
|
|
||||||
() =>
|
|
||||||
(req: $RequestExtend, res: $ResponseExtend, _next): void => {
|
|
||||||
req.remote_user = { name: 'foo', groups: [], real_groups: [] };
|
|
||||||
_next();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
jest.mock('@verdaccio/auth', () => ({
|
|
||||||
Auth: class {
|
|
||||||
apiJWTmiddleware() {
|
|
||||||
return mockApiJWTmiddleware();
|
|
||||||
}
|
|
||||||
init() {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
allow_access(_d, f_, cb) {
|
|
||||||
cb(null, true);
|
|
||||||
}
|
|
||||||
allow_publish(_d, f_, cb) {
|
|
||||||
cb(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
allow_unpublish(_d, f_, cb) {
|
|
||||||
cb(null, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('publish', () => {
|
describe('publish', () => {
|
||||||
describe('handle errors', () => {
|
describe('handle errors', () => {
|
||||||
const pkgName = 'test';
|
const pkgName = 'test';
|
||||||
@ -80,6 +50,22 @@ describe('publish', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.each([['foo', '@scope/foo']])(
|
||||||
|
'should fails on publish a duplicated package',
|
||||||
|
async (pkgName) => {
|
||||||
|
const app = await initializeServer('publish.yaml');
|
||||||
|
await publishVersion(app, pkgName, '1.0.0');
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
publishVersion(app, pkgName, '1.0.0')
|
||||||
|
.expect(HTTP_STATUS.CONFLICT)
|
||||||
|
.then((response) => {
|
||||||
|
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('publish a package', () => {
|
describe('publish a package', () => {
|
||||||
@ -141,6 +127,7 @@ describe('publish', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('proxies setup', () => {
|
describe('proxies setup', () => {
|
||||||
test.each([['foo', '@scope%2Ffoo']])(
|
test.each([['foo', '@scope%2Ffoo']])(
|
||||||
'should publish a a patch package that already exist on a remote',
|
'should publish a a patch package that already exist on a remote',
|
||||||
@ -172,22 +159,6 @@ describe('publish', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each([['foo', '@scope/foo']])(
|
|
||||||
'should fails on publish a duplicated package',
|
|
||||||
async (pkgName) => {
|
|
||||||
const app = await initializeServer('publish.yaml');
|
|
||||||
await publishVersion(app, pkgName, '1.0.0');
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
publishVersion(app, pkgName, '1.0.0')
|
|
||||||
.expect(HTTP_STATUS.CONFLICT)
|
|
||||||
.then((response) => {
|
|
||||||
expect(response.body.error).toEqual(API_ERROR.PACKAGE_EXIST);
|
|
||||||
resolve(response);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
describe('unpublish a package', () => {
|
describe('unpublish a package', () => {
|
||||||
test.each([['foo', '@scope/foo']])('should unpublish entirely a package', async (pkgName) => {
|
test.each([['foo', '@scope/foo']])('should unpublish entirely a package', async (pkgName) => {
|
||||||
const app = await initializeServer('publish.yaml');
|
const app = await initializeServer('publish.yaml');
|
||||||
@ -257,6 +228,4 @@ describe('publish', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('star a package', () => {});
|
|
||||||
});
|
});
|
||||||
|
73
packages/api/test/integration/star.spec.ts
Normal file
73
packages/api/test/integration/star.spec.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import nock from 'nock';
|
||||||
|
import supertest from 'supertest';
|
||||||
|
|
||||||
|
import { HTTP_STATUS } from '@verdaccio/core';
|
||||||
|
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||||
|
|
||||||
|
import { getNewToken, getPackage, initializeServer, publishVersion, starPackage } from './_helper';
|
||||||
|
|
||||||
|
describe('star', () => {
|
||||||
|
test.each([['foo', '@scope%2Ffoo']])(
|
||||||
|
'should list stared packages for an user',
|
||||||
|
async (pkgName) => {
|
||||||
|
const userLogged = 'jota_token';
|
||||||
|
nock('https://registry.npmjs.org').get(`/${pkgName}`).reply(404);
|
||||||
|
const app = await initializeServer('star.yaml');
|
||||||
|
const token = await getNewToken(app, { name: userLogged, password: 'secretPass' });
|
||||||
|
await publishVersion(app, pkgName, '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
||||||
|
await publishVersion(app, 'pkg-1', '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
||||||
|
await publishVersion(app, 'pkg-2', '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
||||||
|
const manifest = await getPackage(app, '', decodeURIComponent(pkgName));
|
||||||
|
await starPackage(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
_rev: manifest.body._rev,
|
||||||
|
_id: manifest.body.id,
|
||||||
|
name: pkgName,
|
||||||
|
users: { [userLogged]: true },
|
||||||
|
},
|
||||||
|
token
|
||||||
|
).expect(HTTP_STATUS.CREATED);
|
||||||
|
await starPackage(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
_rev: manifest.body._rev,
|
||||||
|
_id: manifest.body.id,
|
||||||
|
name: 'pkg-1',
|
||||||
|
users: { [userLogged]: true },
|
||||||
|
},
|
||||||
|
token
|
||||||
|
).expect(HTTP_STATUS.CREATED);
|
||||||
|
await starPackage(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
_rev: manifest.body._rev,
|
||||||
|
_id: manifest.body.id,
|
||||||
|
name: 'pkg-2',
|
||||||
|
users: { [userLogged]: true },
|
||||||
|
},
|
||||||
|
token
|
||||||
|
).expect(HTTP_STATUS.CREATED);
|
||||||
|
const resp = await supertest(app)
|
||||||
|
.get(`/-/_view/starredByUser?key=%22jota_token%22`)
|
||||||
|
.set('Accept', HEADERS.JSON)
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
expect(resp.body.rows).toHaveLength(3);
|
||||||
|
expect(resp.body.rows).toEqual([{ value: 'foo' }, { value: 'pkg-1' }, { value: 'pkg-2' }]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test.each([['foo']])('should requires parameters', async (pkgName) => {
|
||||||
|
const userLogged = 'jota_token';
|
||||||
|
nock('https://registry.npmjs.org').get(`/${pkgName}`).reply(404);
|
||||||
|
const app = await initializeServer('star.yaml');
|
||||||
|
const token = await getNewToken(app, { name: userLogged, password: 'secretPass' });
|
||||||
|
await publishVersion(app, pkgName, '1.0.0', undefined, token).expect(HTTP_STATUS.CREATED);
|
||||||
|
return supertest(app)
|
||||||
|
.get(`/-/_view/starredByUser?key_xxxxx=other`)
|
||||||
|
.set('Accept', HEADERS.JSON)
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET)
|
||||||
|
.expect(HTTP_STATUS.BAD_REQUEST);
|
||||||
|
});
|
||||||
|
});
|
2
packages/api/types/custom.d.ts
vendored
2
packages/api/types/custom.d.ts
vendored
@ -2,7 +2,7 @@ import { NextFunction, Request, Response } from 'express';
|
|||||||
|
|
||||||
import { Logger, RemoteUser } from '@verdaccio/types';
|
import { Logger, RemoteUser } from '@verdaccio/types';
|
||||||
|
|
||||||
export type $RequestExtend = Request & { remote_user?: any; log: Logger };
|
export type $RequestExtend = Request & { remote_user?: any; log: Logger; query?: { key: string } };
|
||||||
export type $ResponseExtend = Response & { cookies?: any };
|
export type $ResponseExtend = Response & { cookies?: any };
|
||||||
export type $NextFunctionVer = NextFunction & any;
|
export type $NextFunctionVer = NextFunction & any;
|
||||||
|
|
||||||
|
@ -589,7 +589,7 @@ class Storage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getLocalDatabaseNext(): Promise<Version[]> {
|
public async getLocalDatabase(): Promise<Version[]> {
|
||||||
debug('get local database');
|
debug('get local database');
|
||||||
const storage = this.localStorage.getStoragePlugin();
|
const storage = this.localStorage.getStoragePlugin();
|
||||||
const database = await storage.get();
|
const database = await storage.get();
|
||||||
@ -988,7 +988,7 @@ class Storage {
|
|||||||
const localStarUsers = localPackage.users || {};
|
const localStarUsers = localPackage.users || {};
|
||||||
// if trying to add a star
|
// if trying to add a star
|
||||||
const userIsAddingStar = Object.keys(users as PackageUsers).includes(username);
|
const userIsAddingStar = Object.keys(users as PackageUsers).includes(username);
|
||||||
if (!isExecutingStarCommand(localPackage.users as PackageUsers, username, userIsAddingStar)) {
|
if (!isExecutingStarCommand(localPackage?.users as PackageUsers, username, userIsAddingStar)) {
|
||||||
return API_MESSAGE.PKG_CHANGED;
|
return API_MESSAGE.PKG_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,7 +1128,7 @@ class Storage {
|
|||||||
// TODO: review why do this
|
// TODO: review why do this
|
||||||
versions[versionToPublish].readme =
|
versions[versionToPublish].readme =
|
||||||
_.isNil(manifest.readme) === false ? String(manifest.readme) : '';
|
_.isNil(manifest.readme) === false ? String(manifest.readme) : '';
|
||||||
await this.addVersionNext(name, versionToPublish, versions[versionToPublish], null);
|
await this.addVersion(name, versionToPublish, versions[versionToPublish], null);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
logger.error({ err: err.message }, 'updated version has failed: @{err}');
|
logger.error({ err: err.message }, 'updated version has failed: @{err}');
|
||||||
debug('error on create a version for %o with error %o', name, err.message);
|
debug('error on create a version for %o with error %o', name, err.message);
|
||||||
@ -1139,7 +1139,7 @@ class Storage {
|
|||||||
// 2. update and merge tags
|
// 2. update and merge tags
|
||||||
let mergedManifest;
|
let mergedManifest;
|
||||||
try {
|
try {
|
||||||
// note: I could merge this with addVersionNext
|
// note: I could merge this with addVersion()
|
||||||
// 1. add version
|
// 1. add version
|
||||||
// 2. merge versions
|
// 2. merge versions
|
||||||
// 3. upload tarball
|
// 3. upload tarball
|
||||||
@ -1325,7 +1325,7 @@ class Storage {
|
|||||||
* @param metadata version metadata
|
* @param metadata version metadata
|
||||||
* @param tag tag of the version
|
* @param tag tag of the version
|
||||||
*/
|
*/
|
||||||
public async addVersionNext(
|
private async addVersion(
|
||||||
name: string,
|
name: string,
|
||||||
version: string,
|
version: string,
|
||||||
metadata: Version,
|
metadata: Version,
|
||||||
|
@ -1090,7 +1090,7 @@ describe('storage', () => {
|
|||||||
);
|
);
|
||||||
const storage = new Storage(config);
|
const storage = new Storage(config);
|
||||||
await storage.init(config);
|
await storage.init(config);
|
||||||
await expect(storage.getLocalDatabaseNext()).resolves.toHaveLength(0);
|
await expect(storage.getLocalDatabase()).resolves.toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return 1 local packages', async () => {
|
test('should return 1 local packages', async () => {
|
||||||
@ -1122,7 +1122,7 @@ describe('storage', () => {
|
|||||||
host: req.get('host') as string,
|
host: req.get('host') as string,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const response = await storage.getLocalDatabaseNext();
|
const response = await storage.getLocalDatabase();
|
||||||
expect(response).toHaveLength(1);
|
expect(response).toHaveLength(1);
|
||||||
expect(response[0]).toEqual(expect.objectContaining({ name: 'foo', version: '1.0.0' }));
|
expect(response[0]).toEqual(expect.objectContaining({ name: 'foo', version: '1.0.0' }));
|
||||||
});
|
});
|
||||||
|
@ -97,7 +97,7 @@ function addPackageWebApi(storage: Storage, auth: Auth, config: Config): Router
|
|||||||
debug('hit package web api %o');
|
debug('hit package web api %o');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const localPackages: Version[] = await storage.getLocalDatabaseNext();
|
const localPackages: Version[] = await storage.getLocalDatabase();
|
||||||
|
|
||||||
const order = getOrder(config?.web?.sort_packages);
|
const order = getOrder(config?.web?.sort_packages);
|
||||||
debug('order %o', order);
|
debug('order %o', order);
|
||||||
|
Loading…
Reference in New Issue
Block a user