mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
feat: show version-specific readmes in web ui
This commit is contained in:
parent
4af6b86094
commit
30dd6653e7
4 changed files with 88 additions and 2 deletions
5
.changeset/strange-pants-chew.md
Normal file
5
.changeset/strange-pants-chew.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@verdaccio/web': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat: show version-specific readmes in web ui
|
|
@ -2,11 +2,12 @@ import buildDebug from 'debug';
|
||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
|
|
||||||
import { Auth } from '@verdaccio/auth';
|
import { Auth } from '@verdaccio/auth';
|
||||||
import { HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
import { DIST_TAGS, HEADERS, HEADER_TYPE } from '@verdaccio/core';
|
||||||
import { logger } from '@verdaccio/logger';
|
import { logger } from '@verdaccio/logger';
|
||||||
import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
|
import { $NextFunctionVer, $RequestExtend, $ResponseExtend, allow } from '@verdaccio/middleware';
|
||||||
import { Storage } from '@verdaccio/store';
|
import { Storage } from '@verdaccio/store';
|
||||||
import { Manifest } from '@verdaccio/types';
|
import { Manifest } from '@verdaccio/types';
|
||||||
|
import { isVersionValid } from '@verdaccio/utils';
|
||||||
|
|
||||||
import { AuthorAvatar, addScope } from '../web-utils';
|
import { AuthorAvatar, addScope } from '../web-utils';
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ export { $RequestExtend, $ResponseExtend, $NextFunctionVer }; // Was required by
|
||||||
export type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };
|
export type PackageExt = Manifest & { author: AuthorAvatar; dist?: { tarball: string } };
|
||||||
export const NOT_README_FOUND = 'ERROR: No README data found!';
|
export const NOT_README_FOUND = 'ERROR: No README data found!';
|
||||||
const debug = buildDebug('verdaccio:web:api:readme');
|
const debug = buildDebug('verdaccio:web:api:readme');
|
||||||
|
|
||||||
const getReadme = (readme) => {
|
const getReadme = (readme) => {
|
||||||
if (typeof readme === 'string' && readme.length === 0) {
|
if (typeof readme === 'string' && readme.length === 0) {
|
||||||
return NOT_README_FOUND;
|
return NOT_README_FOUND;
|
||||||
|
@ -27,6 +29,25 @@ const getReadme = (readme) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getReadmeFromManifest = (manifest: Manifest, v?: any): string | undefined => {
|
||||||
|
let id;
|
||||||
|
let readme;
|
||||||
|
if (typeof v === 'string' && isVersionValid(manifest, v)) {
|
||||||
|
id = 'version';
|
||||||
|
readme = manifest.versions[v].readme;
|
||||||
|
}
|
||||||
|
if (!readme && isVersionValid(manifest, manifest[DIST_TAGS]?.latest)) {
|
||||||
|
id = 'latest';
|
||||||
|
readme = manifest.versions[manifest[DIST_TAGS].latest].readme;
|
||||||
|
}
|
||||||
|
if (!readme && manifest.readme) {
|
||||||
|
id = 'root';
|
||||||
|
readme = manifest.readme;
|
||||||
|
}
|
||||||
|
debug('readme: %o %o', v, id);
|
||||||
|
return readme;
|
||||||
|
};
|
||||||
|
|
||||||
function addReadmeWebApi(storage: Storage, auth: Auth): Router {
|
function addReadmeWebApi(storage: Storage, auth: Auth): Router {
|
||||||
debug('initialized readme web api');
|
debug('initialized readme web api');
|
||||||
const can = allow(auth, {
|
const can = allow(auth, {
|
||||||
|
@ -64,7 +85,9 @@ function addReadmeWebApi(storage: Storage, auth: Auth): Router {
|
||||||
})) as Manifest;
|
})) as Manifest;
|
||||||
debug('readme pkg %o', manifest?.name);
|
debug('readme pkg %o', manifest?.name);
|
||||||
res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8);
|
res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8);
|
||||||
next(getReadme(manifest.readme));
|
const { v } = req.query;
|
||||||
|
const readme = getReadmeFromManifest(manifest, v);
|
||||||
|
next(getReadme(readme));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,4 +73,33 @@ describe('readme api', () => {
|
||||||
.expect(HTTP_STATUS.OK);
|
.expect(HTTP_STATUS.OK);
|
||||||
expect(response.text).toMatch(NOT_README_FOUND);
|
expect(response.text).toMatch(NOT_README_FOUND);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should fetch readme with keeping all readmes (latest)', async () => {
|
||||||
|
const app = await initializeServer('keep-all-readmes.yaml');
|
||||||
|
await publishVersion(app, 'pk1-test', '1.0.0', { readme: 'my readme' });
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get('/-/verdaccio/data/package/readme/pk1-test')
|
||||||
|
.set('Accept', HEADERS.TEXT_PLAIN)
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
expect(response.text).toMatch('my readme');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should fetch readme with keeping all readmes (version)', async () => {
|
||||||
|
const app = await initializeServer('keep-all-readmes.yaml');
|
||||||
|
await publishVersion(app, 'pk1-test', '1.0.0', { readme: 'my readme' });
|
||||||
|
await publishVersion(app, 'pk1-test', '1.2.0', { readme: 'my new readme' });
|
||||||
|
const response = await supertest(app)
|
||||||
|
.get('/-/verdaccio/data/package/readme/pk1-test')
|
||||||
|
.set('Accept', HEADERS.TEXT_PLAIN)
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
expect(response.text).toMatch('my new readme');
|
||||||
|
const response2 = await supertest(app)
|
||||||
|
.get('/-/verdaccio/data/package/readme/pk1-test?v=1.0.0')
|
||||||
|
.set('Accept', HEADERS.TEXT_PLAIN)
|
||||||
|
.expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN_UTF8)
|
||||||
|
.expect(HTTP_STATUS.OK);
|
||||||
|
expect(response2.text).toMatch('my readme');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
29
packages/web/test/config/keep-all-readmes.yaml
Normal file
29
packages/web/test/config/keep-all-readmes.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
auth:
|
||||||
|
auth-memory:
|
||||||
|
users:
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
password: test
|
||||||
|
|
||||||
|
web:
|
||||||
|
title: verdaccio
|
||||||
|
|
||||||
|
publish:
|
||||||
|
allow_offline: false
|
||||||
|
keep_readmes: all
|
||||||
|
|
||||||
|
uplinks:
|
||||||
|
|
||||||
|
log: { type: stdout, format: pretty, level: trace }
|
||||||
|
|
||||||
|
packages:
|
||||||
|
'@*/*':
|
||||||
|
access: $anonymous
|
||||||
|
publish: $anonymous
|
||||||
|
'**':
|
||||||
|
access: $anonymous
|
||||||
|
publish: $anonymous
|
||||||
|
_debug: true
|
||||||
|
|
||||||
|
flags:
|
||||||
|
changePassword: true
|
Loading…
Reference in a new issue