mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-04-01 02:42:23 -05:00
feat: adds support for ascii-doc preview in readme (#464)
This commit is contained in:
parent
825f5a57ea
commit
29bb57ad5f
6 changed files with 150 additions and 5 deletions
67
flow-typed/npm/asciidoctor.js_vx.x.x.js
vendored
Normal file
67
flow-typed/npm/asciidoctor.js_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
// flow-typed signature: b7109b7e394ff03ed211118d5af4cff8
|
||||||
|
// flow-typed version: <<STUB>>/asciidoctor.js_v1.5.6/flow_v0.69.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an autogenerated libdef stub for:
|
||||||
|
*
|
||||||
|
* 'asciidoctor.js'
|
||||||
|
*
|
||||||
|
* Fill this stub out by replacing all the `any` types.
|
||||||
|
*
|
||||||
|
* Once filled out, we encourage you to share your work with the
|
||||||
|
* community by sending a pull request to:
|
||||||
|
* https://github.com/flowtype/flow-typed
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We include stubs for each file inside this npm package in case you need to
|
||||||
|
* require those files directly. Feel free to delete any files that aren't
|
||||||
|
* needed.
|
||||||
|
*/
|
||||||
|
declare module 'asciidoctor.js/dist/asciidoctor' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js/dist/asciidoctor.min' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js/dist/browser/asciidoctor' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js/dist/nashorn/asciidoctor' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js/dist/node/asciidoctor' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asciidoctor.js/dist/umd/asciidoctor' {
|
||||||
|
declare module.exports: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filename aliases
|
||||||
|
declare module 'asciidoctor.js/dist/asciidoctor.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/asciidoctor'>;
|
||||||
|
}
|
||||||
|
declare module 'asciidoctor.js/dist/asciidoctor.min.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/asciidoctor.min'>;
|
||||||
|
}
|
||||||
|
declare module 'asciidoctor.js/dist/browser/asciidoctor.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/browser/asciidoctor'>;
|
||||||
|
}
|
||||||
|
declare module 'asciidoctor.js/dist/nashorn/asciidoctor.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/nashorn/asciidoctor'>;
|
||||||
|
}
|
||||||
|
declare module 'asciidoctor.js/dist/node/asciidoctor.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/node/asciidoctor'>;
|
||||||
|
}
|
||||||
|
declare module 'asciidoctor.js/dist/umd/asciidoctor.js' {
|
||||||
|
declare module.exports: $Exports<'asciidoctor.js/dist/umd/asciidoctor'>;
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
"@verdaccio/local-storage": "1.1.2",
|
"@verdaccio/local-storage": "1.1.2",
|
||||||
"@verdaccio/streams": "1.0.0",
|
"@verdaccio/streams": "1.0.0",
|
||||||
"JSONStream": "1.3.2",
|
"JSONStream": "1.3.2",
|
||||||
|
"asciidoctor.js": "1.5.6",
|
||||||
"async": "2.6.0",
|
"async": "2.6.0",
|
||||||
"body-parser": "1.18.2",
|
"body-parser": "1.18.2",
|
||||||
"bunyan": "1.8.12",
|
"bunyan": "1.8.12",
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {addScope, addGravatarSupport, deleteProperties, sortByName, DIST_TAGS} from '../../../lib/utils';
|
import {addScope, addGravatarSupport, deleteProperties, sortByName, DIST_TAGS, parseReadme} from '../../../lib/utils';
|
||||||
import {allow} from '../../middleware';
|
import {allow} from '../../middleware';
|
||||||
import marked from 'marked';
|
|
||||||
import type {Router} from 'express';
|
import type {Router} from 'express';
|
||||||
import type {
|
import type {
|
||||||
IAuth,
|
IAuth,
|
||||||
|
@ -71,7 +70,7 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.set('Content-Type', 'text/plain');
|
res.set('Content-Type', 'text/plain');
|
||||||
next(marked(info.readme || 'ERROR: No README data found!'));
|
next(parseReadme(info.name, info.readme));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,8 @@ import _ from 'lodash';
|
||||||
import createError from 'http-errors';
|
import createError from 'http-errors';
|
||||||
import type {Package} from '@verdaccio/types';
|
import type {Package} from '@verdaccio/types';
|
||||||
import type {$Request} from 'express';
|
import type {$Request} from 'express';
|
||||||
|
import marked from 'marked';
|
||||||
|
import asciidoctor from 'asciidoctor.js';
|
||||||
import type {StringValue} from '../../types';
|
import type {StringValue} from '../../types';
|
||||||
|
|
||||||
const Logger = require('./logger');
|
const Logger = require('./logger');
|
||||||
|
@ -437,6 +439,31 @@ function addGravatarSupport(pkgInfo: any) {
|
||||||
return pkgInfo;
|
return pkgInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse package readme - markdown/ascii
|
||||||
|
* @param {String} packageName name of package
|
||||||
|
* @param {String} readme package readme
|
||||||
|
* @return {String} converted html template
|
||||||
|
*/
|
||||||
|
function parseReadme(packageName: string, readme: string): string {
|
||||||
|
const ascii = asciidoctor();
|
||||||
|
const docTypeIdentifier = new RegExp(/^=+ \w/, 'g');
|
||||||
|
|
||||||
|
// asciidoc
|
||||||
|
if (docTypeIdentifier.test(readme)) {
|
||||||
|
return ascii.convert(readme, {safe: 'safe', attributes: {showtitle: true, icons: 'font'}});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readme) {
|
||||||
|
return marked(readme);
|
||||||
|
}
|
||||||
|
|
||||||
|
// logs readme not found error
|
||||||
|
Logger.logger.error({packageName}, '@{packageName}: No readme found');
|
||||||
|
|
||||||
|
return marked('ERROR: No README data found!');
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
addGravatarSupport,
|
addGravatarSupport,
|
||||||
deleteProperties,
|
deleteProperties,
|
||||||
|
@ -458,4 +485,5 @@ export {
|
||||||
getLatestVersion,
|
getLatestVersion,
|
||||||
ErrorCode,
|
ErrorCode,
|
||||||
parseConfigFile,
|
parseConfigFile,
|
||||||
|
parseReadme,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import {validateName as validate, convertDistRemoteToLocalTarballUrls} from '../../src/lib/utils';
|
import {validateName as validate, convertDistRemoteToLocalTarballUrls, parseReadme} from '../../src/lib/utils';
|
||||||
import {generateGravatarUrl, GRAVATAR_DEFAULT} from '../../src/utils/user';
|
import {generateGravatarUrl, GRAVATAR_DEFAULT} from '../../src/utils/user';
|
||||||
import {spliceURL} from '../../src/utils/string';
|
import {spliceURL} from '../../src/utils/string';
|
||||||
import Package from "../../src/webui/src/components/Package";
|
import Package from "../../src/webui/src/components/Package";
|
||||||
|
import Logger, {setup} from '../../src/lib/logger';
|
||||||
|
|
||||||
|
setup([]);
|
||||||
|
|
||||||
describe('Utilities', () => {
|
describe('Utilities', () => {
|
||||||
|
|
||||||
|
@ -110,4 +113,34 @@ describe('Utilities', () => {
|
||||||
expect(convertDist.versions['1.0.1'].dist.tarball).toEqual(buildURI(host, '1.0.1'));
|
expect(convertDist.versions['1.0.1'].dist.tarball).toEqual(buildURI(host, '1.0.1'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('parseReadme', () => {
|
||||||
|
test('should pass for ascii/makrdown text to html template', () => {
|
||||||
|
const markdown = '# markdown';
|
||||||
|
const ascii = "= AsciiDoc";
|
||||||
|
expect(parseReadme('testPackage', markdown)).toEqual('<h1 id="markdown">markdown</h1>\n');
|
||||||
|
expect(parseReadme('testPackage', ascii)).toEqual('<h1>AsciiDoc</h1>\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should pass for conversion of non-ascii to markdown text', () => {
|
||||||
|
const simpleText = 'simple text';
|
||||||
|
const randomText = '%%%%%**##==';
|
||||||
|
const randomTextNonAscii = 'simple text \n = ascii';
|
||||||
|
const randomTextMarkdown = 'simple text \n # markdown';
|
||||||
|
expect(parseReadme('testPackage', randomText)).toEqual('<p>%%%%%**##==</p>\n');
|
||||||
|
expect(parseReadme('testPackage', simpleText)).toEqual('<p>simple text</p>\n');
|
||||||
|
expect(parseReadme('testPackage', randomTextNonAscii))
|
||||||
|
.toEqual('<p>simple text \n = ascii</p>\n');
|
||||||
|
expect(parseReadme('testPackage', randomTextMarkdown))
|
||||||
|
.toEqual('<p>simple text </p>\n<h1 id="markdown">markdown</h1>\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show error for no readme data', () => {
|
||||||
|
const noData = '';
|
||||||
|
const spy = jest.spyOn(Logger.logger, 'error')
|
||||||
|
expect(parseReadme('testPackage', noData))
|
||||||
|
.toEqual('<p>ERROR: No README data found!</p>\n');
|
||||||
|
expect(spy).toHaveBeenCalledWith({'packageName': 'testPackage'}, '@{packageName}: No readme found');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -631,6 +631,12 @@ asap@~2.0.3:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||||
|
|
||||||
|
asciidoctor.js@1.5.6:
|
||||||
|
version "1.5.6"
|
||||||
|
resolved "https://registry.npmjs.org/asciidoctor.js/-/asciidoctor.js-1.5.6.tgz#12f4810c62ea47867da145e819fc93b0674b5431"
|
||||||
|
dependencies:
|
||||||
|
opal-runtime "1.0.3"
|
||||||
|
|
||||||
asn1.js@^4.0.0:
|
asn1.js@^4.0.0:
|
||||||
version "4.10.1"
|
version "4.10.1"
|
||||||
resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
|
resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
|
||||||
|
@ -4109,7 +4115,7 @@ glob-parent@^3.1.0:
|
||||||
is-glob "^3.1.0"
|
is-glob "^3.1.0"
|
||||||
path-dirname "^1.0.0"
|
path-dirname "^1.0.0"
|
||||||
|
|
||||||
glob@^6.0.1, glob@^6.0.4:
|
glob@6.0.4, glob@^6.0.1, glob@^6.0.4:
|
||||||
version "6.0.4"
|
version "6.0.4"
|
||||||
resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6686,6 +6692,13 @@ onetime@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^1.0.0"
|
mimic-fn "^1.0.0"
|
||||||
|
|
||||||
|
opal-runtime@1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.npmjs.org/opal-runtime/-/opal-runtime-1.0.3.tgz#e81e5c2a2568bbb0b05743b427d035dd901485b7"
|
||||||
|
dependencies:
|
||||||
|
glob "6.0.4"
|
||||||
|
xmlhttprequest "1.8.0"
|
||||||
|
|
||||||
opener@^1.4.3:
|
opener@^1.4.3:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
|
resolved "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8"
|
||||||
|
@ -9779,6 +9792,10 @@ xml-name-validator@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||||
|
|
||||||
|
xmlhttprequest@1.8.0:
|
||||||
|
version "1.8.0"
|
||||||
|
resolved "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
|
||||||
|
|
||||||
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
|
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
|
||||||
|
|
Loading…
Add table
Reference in a new issue