0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-04-01 02:42:23 -05:00

refactor: directory structure

This commit is contained in:
Meeeeow 2017-06-22 01:02:52 +08:00 committed by Juan Picado @jotadeveloper
parent e3b1a33596
commit 7fef14c322
No known key found for this signature in database
GPG key ID: 18AC54485952D158
82 changed files with 250 additions and 142 deletions

View file

@ -1,3 +1,3 @@
#!/usr/bin/env node
require('../lib/cli');
require('../src/lib/cli');

View file

@ -1,4 +1,4 @@
module.exports = require('./lib');
module.exports = require('./src/api/index');
/** package
{ "name": "verdaccio",

View file

View file

@ -1,7 +1,7 @@
'use strict';
const Middleware = require('../../middleware');
const constant = require('../../utils/const');
const Middleware = require('../../web/middleware');
const constant = require('../../../webui/utils/const');
const media = Middleware.media;
const expect_json = Middleware.expect_json;

View file

@ -3,8 +3,8 @@
const _ = require('lodash');
const createError = require('http-errors');
const Middleware = require('../../middleware');
const Utils = require('../../../utils');
const Middleware = require('../../web/middleware');
const Utils = require('../../../lib/utils');
module.exports = function(route, auth, storage, config) {
const can = Middleware.allow(auth);

View file

@ -4,10 +4,10 @@ const _ = require('lodash');
const Path = require('path');
const createError = require('http-errors');
const Middleware = require('../../middleware');
const Notify = require('../../../notify');
const Utils = require('../../../utils');
const constant = require('../../utils/const');
const Middleware = require('../../web/middleware');
const Notify = require('../../../lib/notify');
const Utils = require('../../../lib/utils');
const constant = require('../../../webui/utils/const');
const media = Middleware.media;
const expect_json = Middleware.expect_json;

63
src/api/endpoint/index.js Normal file
View file

@ -0,0 +1,63 @@
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const Middleware = require('../web/middleware');
const match = Middleware.match;
const validate_name = Middleware.validate_name;
const validate_pkg = Middleware.validate_package;
const encodeScopePackage = Middleware.encodeScopePackage;
const whoami = require('./api/whoami');
const ping = require('./api/ping');
const user = require('./api/user');
const distTags = require('./api/dist-tags');
const publish = require('./api/publish');
const search = require('./api/search');
const pkg = require('./api/package');
module.exports = function(config, auth, storage) {
/* eslint new-cap:off */
const app = express.Router();
/* eslint new-cap:off */
// validate all of these params as a package name
// this might be too harsh, so ask if it causes trouble
app.param('package', validate_pkg);
app.param('filename', validate_name);
app.param('tag', validate_name);
app.param('version', validate_name);
app.param('revision', validate_name);
app.param('token', validate_name);
// these can't be safely put into express url for some reason
// TODO: For some reason? what reason?
app.param('_rev', match(/^-rev$/));
app.param('org_couchdb_user', match(/^org\.couchdb\.user:/));
app.param('anything', match(/.*/));
app.use(auth.basic_middleware());
// app.use(auth.bearer_middleware())
app.use(bodyParser.json({strict: false, limit: config.max_body_size || '10mb'}));
app.use(Middleware.anti_loop(config));
// encode / in a scoped package name to be matched as a single parameter in routes
app.use(encodeScopePackage);
// for "npm whoami"
whoami(app);
pkg(app, auth, storage, config);
search(app, auth, storage);
user(app, auth);
distTags(app, auth, storage);
publish(app, auth, storage, config);
ping(app);
return app;
};

View file

@ -3,25 +3,26 @@
const express = require('express');
const Error = require('http-errors');
const compression = require('compression');
const Auth = require('./auth');
const Logger = require('./logger');
const Config = require('./config');
const Auth = require('../lib/auth');
const Logger = require('../lib/logger');
const Config = require('../lib/config');
const Middleware = require('./web/middleware');
const Cats = require('./status-cats');
const Storage = require('./storage');
const Cats = require('../lib/status-cats');
const Storage = require('../lib/storage');
const _ = require('lodash');
module.exports = function(config_hash) {
// Config
Logger.setup(config_hash.logs);
const config = new Config(config_hash);
const storage = new Storage(config);
const auth = new Auth(config);
const app = express();
// run in production mode by default, just in case
// it shouldn't make any difference anyway
app.set('env', process.env.NODE_ENV || 'production');
// Middleware
const error_reporting_middleware = function(req, res, next) {
res.report_error = res.report_error || function(err) {
if (err.status && err.status >= 400 && err.status < 600) {
@ -46,6 +47,7 @@ module.exports = function(config_hash) {
next();
};
// Router setup
app.use(Middleware.log);
app.use(error_reporting_middleware);
app.use(function(req, res, next) {
@ -60,7 +62,7 @@ module.exports = function(config_hash) {
next();
});
// hook for tests only
// Hook for tests only
if (config._debug) {
app.get('/-/_debug', function(req, res, next) {
let do_gc = typeof(global.gc) !== 'undefined';
@ -77,33 +79,39 @@ module.exports = function(config_hash) {
});
}
app.use(require('./web/api/api')(config, auth, storage));
// For npm request
app.use(require('./endpoint')(config, auth, storage));
if (config.web && config.web.enable === false) {
app.get('/', function(req, res, next) {
next( Error[404]('web interface is disabled in the config file') );
});
// For WebUI & WebUI API
if (_.get(config, 'web.enable', true)) {
app.use('/', require('./web')(config, auth, storage));
app.use('/-/verdaccio/', require('./web/api')(config, auth, storage));
} else {
app.use(require('./web/index')(config, auth, storage));
app.get('/', function(req, res, next) {
next(Error[404]('Web interface is disabled in the config file'));
});
}
// Catch 404
app.get('/*', function(req, res, next) {
next( Error[404]('file not found') );
next(Error[404]('File not found'));
});
app.use(function(err, req, res, next) {
if (Object.prototype.toString.call(err) !== '[object Error]') {
if (_.isError(err)) {
if (err.code === 'ECONNABORT' && res.statusCode === 304) {
return next();
}
if (typeof res.report_error !== 'function') {
// in case of very early error this middleware may not be loaded before error is generated
// fixing that
error_reporting_middleware(req, res, _.noop);
}
res.report_error(err);
} else {
// Fall to Middleware.final
return next(err);
}
if (err.code === 'ECONNABORT' && res.statusCode === 304) {
return next();
}
if (typeof(res.report_error) !== 'function') {
// in case of very early error this middleware may not be loaded before error is generated
// fixing that
error_reporting_middleware(req, res, function() {});
}
res.report_error(err);
});
app.use(Middleware.final);

View file

@ -1,28 +1,26 @@
'use strict';
const async = require('async');
const bodyParser = require('body-parser');
const Cookies = require('cookies');
const escape = require('js-string-escape');
const express = require('express');
const fs = require('fs');
const Handlebars = require('handlebars');
const marked = require('marked');
const Search = require('../search');
const Search = require('../../lib/search');
const Middleware = require('./middleware');
const Utils = require('../utils');
const match = Middleware.match;
const validateName = Middleware.validate_name;
const validatePkg = Middleware.validate_package;
const securityIframe = Middleware.securityIframe;
/*
This file include all verdaccio only API(Web UI), for npm API please see ../endpoint/
*/
module.exports = function(config, auth, storage) {
Search.configureStorage(storage);
/* eslint new-cap:off */
const app = express.Router();
/* eslint new-cap:off */
const can = Middleware.allow(auth);
let template;
// validate all of these params as a package name
// this might be too harsh, so ask if it causes trouble
@ -36,76 +34,6 @@ module.exports = function(config, auth, storage) {
app.use(auth.cookie_middleware());
app.use(securityIframe);
Handlebars.registerPartial('entry', fs.readFileSync(require.resolve('./ui/entry.hbs'), 'utf8'));
if (config.web && config.web.template) {
template = Handlebars.compile(fs.readFileSync(config.web.template, 'utf8'));
} else {
template = Handlebars.compile(fs.readFileSync(require.resolve('./ui/index.hbs'), 'utf8'));
}
app.get('/', function(req, res, next) {
let base = Utils.combineBaseUrl(Utils.getWebProtocol(req), req.get('host'), config.url_prefix);
res.setHeader('Content-Type', 'text/html');
storage.get_local(function(err, packages) {
if (err) {
throw err;
} // that function shouldn't produce any
async.filterSeries(packages, function(pkg, cb) {
auth.allow_access(pkg.name, req.remote_user, function(err, allowed) {
setImmediate(function() {
if (err) {
cb(null, false);
} else {
cb(err, allowed);
}
});
});
}, function(err, packages) {
if (err) throw err;
packages.sort(function(p1, p2) {
if (p1.name < p2.name) {
return -1;
} else {
return 1;
}
});
let json = {
packages: packages,
tagline: config.web && config.web.tagline ? config.web.tagline : '',
baseUrl: base,
username: req.remote_user.name,
};
next(template({
name: config.web && config.web.title ? config.web.title : 'Verdaccio',
data: escape(JSON.stringify(json)),
}));
});
});
});
// Static
app.get('/-/static/:filename', function(req, res, next) {
let file = __dirname + '/static/' + req.params.filename;
res.sendFile(file, function(err) {
if (!err) {
return;
}
if (err.status === 404) {
next();
} else {
next(err);
}
});
});
app.get('/-/logo', function(req, res, next) {
res.sendFile( config.web && config.web.logo
? config.web.logo
: __dirname + '/static/logo-sm.png' );
});
app.post('/-/login', function(req, res, next) {
auth.authenticate(req.body.user, req.body.pass, (err, user) => {
if (!err) {

103
src/api/web/index.js Normal file
View file

@ -0,0 +1,103 @@
'use strict';
const async = require('async');
const Cookies = require('cookies');
const escape = require('js-string-escape');
const express = require('express');
const fs = require('fs');
const Handlebars = require('handlebars');
const Search = require('../../lib/search');
const Middleware = require('./middleware');
const Utils = require('../../lib/utils');
const securityIframe = Middleware.securityIframe;
/* eslint new-cap:off */
const router = express.Router();
const _ = require('lodash');
const env = require('../../config/env');
module.exports = function(config, auth, storage) {
Search.configureStorage(storage);
router.use(Cookies.express());
router.use(auth.cookie_middleware());
router.use(securityIframe);
Handlebars.registerPartial('entry', fs.readFileSync(require.resolve('../../webui/src/entry.hbs'), 'utf8'));
let template;
if (config.web && config.web.template) {
template = Handlebars.compile(fs.readFileSync(config.web.template, 'utf8'));
} else {
template = Handlebars.compile(fs.readFileSync(require.resolve('../../webui/src/index.hbs'), 'utf8'));
}
// Static
router.get('/-/static/:filename', function(req, res, next) {
let file = `${env.APP_ROOT}/static/${req.params.filename}`;
res.sendFile(file, function(err) {
if (!err) {
return;
}
if (err.status === 404) {
next();
} else {
next(err);
}
});
});
router.get('/-/logo', function(req, res, next) {
res.sendFile(_.get(config, 'web.logo') || `${env.APP_ROOT}/static/logo-sm.png`
);
});
router.get('/', function(req, res, next) {
res.setHeader('Content-Type', 'text/html');
const base = Utils.combineBaseUrl(req.protocol, req.get('host'), config.url_prefix);
storage.get_local(function(err, packages) {
if (err) {
throw err;
} // that function shouldn't produce any
async.filterSeries(
packages,
function(pkg, cb) {
auth.allow_access(pkg.name, req.remote_user, function(err, allowed) {
setImmediate(function() {
if (err) {
cb(null, false);
} else {
cb(err, allowed);
}
});
});
},
function(err, packages) {
if (err) throw err;
packages.sort(function(a, b) {
if (a.name < b.name) {
return -1;
} else {
return 1;
}
});
let json = {
packages: packages,
tagline: config.web && config.web.tagline ? config.web.tagline : '',
baseUrl: base,
username: req.remote_user.name,
};
next(template({
name: config.web && config.web.title ? config.web.title : 'Verdaccio',
data: escape(JSON.stringify(json)),
}));
}
);
});
});
return router;
};

View file

@ -5,8 +5,8 @@
const crypto = require('crypto');
const _ = require('lodash');
const createError = require('http-errors');
const utils = require('../utils');
const Logger = require('../logger');
const utils = require('../../lib/utils');
const Logger = require('../../lib/logger');
module.exports.match = function match(regexp) {

6
src/config/env.js Normal file
View file

@ -0,0 +1,6 @@
const path = require('path');
module.exports = {
APP_ROOT: path.resolve(__dirname, '../../'),
SRC_ROOT: path.resolve(__dirname, '../'),
};

View file

@ -8,7 +8,7 @@ const jju = require('jju');
const Error = require('http-errors');
const Logger = require('./logger');
const load_plugins = require('./plugin-loader').load_plugins;
const pkgJson = require('../package.json');
const pkgJson = require('../../package.json');
/**
* Handles the authentification, load auth plugins.
*/

View file

@ -29,7 +29,7 @@ const https = require('https');
const YAML = require('js-yaml');
const Path = require('path');
const URL = require('url');
const server = require('./index');
const server = require('../api/index');
const Utils = require('./utils');
const pkginfo = require('pkginfo')(module); // eslint-disable-line no-unused-vars
const pkgVersion = module.exports.version;

View file

@ -4,7 +4,7 @@ const fs = require('fs');
const Path = require('path');
const logger = require('./logger');
const CONFIG_FILE = 'config.yaml';
const pkgJson = require('../package.json');
const pkgJson = require('../../package.json');
/**
* Find and get the first config file that match.
* @return {String} the config file path
@ -28,7 +28,7 @@ function create_config_file(config_path) {
require('mkdirp').sync(Path.dirname(config_path.path));
logger.logger.info({file: config_path.path}, 'Creating default config file in @{file}');
let created_config = fs.readFileSync(require.resolve('../conf/default.yaml'), 'utf8');
let created_config = fs.readFileSync(require.resolve('../../conf/default.yaml'), 'utf8');
if (config_path.type === 'xdg') {
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored,

View file

@ -5,7 +5,7 @@ const Error = require('http-errors');
const Stream = require('stream');
const chalk = require('chalk');
const Utils = require('./utils');
const pkgJSON = require('../package.json');
const pkgJSON = require('../../package.json');
/**
* Match the level based on buyan severity scale

View file

@ -34,7 +34,7 @@ function load_plugins(config, plugin_configs, params, sanity_check) {
let plugin;
// try local plugins first
plugin = try_load(Path.resolve(__dirname + '/plugins', p));
plugin = try_load(Path.resolve(__dirname + '/..//plugins', p));
// npm package
if (plugin === null && p.match(/^[^\.\/]/)) {

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -2,7 +2,7 @@
const assert = require('assert');
const config_hash = require('./partials/config');
const Config = require('../../lib/config');
const Config = require('../../src/lib/config');
describe('Config', function() {

View file

@ -1,7 +1,7 @@
'use strict';
let assert = require('assert');
let parse = require('../../lib/utils').parse_address;
let parse = require('../../src/lib/utils').parse_address;
describe('Parse address', function() {
function addTest(what, proto, host, port) {

View file

@ -1,6 +1,6 @@
'use strict';
let ReadTarball = require('../../lib/storage/streams').ReadTarball;
let ReadTarball = require('../../src/lib/storage/streams').ReadTarball;
describe('mystreams', function() {
it('should delay events', function(cb) {

View file

@ -1,9 +1,9 @@
'use strict';
let assert = require('assert');
let Storage = require('../../lib/storage/up-storage');
let Storage = require('../../src/lib/storage/up-storage');
require('../../lib/logger').setup([]);
require('../../src/lib/logger').setup([]);
function setup(host, config, mainconfig) {
config.url = host;

View file

@ -1,7 +1,7 @@
'use strict';
let assert = require('assert');
let parseInterval = require('../../lib/utils').parseInterval;
let parseInterval = require('../../src/lib/utils').parseInterval;
describe('Parse interval', function() {
function add_test(str, res) {

View file

@ -1,7 +1,7 @@
'use strict';
const assert = require('assert');
const load_plugins = require('../../lib/plugin-loader').load_plugins;
const load_plugins = require('../../src/lib/plugin-loader').load_plugins;
const path = require('path');
describe('plugin loader', function() {

View file

@ -1,12 +1,12 @@
'use strict';
let assert = require('assert');
let Search = require('../../lib/search');
let Storage = require('../../lib/storage');
let Search = require('../../src/lib/search');
let Storage = require('../../src/lib/storage');
let config_hash = require('./partials/config');
let Config = require('../../lib/config');
let Config = require('../../src/lib/config');
require('../../lib/logger').setup([]);
require('../../src/lib/logger').setup([]);
let packages = [
{

View file

@ -1,10 +1,10 @@
'use strict';
let assert = require('assert');
let semver_sort = require('../../lib/utils').semver_sort;
let merge = require('../../lib/storage')._merge_versions;
let semver_sort = require('../../src/lib/utils').semver_sort;
let merge = require('../../src/lib/storage')._merge_versions;
require('../../lib/logger').setup([]);
require('../../src/lib/logger').setup([]);
describe('Merge', function() {
it('simple', function() {

View file

@ -1,9 +1,9 @@
'use strict';
let assert = require('assert');
let tag_version = require('../../lib/utils').tag_version;
let tag_version = require('../../src/lib/utils').tag_version;
require('../../lib/logger').setup([]);
require('../../src/lib/logger').setup([]);
describe('tag_version', function() {
it('add new one', function() {

View file

@ -1,7 +1,7 @@
'use strict';
let assert = require('assert');
let validate = require('../../lib/utils').validate_name;
let validate = require('../../src/lib/utils').validate_name;
describe('Validate', function() {
it('good ones', function() {

View file

@ -6,13 +6,13 @@ const assert = require('assert');
const path = require('path');
describe('index.js app', test('index.js'));
describe('api.js app', test('api/api.js'));
describe('index.js app', test('../endpoint/index.js'));
describe('index.js app', test('index.js'));
function test(file) {
return function() {
let requirePath = path.normalize(path.join(__dirname + '/../../lib/web/', file));
let requirePath = path.normalize(path.join(__dirname + '/../../src/api/web/', file));
let source = require('fs').readFileSync(requirePath, 'utf8');
let very_scary_regexp = /\n\s*app\.(\w+)\s*\(\s*(("[^"]*")|('[^']*'))\s*,/g;

View file

@ -1,12 +1,12 @@
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const env = require('../src/config/env');
module.exports = {
entry: './lib/web/ui/index.js',
entry: `${env.SRC_ROOT}/webui/src/index.js`,
devtool: 'source-map',
output: {
path: path.resolve(__dirname, '../lib/web/static'),
path: `${env.APP_ROOT}/static/`,
filename: 'bundle.js'
},
module: {