From aa7a9a85e754b1c7ee932577bbe0ab99dfbfbba3 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Wed, 7 Jun 2017 23:14:28 +0100 Subject: [PATCH 1/3] eslint->prettier workflow --- package.json | 10 + src/cli/commands.js | 31 +- src/cli/domain/get-components-by-dir.js | 19 +- src/cli/domain/get-components-deps.js | 12 +- src/cli/domain/get-local-npm-modules.js | 10 +- src/cli/domain/get-missing-deps.js | 8 +- src/cli/domain/get-mocked-plugins.js | 36 +- src/cli/domain/local.js | 40 +- src/cli/domain/mock.js | 24 +- src/cli/domain/npm-installer.js | 8 +- src/cli/domain/package-components.js | 165 +++-- .../config/external-dependencies-handlers.js | 17 +- .../bundle/config/index.js | 30 +- .../package-server-script/bundle/index.js | 7 +- src/cli/domain/package-server-script/index.js | 4 +- src/cli/domain/package-static-files/index.js | 45 +- .../package-static-files/minify-file.js | 10 +- src/cli/domain/package-template.js | 58 +- src/cli/domain/registry.js | 157 +++-- src/cli/domain/url-parser.js | 19 +- src/cli/domain/watch.js | 27 +- src/cli/facade/dev.js | 145 ++-- src/cli/facade/init.js | 18 +- src/cli/facade/mock.js | 14 +- src/cli/facade/package.js | 14 +- src/cli/facade/preview.js | 8 +- src/cli/facade/publish.js | 117 ++-- src/cli/facade/registry-add.js | 10 +- src/cli/facade/registry-ls.js | 12 +- src/cli/facade/registry-remove.js | 10 +- src/cli/facade/registry.js | 5 +- src/cli/index.js | 66 +- src/cli/logger.js | 3 +- src/cli/validate-command.js | 4 +- src/cli/wrap-cli-callback.js | 8 +- src/components/oc-client/src/oc-client.js | 369 +++++----- src/registry/app-start.js | 56 +- src/registry/domain/authentication.js | 25 +- .../components-cache/components-list.js | 40 +- src/registry/domain/components-cache/index.js | 57 +- src/registry/domain/components-details.js | 72 +- src/registry/domain/events-handler.js | 16 +- src/registry/domain/extract-package.js | 37 +- .../domain/get-package-json-from-temp-dir.js | 2 +- src/registry/domain/nested-renderer.js | 109 +-- src/registry/domain/options-sanitiser.js | 31 +- src/registry/domain/plugins-detective.js | 2 +- src/registry/domain/plugins-initialiser.js | 64 +- src/registry/domain/repository.js | 333 ++++++--- src/registry/domain/require-wrapper.js | 19 +- src/registry/domain/s3.js | 143 ++-- src/registry/domain/sanitiser.js | 50 +- src/registry/domain/url-builder.js | 12 +- .../domain/validators/component-parameters.js | 118 ++-- src/registry/domain/validators/index.js | 10 +- .../domain/validators/node-version.js | 8 +- .../domain/validators/oc-cli-version.js | 14 +- .../validators/package-json-validator.js | 9 +- .../domain/validators/plugins-requirements.js | 12 +- .../validators/registry-configuration.js | 85 ++- .../domain/validators/uploaded-package.js | 14 +- src/registry/domain/version-handler.js | 10 +- src/registry/index.js | 95 +-- src/registry/middleware/base-url-handler.js | 9 +- src/registry/middleware/cors.js | 7 +- src/registry/middleware/discovery-handler.js | 9 +- src/registry/middleware/file-uploads.js | 11 +- src/registry/middleware/index.js | 7 +- src/registry/middleware/request-handler.js | 8 +- src/registry/router.js | 65 +- src/registry/routes/component-info.js | 67 +- src/registry/routes/component-preview.js | 59 +- src/registry/routes/component.js | 40 +- src/registry/routes/components.js | 65 +- .../routes/helpers/apply-default-values.js | 18 +- .../helpers/get-available-dependencies.js | 20 +- .../routes/helpers/get-component-fallback.js | 139 ++-- .../helpers/get-component-retrieving-info.js | 8 +- src/registry/routes/helpers/get-component.js | 638 ++++++++++-------- .../routes/helpers/get-components-history.js | 17 +- .../routes/helpers/is-url-discoverable.js | 26 +- src/registry/routes/index.js | 125 ++-- src/registry/routes/publish.js | 97 ++- src/registry/routes/static-redirector.js | 48 +- src/registry/views/static/component-info.js | 14 +- src/registry/views/static/index.js | 32 +- src/resources/index.js | 126 ++-- src/utils/date-stringify.js | 19 +- src/utils/get-file-info.js | 4 +- src/utils/get-mime-type.js | 2 +- src/utils/get-next-year.js | 4 +- src/utils/get-unix-utc-timestamp.js | 12 +- src/utils/hash-builder.js | 2 +- src/utils/pad-zero.js | 2 +- src/utils/put.js | 16 +- src/utils/require-template.js | 24 +- 96 files changed, 2833 insertions(+), 1890 deletions(-) diff --git a/package.json b/package.json index 4b1efcdc5..f739ee54c 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,15 @@ "oc": "./src/oc-cli.js" }, "scripts": { + "precommit": "lint-staged", "test": "grunt test" }, + "lint-staged": { + "*.js": [ + "prettier-eslint --single-quote --write", + "git add" + ] + }, "engines": { "node": ">=4" }, @@ -35,6 +42,7 @@ "grunt-git": "^1.0.0", "grunt-karma": "^2.0.0", "grunt-mocha-test": "^0.12.7", + "husky": "^0.13.4", "injectr": "0.5.1", "jasmine-core": "^2.5.1", "karma": "^1.3.0", @@ -42,9 +50,11 @@ "karma-phantomjs-launcher": "^1.0.2", "karma-sauce-launcher": "^1.0.0", "karma-sinon": "^1.0.5", + "lint-staged": "^3.6.0", "load-grunt-tasks": "^3.5.2", "mocha": "^3.0.2", "phantomjs-prebuilt": "^2.1.12", + "prettier-eslint-cli": "^4.0.4", "semver-sort": "0.0.4", "sinon": "^1.17.5" }, diff --git a/src/cli/commands.js b/src/cli/commands.js index 8eb0c117f..7e4eea970 100644 --- a/src/cli/commands.js +++ b/src/cli/commands.js @@ -4,20 +4,23 @@ module.exports = { usage: 'Usage: $0 [options]', commands: { - dev: { cmd: 'dev [port] [baseUrl]', example: { - cmd: '$0 dev ../all-components 3001 127.0.0.1:3001 --fallbackRegistryUrl=http://anotherhost:anotherport/' + cmd: + '$0 dev ../all-components 3001 127.0.0.1:3001 --fallbackRegistryUrl=http://anotherhost:anotherport/' }, - description: 'Runs a local oc test registry in order to develop and test components', + description: + 'Runs a local oc test registry in order to develop and test components', options: { fallbackRegistryUrl: { - description: 'Url to another registry which will be used by dev registry when component cannot be found in local registry', + description: + 'Url to another registry which will be used by dev registry when component cannot be found in local registry' }, hotReloading: { boolean: true, - description: 'Enables hot reloading. Note: when hot reloading is set to true, each request to the component will make the registry to create a new instance for the javascript closures to be loaded, while when false the instance will be recycled between components executions', + description: + 'Enables hot reloading. Note: when hot reloading is set to true, each request to the component will make the registry to create a new instance for the javascript closures to be loaded, while when false the instance will be recycled between components executions', default: true }, verbose: { @@ -34,7 +37,8 @@ module.exports = { example: { cmd: '$0 init test-component jade' }, - description: 'Creates a new empty component [of either jade or handlebars template type] in the current folder', + description: + 'Creates a new empty component [of either jade or handlebars template type] in the current folder', usage: 'Usage: $0 init [templateType]' }, @@ -42,16 +46,19 @@ module.exports = { cmd: 'mock ', example: { cmd: '$0 mock plugin hash "always-returned-value"', - description: 'Creates static mock for a "hash" plugin which always returns "always-returned-value" value' + description: + 'Creates static mock for a "hash" plugin which always returns "always-returned-value" value' }, - description: 'Allows to mock configuration in order to facilitate local development', + description: + 'Allows to mock configuration in order to facilitate local development', usage: 'Usage: $0 mock ' }, preview: { cmd: 'preview ', example: { - cmd: '$0 preview "http://localhost:3000/my-new-component/1.0.0/?param1=hello&name=Arthur"' + cmd: + '$0 preview "http://localhost:3000/my-new-component/1.0.0/?param1=hello&name=Arthur"' }, description: 'Runs a test page consuming a component', usage: 'Usage: $0 preview ' @@ -80,10 +87,12 @@ module.exports = { }, options: { password: { - description: 'password used to authenticate when publishing to registry' + description: + 'password used to authenticate when publishing to registry' }, username: { - description: 'username used to authenticate when publishing to registry' + description: + 'username used to authenticate when publishing to registry' } }, description: 'Publish a component', diff --git a/src/cli/domain/get-components-by-dir.js b/src/cli/domain/get-components-by-dir.js index 87016fbcb..515cc1e36 100644 --- a/src/cli/domain/get-components-by-dir.js +++ b/src/cli/domain/get-components-by-dir.js @@ -4,21 +4,16 @@ const fs = require('fs-extra'); const path = require('path'); const _ = require('lodash'); -module.exports = function(){ - - return function(componentsDir, callback){ - - const isOcComponent = function(file){ - +module.exports = function() { + return function(componentsDir, callback) { + const isOcComponent = function(file) { const filePath = path.resolve(componentsDir, file), packagePath = path.join(filePath, 'package.json'); let content; try { content = fs.readJsonSync(packagePath); - } - catch(err) - { + } catch (err) { return false; } @@ -35,11 +30,13 @@ module.exports = function(){ try { dirContent = fs.readdirSync(componentsDir); - } catch(err){ + } catch (err) { return callback(null, []); } - const components = dirContent.filter(isOcComponent).map((component) => path.resolve(componentsDir, component)); + const components = dirContent + .filter(isOcComponent) + .map(component => path.resolve(componentsDir, component)); callback(null, components); }; diff --git a/src/cli/domain/get-components-deps.js b/src/cli/domain/get-components-deps.js index ca9a577e3..b5311a35b 100644 --- a/src/cli/domain/get-components-deps.js +++ b/src/cli/domain/get-components-deps.js @@ -4,19 +4,19 @@ const coreModules = require('builtin-modules'); const format = require('stringformat'); const fs = require('fs-extra'); const path = require('path'); -const _ = require('lodash'); +const _ = require('lodash'); const settings = require('../../resources'); -module.exports = function(components){ +module.exports = function(components) { const deps = { modules: {}, withVersions: {}, templates: {} }; const legacyTemplates = { - 'jade': true, - 'handlebars': true + jade: true, + handlebars: true }; - components.forEach((c) => { + components.forEach(c => { const pkg = fs.readJsonSync(path.join(c, 'package.json')); const type = pkg.oc.files.template.type; const dependencies = pkg.dependencies || {}; @@ -28,7 +28,7 @@ module.exports = function(components){ deps.templates[type] = true; } - _.keys(dependencies).forEach((name) => { + _.keys(dependencies).forEach(name => { const version = dependencies[name]; const depToInstall = version.length > 0 ? `${name}@${version}` : name; diff --git a/src/cli/domain/get-local-npm-modules.js b/src/cli/domain/get-local-npm-modules.js index 717b0afe2..e55f8008e 100644 --- a/src/cli/domain/get-local-npm-modules.js +++ b/src/cli/domain/get-local-npm-modules.js @@ -3,17 +3,15 @@ const fs = require('fs-extra'); const path = require('path'); -module.exports = function(){ - return function(componentsDir){ - +module.exports = function() { + return function(componentsDir) { const nodeFolder = path.join(componentsDir, 'node_modules'); - if(!fs.existsSync(nodeFolder)){ + if (!fs.existsSync(nodeFolder)) { return []; } - return fs.readdirSync(nodeFolder).filter((file) => { - + return fs.readdirSync(nodeFolder).filter(file => { const filePath = path.resolve(nodeFolder, file), isBin = file === '.bin', isDir = fs.lstatSync(filePath).isDirectory(); diff --git a/src/cli/domain/get-missing-deps.js b/src/cli/domain/get-missing-deps.js index 3e8992cf9..e901e27f8 100644 --- a/src/cli/domain/get-missing-deps.js +++ b/src/cli/domain/get-missing-deps.js @@ -3,12 +3,10 @@ const path = require('path'); const _ = require('lodash'); -module.exports = (dependencies) => { - +module.exports = dependencies => { const missing = []; - _.forEach(dependencies, (npmModule) => { - + _.forEach(dependencies, npmModule => { const index = npmModule.indexOf('@'); let moduleName = npmModule; @@ -19,7 +17,7 @@ module.exports = (dependencies) => { const pathToModule = path.resolve('node_modules/', moduleName); try { - if(require.cache[pathToModule]){ + if (require.cache[pathToModule]) { delete require.cache[pathToModule]; } diff --git a/src/cli/domain/get-mocked-plugins.js b/src/cli/domain/get-mocked-plugins.js index ca7d5265a..fe9c1cb1c 100644 --- a/src/cli/domain/get-mocked-plugins.js +++ b/src/cli/domain/get-mocked-plugins.js @@ -8,16 +8,16 @@ const _ = require('lodash'); const settings = require('../../resources/settings'); const strings = require('../../resources/'); -const registerStaticMocks = function(mocks, logger){ +const registerStaticMocks = function(mocks, logger) { return _.map(mocks, (mockedValue, pluginName) => { logger.log(colors.green('├── ' + pluginName + ' () => ' + mockedValue)); return { name: pluginName, register: { - register: function(options, dependencies, next){ + register: function(options, dependencies, next) { return next(); }, - execute: function(){ + execute: function() { return mockedValue; } } @@ -25,18 +25,17 @@ const registerStaticMocks = function(mocks, logger){ }); }; -const registerDynamicMocks = function(ocJsonLocation, mocks, logger){ +const registerDynamicMocks = function(ocJsonLocation, mocks, logger) { return _.map(mocks, (source, pluginName) => { - let p; try { p = require(path.resolve(ocJsonLocation, source)); - } catch(er) { + } catch (er) { logger.err(er.toString()); return; } - if(!_.isFunction(p)){ + if (!_.isFunction(p)) { logger.err(strings.errors.cli.MOCK_PLUGIN_IS_NOT_A_FUNCTION); return; } @@ -45,17 +44,16 @@ const registerDynamicMocks = function(ocJsonLocation, mocks, logger){ return { name: pluginName, register: { - register: function(options, dependencies, next){ + register: function(options, dependencies, next) { return next(); }, execute: p } }; - }).filter((p) => p); + }).filter(p => p); }; const findPath = function(pathToResolve, fileName) { - const rootDir = fs.realpathSync('.'), fileToResolve = path.join(pathToResolve, fileName); @@ -63,7 +61,9 @@ const findPath = function(pathToResolve, fileName) { if (pathToResolve === rootDir) { return undefined; } else { - const getParent = function(x){ return x.split('/').slice(0, -1).join('/'); }, + const getParent = function(x) { + return x.split('/').slice(0, -1).join('/'); + }, parentDir = pathToResolve ? getParent(pathToResolve) : rootDir; return findPath(parentDir, fileName); @@ -73,28 +73,32 @@ const findPath = function(pathToResolve, fileName) { return fileToResolve; }; -module.exports = function(logger, componentsDir){ +module.exports = function(logger, componentsDir) { componentsDir = path.resolve(componentsDir || '.'); let plugins = []; const ocJsonFileName = settings.configFile.src.replace('./', ''), ocJsonPath = findPath(componentsDir, ocJsonFileName); - if(!ocJsonPath){ + if (!ocJsonPath) { return plugins; } const content = fs.readJsonSync(ocJsonPath), ocJsonLocation = ocJsonPath.slice(0, -ocJsonFileName.length); - if(!content.mocks || !content.mocks.plugins){ + if (!content.mocks || !content.mocks.plugins) { return plugins; } logger.warn(strings.messages.cli.REGISTERING_MOCKED_PLUGINS); - plugins = plugins.concat(registerStaticMocks(content.mocks.plugins.static, logger)); - plugins = plugins.concat(registerDynamicMocks(ocJsonLocation, content.mocks.plugins.dynamic, logger)); + plugins = plugins.concat( + registerStaticMocks(content.mocks.plugins.static, logger) + ); + plugins = plugins.concat( + registerDynamicMocks(ocJsonLocation, content.mocks.plugins.dynamic, logger) + ); return plugins; }; diff --git a/src/cli/domain/local.js b/src/cli/domain/local.js index 44b33c5fd..601bada09 100644 --- a/src/cli/domain/local.js +++ b/src/cli/domain/local.js @@ -11,39 +11,39 @@ const packageComponents = require('./package-components'); const mock = require('./mock'); const validator = require('../../registry/domain/validators'); -module.exports = function(){ - +module.exports = function() { return _.extend(this, { - cleanup: function(compressedPackagePath, callback){ + cleanup: function(compressedPackagePath, callback) { return fs.unlink(compressedPackagePath, callback); }, - compress: function(input, output, callback){ - return targz.compress({ - src: input, - dest: output, - tar: { - map: function(file){ - return _.extend(file, { - name: '_package/' + file.name - }); + compress: function(input, output, callback) { + return targz.compress( + { + src: input, + dest: output, + tar: { + map: function(file) { + return _.extend(file, { + name: '_package/' + file.name + }); + } } - } - }, callback); + }, + callback + ); }, getComponentsByDir: getComponentsByDir(), getLocalNpmModules: getLocalNpmModules(), - init: function(componentName, templateType, callback){ - - if(!validator.validateComponentName(componentName)){ + init: function(componentName, templateType, callback) { + if (!validator.validateComponentName(componentName)) { return callback('name not valid'); } - if(!validator.validateTemplateType(templateType)){ + if (!validator.validateTemplateType(templateType)) { return callback('template type not valid'); } try { - const pathDir = '../../components/base-component-' + templateType, baseComponentDir = path.resolve(__dirname, pathDir), npmIgnorePath = path.resolve(__dirname, pathDir + '/.npmignore'); @@ -60,7 +60,7 @@ module.exports = function(){ fs.outputJsonSync(componentPath, component); return callback(null, { ok: true }); - } catch(e){ + } catch (e) { return callback(e); } }, diff --git a/src/cli/domain/mock.js b/src/cli/domain/mock.js index 9f47b77b7..40edd69f5 100644 --- a/src/cli/domain/mock.js +++ b/src/cli/domain/mock.js @@ -5,35 +5,39 @@ const path = require('path'); const settings = require('../../resources/settings'); -module.exports = function(){ - return function(params, callback){ - +module.exports = function() { + return function(params, callback) { fs.readJson(settings.configFile.src, (err, localConfig) => { - localConfig = localConfig || {}; const mockType = params.targetType + 's'; - if(!localConfig.mocks){ + if (!localConfig.mocks) { localConfig.mocks = {}; } - if(!localConfig.mocks[mockType]){ + if (!localConfig.mocks[mockType]) { localConfig.mocks[mockType] = {}; } let pluginType = 'static'; - if(fs.existsSync(path.resolve(params.targetValue.toString()))){ + if (fs.existsSync(path.resolve(params.targetValue.toString()))) { pluginType = 'dynamic'; } - if(!localConfig.mocks[mockType][pluginType]){ + if (!localConfig.mocks[mockType][pluginType]) { localConfig.mocks[mockType][pluginType] = {}; } - localConfig.mocks[mockType][pluginType][params.targetName] = params.targetValue; + localConfig.mocks[mockType][pluginType][params.targetName] = + params.targetValue; - return fs.writeJson(settings.configFile.src, localConfig, {spaces: 2}, callback); + return fs.writeJson( + settings.configFile.src, + localConfig, + { spaces: 2 }, + callback + ); }); }; }; diff --git a/src/cli/domain/npm-installer.js b/src/cli/domain/npm-installer.js index cc33372ea..9d87a371f 100644 --- a/src/cli/domain/npm-installer.js +++ b/src/cli/domain/npm-installer.js @@ -3,9 +3,11 @@ const npm = require('npm'); const path = require('path'); -module.exports = function(dependencies, cb){ - npm.load({}, (npmEr) => { - if(npmEr){ return cb(npmEr); } +module.exports = function(dependencies, cb) { + npm.load({}, npmEr => { + if (npmEr) { + return cb(npmEr); + } npm.commands.install(path.resolve('.'), dependencies, cb); }); }; diff --git a/src/cli/domain/package-components.js b/src/cli/domain/package-components.js index e3f1f0ac6..6c560f0bf 100644 --- a/src/cli/domain/package-components.js +++ b/src/cli/domain/package-components.js @@ -11,16 +11,15 @@ const packageTemplate = require('./package-template'); const getUnixUtcTimestamp = require('../../utils/get-unix-utc-timestamp'); const validator = require('../../registry/domain/validators'); -module.exports = function(){ - return function(options, callback){ - +module.exports = function() { + return function(options, callback) { const componentPath = options.componentPath; const minify = options.minify === true; const files = fs.readdirSync(componentPath), publishPath = path.join(componentPath, '_package'); - if(_.includes(files, '_package')){ + if (_.includes(files, '_package')) { fs.removeSync(publishPath); } @@ -29,85 +28,105 @@ module.exports = function(){ const componentPackagePath = path.join(componentPath, 'package.json'), ocPackagePath = path.join(__dirname, '../../../package.json'); - if(!fs.existsSync(componentPackagePath)){ + if (!fs.existsSync(componentPackagePath)) { return callback(new Error('component does not contain package.json')); - } else if(!fs.existsSync(ocPackagePath)){ + } else if (!fs.existsSync(ocPackagePath)) { return callback(new Error('error resolving oc internal dependencies')); } const component = fs.readJsonSync(componentPackagePath), ocInfo = fs.readJsonSync(ocPackagePath); - if(!validator.validateComponentName(component.name)){ + if (!validator.validateComponentName(component.name)) { return callback(new Error('name not valid')); } - async.waterfall([ - function(cb){ - // Packaging template.js - - packageTemplate({ - componentName: component.name, - componentPath: componentPath, - ocOptions: component.oc, - publishPath: publishPath - }, (err, packagedTemplateInfo) => { - if(err){ return cb(err); } - - component.oc.files.template = packagedTemplateInfo; - delete component.oc.files.client; - cb(err, component); - }); - }, - function(component, cb){ - // Packaging server.js - - if(!component.oc.files.data){ - return cb(null, component); - } - - packageServerScript({ - componentPath: componentPath, - dependencies: component.dependencies, - ocOptions: component.oc, - publishPath: publishPath, - verbose: options.verbose - }, (err, packagedServerScriptInfo) => { - if(err){ return cb(err); } - - component.oc.files.dataProvider = packagedServerScriptInfo; - delete component.oc.files.data; - cb(err, component); - }); - }, - function(component, cb){ - // Packaging package.json - - component.oc.version = ocInfo.version; - component.oc.packaged = true; - component.oc.date = getUnixUtcTimestamp(); - - if(!component.oc.files.static){ - component.oc.files.static = []; + async.waterfall( + [ + function(cb) { + // Packaging template.js + + packageTemplate( + { + componentName: component.name, + componentPath: componentPath, + ocOptions: component.oc, + publishPath: publishPath + }, + (err, packagedTemplateInfo) => { + if (err) { + return cb(err); + } + + component.oc.files.template = packagedTemplateInfo; + delete component.oc.files.client; + cb(err, component); + } + ); + }, + function(component, cb) { + // Packaging server.js + + if (!component.oc.files.data) { + return cb(null, component); + } + + packageServerScript( + { + componentPath: componentPath, + dependencies: component.dependencies, + ocOptions: component.oc, + publishPath: publishPath, + verbose: options.verbose + }, + (err, packagedServerScriptInfo) => { + if (err) { + return cb(err); + } + + component.oc.files.dataProvider = packagedServerScriptInfo; + delete component.oc.files.data; + cb(err, component); + } + ); + }, + function(component, cb) { + // Packaging package.json + + component.oc.version = ocInfo.version; + component.oc.packaged = true; + component.oc.date = getUnixUtcTimestamp(); + + if (!component.oc.files.static) { + component.oc.files.static = []; + } + + if (!_.isArray(component.oc.files.static)) { + component.oc.files.static = [component.oc.files.static]; + } + + fs.writeJson( + path.join(publishPath, 'package.json'), + component, + err => { + cb(err, component); + } + ); + }, + function(component, cb) { + // Packaging static files + packageStaticFiles( + { + componentPath: componentPath, + publishPath: publishPath, + minify: minify, + ocOptions: component.oc + }, + err => cb(err, component) + ); } - - if(!_.isArray(component.oc.files.static)){ - component.oc.files.static = [component.oc.files.static]; - } - - fs.writeJson(path.join(publishPath, 'package.json'), component, (err) => { - cb(err, component); - }); - }, - function(component, cb){ - // Packaging static files - packageStaticFiles({ - componentPath: componentPath, - publishPath: publishPath, - minify: minify, - ocOptions: component.oc - }, (err) => cb(err, component)); - } - ], callback); + ], + callback + ); }; }; diff --git a/src/cli/domain/package-server-script/bundle/config/external-dependencies-handlers.js b/src/cli/domain/package-server-script/bundle/config/external-dependencies-handlers.js index cda10c1c2..6dbbe5504 100644 --- a/src/cli/domain/package-server-script/bundle/config/external-dependencies-handlers.js +++ b/src/cli/domain/package-server-script/bundle/config/external-dependencies-handlers.js @@ -14,8 +14,7 @@ const _ = require('lodash'); const strings = require('../../../../../resources'); - -module.exports = function externalDependenciesHandlers(dependencies){ +module.exports = function externalDependenciesHandlers(dependencies) { const deps = dependencies || {}; const missingExternalDependency = (dep, dependencies) => @@ -26,10 +25,20 @@ module.exports = function externalDependenciesHandlers(dependencies){ if (/^[a-z@][a-z\-\/0-9]+$/i.test(req)) { let dependencyName = req; if (/\//g.test(dependencyName)) { - dependencyName = dependencyName.substring(0, dependencyName.indexOf('/')); + dependencyName = dependencyName.substring( + 0, + dependencyName.indexOf('/') + ); } if (missingExternalDependency(dependencyName, deps)) { - return callback(new Error(format(strings.errors.cli.SERVERJS_DEPENDENCY_NOT_DECLARED, JSON.stringify(dependencyName)))); + return callback( + new Error( + format( + strings.errors.cli.SERVERJS_DEPENDENCY_NOT_DECLARED, + JSON.stringify(dependencyName) + ) + ) + ); } } callback(); diff --git a/src/cli/domain/package-server-script/bundle/config/index.js b/src/cli/domain/package-server-script/bundle/config/index.js index 1339f3549..5e8561433 100644 --- a/src/cli/domain/package-server-script/bundle/config/index.js +++ b/src/cli/domain/package-server-script/bundle/config/index.js @@ -6,14 +6,14 @@ const path = require('path'); const externalDependenciesHandlers = require('./external-dependencies-handlers'); const BabiliPlugin = require('babili-webpack-plugin'); -module.exports = function webpackConfigGenerator(params){ +module.exports = function webpackConfigGenerator(params) { return { entry: params.dataPath, target: 'node', output: { path: '/build', filename: params.fileName, - libraryTarget: 'commonjs2', + libraryTarget: 'commonjs2' }, externals: externalDependenciesHandlers(params.dependencies), module: { @@ -23,23 +23,26 @@ module.exports = function webpackConfigGenerator(params){ exclude: /node_modules/, use: [ { - loader: 'infinite-loop-loader' + loader: 'infinite-loop-loader' }, { - loader: 'babel-loader', + loader: 'babel-loader', options: { cacheDirectory: true, - 'presets': [ - [require.resolve('babel-preset-env'), { - 'modules': false, - 'targets': { - 'node': 4 + presets: [ + [ + require.resolve('babel-preset-env'), + { + modules: false, + targets: { + node: 4 + } } - }] + ] ] } } - ], + ] } ] }, @@ -50,7 +53,10 @@ module.exports = function webpackConfigGenerator(params){ }) ], resolveLoader: { - modules: ['node_modules', path.resolve(__dirname, '../../../../../../node_modules')] + modules: [ + 'node_modules', + path.resolve(__dirname, '../../../../../../node_modules') + ] } }; }; diff --git a/src/cli/domain/package-server-script/bundle/index.js b/src/cli/domain/package-server-script/bundle/index.js index 560b07efc..d6d53b4ba 100644 --- a/src/cli/domain/package-server-script/bundle/index.js +++ b/src/cli/domain/package-server-script/bundle/index.js @@ -33,11 +33,14 @@ module.exports = function bundle(params, callBack) { const log = stats.toString(params.webpack.stats); - if(log){ + if (log) { console.log(log); } - const serverContentBundled = memoryFs.readFileSync('/build/server.js', 'UTF8'); + const serverContentBundled = memoryFs.readFileSync( + '/build/server.js', + 'UTF8' + ); callBack(warning, serverContentBundled); }); }; diff --git a/src/cli/domain/package-server-script/index.js b/src/cli/domain/package-server-script/index.js index 34e3cc730..016b08704 100644 --- a/src/cli/domain/package-server-script/index.js +++ b/src/cli/domain/package-server-script/index.js @@ -6,7 +6,7 @@ const path = require('path'); const bundle = require('./bundle'); const hashBuilder = require('../../../utils/hash-builder'); -module.exports = function packageServerScript(params, callback){ +module.exports = function packageServerScript(params, callback) { const fileName = 'server.js'; const publishPath = params.publishPath; const webpackParams = { stats: params.verbose ? 'verbose' : 'errors-only' }; @@ -22,7 +22,7 @@ module.exports = function packageServerScript(params, callback){ if (err) { return callback(err); } else { - fs.writeFile(path.join(publishPath, fileName), bundledServer, (err) => { + fs.writeFile(path.join(publishPath, fileName), bundledServer, err => { callback(err, { type: 'node.js', hashKey: hashBuilder.fromString(bundledServer), diff --git a/src/cli/domain/package-static-files/index.js b/src/cli/domain/package-static-files/index.js index 1539b441b..7a5ad2d89 100644 --- a/src/cli/domain/package-static-files/index.js +++ b/src/cli/domain/package-static-files/index.js @@ -10,29 +10,35 @@ const _ = require('lodash'); const strings = require('../../../resources'); -const copyDir = function(params, cb){ +const copyDir = function(params, cb) { const staticPath = path.join(params.componentPath, params.staticDir), exists = fs.existsSync(staticPath), isDir = exists && fs.lstatSync(staticPath).isDirectory(); - if(!exists){ + if (!exists) { return cb(format(strings.errors.cli.FOLDER_NOT_FOUND, staticPath)); - } else if(!isDir){ + } else if (!isDir) { return cb(format(strings.errors.cli.FOLDER_IS_NOT_A_FOLDER, staticPath)); } else { - nodeDir.paths(staticPath, (err, res) => { - _.forEach(res.files, (filePath) => { - + _.forEach(res.files, filePath => { const fileName = path.basename(filePath), fileExt = path.extname(filePath).toLowerCase(), fileRelativePath = path.relative(staticPath, path.dirname(filePath)), - fileDestinationPath = path.join(params.publishPath, params.staticDir, fileRelativePath), + fileDestinationPath = path.join( + params.publishPath, + params.staticDir, + fileRelativePath + ), fileDestination = path.join(fileDestinationPath, fileName); fs.ensureDirSync(fileDestinationPath); - if(params.minify && params.ocOptions.minify !== false && (fileExt === '.js' || fileExt === '.css')){ + if ( + params.minify && + params.ocOptions.minify !== false && + (fileExt === '.js' || fileExt === '.css') + ) { const fileContent = fs.readFileSync(filePath).toString(), minified = minifyFile(fileExt, fileContent); @@ -46,18 +52,23 @@ const copyDir = function(params, cb){ } }; -module.exports = function(params, callback){ - +module.exports = function(params, callback) { const staticList = params.ocOptions.files.static; - if(staticList.length === 0){ + if (staticList.length === 0) { return callback(null, 'ok'); } - async.eachSeries(staticList, (staticDir, cb) => { - copyDir(_.extend(params, { staticDir: staticDir }), cb); - }, (errors) => { - if(errors){ return callback(errors); } - callback(null, 'ok'); - }); + async.eachSeries( + staticList, + (staticDir, cb) => { + copyDir(_.extend(params, { staticDir: staticDir }), cb); + }, + errors => { + if (errors) { + return callback(errors); + } + callback(null, 'ok'); + } + ); }; diff --git a/src/cli/domain/package-static-files/minify-file.js b/src/cli/domain/package-static-files/minify-file.js index c66bb92e0..81cfd5f4e 100644 --- a/src/cli/domain/package-static-files/minify-file.js +++ b/src/cli/domain/package-static-files/minify-file.js @@ -5,10 +5,8 @@ const babelPresetEnv = require('babel-preset-env'); const CleanCss = require('clean-css'); const uglifyJs = require('uglify-js'); -module.exports = function(fileExt, fileContent){ - - if(fileExt === '.js'){ - +module.exports = function(fileExt, fileContent) { + if (fileExt === '.js') { const presetOptions = { targets: { browsers: 'ie 8', @@ -22,9 +20,7 @@ module.exports = function(fileExt, fileContent){ es5 = babel.transform(fileContent, babelOptions).code; return uglifyJs.minify(es5, { fromString: true }).code; - - } else if(fileExt === '.css'){ - + } else if (fileExt === '.css') { return new CleanCss().minify(fileContent).styles; } }; diff --git a/src/cli/domain/package-template.js b/src/cli/domain/package-template.js index 10e4917fd..3519e365d 100644 --- a/src/cli/domain/package-template.js +++ b/src/cli/domain/package-template.js @@ -9,17 +9,25 @@ const hashBuilder = require('../../utils/hash-builder'); const strings = require('../../resources'); const requireTemplate = require('../../utils/require-template'); -const javaScriptizeTemplate = function(functionName, data){ - return format('var {0}={0}||{};{0}.components={0}.components||{};{0}.components[\'{1}\']={2}', 'oc', functionName, data.toString()); +const javaScriptizeTemplate = function(functionName, data) { + return format( + "var {0}={0}||{};{0}.components={0}.components||{};{0}.components['{1}']={2}", + 'oc', + functionName, + data.toString() + ); }; const compileView = function(viewPath, type, cb) { const template = fs.readFileSync(viewPath).toString(); let ocTemplate; - if (type === 'jade') { type = 'oc-template-jade'; } - if (type === 'handlebars') { type = 'oc-template-handlebars'; } - + if (type === 'jade') { + type = 'oc-template-jade'; + } + if (type === 'handlebars') { + type = 'oc-template-handlebars'; + } try { ocTemplate = requireTemplate(type); @@ -28,39 +36,49 @@ const compileView = function(viewPath, type, cb) { } ocTemplate.compile({ template, viewPath }, (err, compiledView) => { - if (err) { return cb(err);} + if (err) { + return cb(err); + } const hashView = hashBuilder.fromString(compiledView.toString()), javaScriptizedView = javaScriptizeTemplate(hashView, compiledView); return cb(null, { hash: hashView, - view: uglifyJs.minify(javaScriptizedView, {fromString: true}).code + view: uglifyJs.minify(javaScriptizedView, { fromString: true }).code }); }); }; -module.exports = function(params, callback){ - +module.exports = function(params, callback) { const viewSrc = params.ocOptions.files.template.src, viewPath = path.join(params.componentPath, viewSrc); - if(!fs.existsSync(viewPath)){ + if (!fs.existsSync(viewPath)) { return callback(format(strings.errors.cli.TEMPLATE_NOT_FOUND, viewSrc)); } try { - compileView(viewPath, params.ocOptions.files.template.type, (err, compiled) => { - if (err) { - return callback(format('{0} compilation failed - {1}', viewSrc, err)); + compileView( + viewPath, + params.ocOptions.files.template.type, + (err, compiled) => { + if (err) { + return callback(format('{0} compilation failed - {1}', viewSrc, err)); + } + fs.writeFile( + path.join(params.publishPath, 'template.js'), + compiled.view, + err => + callback(err, { + type: params.ocOptions.files.template.type, + hashKey: compiled.hash, + src: 'template.js' + }) + ); } - fs.writeFile(path.join(params.publishPath, 'template.js'), compiled.view, (err) => callback(err, { - type: params.ocOptions.files.template.type, - hashKey: compiled.hash, - src: 'template.js' - })); - }); - } catch(e){ + ); + } catch (e) { return callback(format('{0} compilation failed - {1}', viewSrc, e)); } }; diff --git a/src/cli/domain/registry.js b/src/cli/domain/registry.js index 3d3fb8b74..619bf5e20 100644 --- a/src/cli/domain/registry.js +++ b/src/cli/domain/registry.js @@ -11,111 +11,132 @@ const settings = require('../../resources/settings'); const urlBuilder = require('../../registry/domain/url-builder'); const urlParser = require('../domain/url-parser'); -const getOcVersion = function(){ - +const getOcVersion = function() { const ocPackagePath = path.join(__dirname, '../../../package.json'), ocInfo = fs.readJsonSync(ocPackagePath); return ocInfo.version; }; -module.exports = function(opts){ +module.exports = function(opts) { opts = opts || {}; let requestsHeaders = { - 'user-agent': format('oc-cli-{0}/{1}-{2}-{3}', - getOcVersion(), - process.version, - process.platform, - process.arch) + 'user-agent': format( + 'oc-cli-{0}/{1}-{2}-{3}', + getOcVersion(), + process.version, + process.platform, + process.arch + ) }; return _.extend(this, { - add: function(registry, callback){ - - if(registry.slice(registry.length - 1) !== '/'){ + add: function(registry, callback) { + if (registry.slice(registry.length - 1) !== '/') { registry += '/'; } - request({ - url: registry, - headers: requestsHeaders, - json: true - }, (err, apiResponse) => { - if(err || !apiResponse){ - return callback('oc registry not available', null); - } else if(apiResponse.type !== 'oc-registry'){ - return callback('not a valid oc registry', null); - } - - fs.readJson(settings.configFile.src, (err, res) => { - if(err){ - res = {}; + request( + { + url: registry, + headers: requestsHeaders, + json: true + }, + (err, apiResponse) => { + if (err || !apiResponse) { + return callback('oc registry not available', null); + } else if (apiResponse.type !== 'oc-registry') { + return callback('not a valid oc registry', null); } - if(!res.registries){ - res.registries = []; - } + fs.readJson(settings.configFile.src, (err, res) => { + if (err) { + res = {}; + } - if(!_.includes(res.registries, registry)){ - res.registries.push(registry); - } + if (!res.registries) { + res.registries = []; + } - fs.writeJson(settings.configFile.src, res, callback); - }); - }); + if (!_.includes(res.registries, registry)) { + res.registries.push(registry); + } + + fs.writeJson(settings.configFile.src, res, callback); + }); + } + ); }, - get: function(callback){ - if(opts.registry){ + get: function(callback) { + if (opts.registry) { return callback(null, [opts.registry]); } fs.readJson(settings.configFile.src, (err, res) => { - if(err || !res.registries || res.registries.length === 0){ + if (err || !res.registries || res.registries.length === 0) { return callback('No oc registries'); } return callback(null, res.registries); }); }, - getApiComponentByHref: function(href, callback){ - request({ - url: href + settings.registry.componentInfoPath, - headers: requestsHeaders, - json: true - }, callback); + getApiComponentByHref: function(href, callback) { + request( + { + url: href + settings.registry.componentInfoPath, + headers: requestsHeaders, + json: true + }, + callback + ); }, - getComponentPreviewUrlByUrl: function(componentHref, callback){ - request({ - url: componentHref, - headers: requestsHeaders, - json: true - }, (err, res) => { - if(err){ return callback(err); } - - const parsed = urlParser.parse(res); - callback(null, urlBuilder.componentPreview(parsed, parsed.registryUrl)); - }); + getComponentPreviewUrlByUrl: function(componentHref, callback) { + request( + { + url: componentHref, + headers: requestsHeaders, + json: true + }, + (err, res) => { + if (err) { + return callback(err); + } + + const parsed = urlParser.parse(res); + callback( + null, + urlBuilder.componentPreview(parsed, parsed.registryUrl) + ); + } + ); }, - putComponent: function(options, callback){ - if(!!options.username && !!options.password){ - requestsHeaders = _.extend(requestsHeaders, { 'Authorization': 'Basic ' + new Buffer(options.username + ':' + options.password).toString('base64') }); + putComponent: function(options, callback) { + if (!!options.username && !!options.password) { + requestsHeaders = _.extend(requestsHeaders, { + Authorization: + 'Basic ' + + new Buffer(options.username + ':' + options.password).toString( + 'base64' + ) + }); } put(options.route, options.path, requestsHeaders, (err, res) => { - - if(err){ - if(!_.isObject(err)){ + if (err) { + if (!_.isObject(err)) { try { err = JSON.parse(err); - } catch(er){ - } + } catch (er) {} } - if(!!err.code && err.code === 'ECONNREFUSED'){ + if (!!err.code && err.code === 'ECONNREFUSED') { err = 'Connection to registry has not been established'; - } else if(err.code !== 'cli_version_not_valid' - && err.code !== 'node_version_not_valid' && !!err.error){ + } else if ( + err.code !== 'cli_version_not_valid' && + err.code !== 'node_version_not_valid' && + !!err.error + ) { err = err.error; } @@ -125,13 +146,13 @@ module.exports = function(opts){ callback(err, res); }); }, - remove: function(registry, callback){ + remove: function(registry, callback) { fs.readJson(settings.configFile.src, (err, res) => { - if(err){ + if (err) { res = {}; } - if(!res.registries){ + if (!res.registries) { res.registries = []; } diff --git a/src/cli/domain/url-parser.js b/src/cli/domain/url-parser.js index ac2a9027f..c43422c1a 100644 --- a/src/cli/domain/url-parser.js +++ b/src/cli/domain/url-parser.js @@ -3,22 +3,27 @@ const querystring = require('querystring'); const url = require('url'); -const removeFinalSlashes = function(s){ - while(s.slice(-1) === '/'){ +const removeFinalSlashes = function(s) { + while (s.slice(-1) === '/') { s = s.slice(0, -1); } return s; }; module.exports = { - parse: function(parsed){ - + parse: function(parsed) { const requestedVersion = parsed.requestVersion, href = url.parse(parsed.href), relativePath = removeFinalSlashes(href.pathname), - withoutVersion = removeFinalSlashes(relativePath.replace(requestedVersion, '')), - componentName = withoutVersion.substr(withoutVersion.lastIndexOf('/') + 1), - withoutComponent = removeFinalSlashes(withoutVersion.replace(componentName, '')), + withoutVersion = removeFinalSlashes( + relativePath.replace(requestedVersion, '') + ), + componentName = withoutVersion.substr( + withoutVersion.lastIndexOf('/') + 1 + ), + withoutComponent = removeFinalSlashes( + withoutVersion.replace(componentName, '') + ), registryUrl = href.protocol + '//' + href.host + withoutComponent + '/'; return { diff --git a/src/cli/domain/watch.js b/src/cli/domain/watch.js index f1a5bf1f2..0dba9750f 100644 --- a/src/cli/domain/watch.js +++ b/src/cli/domain/watch.js @@ -3,19 +3,26 @@ const path = require('path'); const watch = require('watch'); -module.exports = function(dirs, baseDir, changed){ +module.exports = function(dirs, baseDir, changed) { try { - watch.watchTree(path.resolve(baseDir), { - ignoreUnreadableDir: true, - ignoreDotFiles: false - }, (fileName, currentStat, previousStat) => { - if(!!currentStat || !!previousStat){ - if(/node_modules|package.tar.gz|_package|\.sw[op]/gi.test(fileName) === false){ - changed(null, fileName); + watch.watchTree( + path.resolve(baseDir), + { + ignoreUnreadableDir: true, + ignoreDotFiles: false + }, + (fileName, currentStat, previousStat) => { + if (!!currentStat || !!previousStat) { + if ( + /node_modules|package.tar.gz|_package|\.sw[op]/gi.test(fileName) === + false + ) { + changed(null, fileName); + } } } - }); - } catch(err){ + ); + } catch (err) { changed(err); } }; diff --git a/src/cli/facade/dev.js b/src/cli/facade/dev.js index f27146b78..2edfc893e 100644 --- a/src/cli/facade/dev.js +++ b/src/cli/facade/dev.js @@ -15,28 +15,33 @@ const strings = require('../../resources/index'); const watch = require('../domain/watch'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ +module.exports = function(dependencies) { const local = dependencies.local, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { const componentsDir = opts.dirPath, port = opts.port || 3000, baseUrl = opts.baseUrl || format('http://localhost:{0}/', port), errors = strings.errors.cli, fallbackRegistryUrl = opts.fallbackRegistryUrl, - hotReloading = _.isUndefined(opts.hotReloading) ? true : opts.hotReloading; + hotReloading = _.isUndefined(opts.hotReloading) + ? true + : opts.hotReloading; let packaging = false; callback = wrapCliCallback(callback); - const installMissingDeps = function(missing, cb){ - if(_.isEmpty(missing)){ return cb(); } + const installMissingDeps = function(missing, cb) { + if (_.isEmpty(missing)) { + return cb(); + } - logger.warn(format(strings.messages.cli.INSTALLING_DEPS, missing.join(', '))); - npmInstaller(missing, (err) => { - if(err){ + logger.warn( + format(strings.messages.cli.INSTALLING_DEPS, missing.join(', ')) + ); + npmInstaller(missing, err => { + if (err) { logger.err(err.toString()); throw err; } @@ -44,13 +49,15 @@ module.exports = function(dependencies){ }); }; - const watchForChanges = function(components, cb){ + const watchForChanges = function(components, cb) { watch(components, componentsDir, (err, changedFile) => { - if(err){ + if (err) { logger.err(format(strings.errors.generic, err)); } else { - logger.warn(format(strings.messages.cli.CHANGES_DETECTED, changedFile)); - if(!hotReloading){ + logger.warn( + format(strings.messages.cli.CHANGES_DETECTED, changedFile) + ); + if (!hotReloading) { logger.warn(strings.messages.cli.HOT_RELOADING_DISABLED); } else { cb(components); @@ -59,52 +66,66 @@ module.exports = function(dependencies){ }); }; - const packageComponents = function(componentsDirs, cb){ + const packageComponents = function(componentsDirs, cb) { cb = _.isFunction(cb) ? cb : _.noop; let i = 0; - if(!packaging){ + if (!packaging) { packaging = true; logger.warn(strings.messages.cli.PACKAGING_COMPONENTS, true); - async.eachSeries(componentsDirs, (dir, cb) => { - - const packageOptions = { - componentPath: dir, - minify: false, - verbose: opts.verbose - }; - - local.package(packageOptions, (err) => { - if(!err){ i++; } - cb(err); - }); - }, (error) => { - if(error){ - const errorDescription = ((error instanceof SyntaxError) || !!error.message) ? error.message : error; - logger.err(format(strings.errors.cli.PACKAGING_FAIL, componentsDirs[i], errorDescription)); - logger.warn(strings.messages.cli.RETRYING_10_SECONDS); - setTimeout(() => { + async.eachSeries( + componentsDirs, + (dir, cb) => { + const packageOptions = { + componentPath: dir, + minify: false, + verbose: opts.verbose + }; + + local.package(packageOptions, err => { + if (!err) { + i++; + } + cb(err); + }); + }, + error => { + if (error) { + const errorDescription = error instanceof SyntaxError || + !!error.message + ? error.message + : error; + logger.err( + format( + strings.errors.cli.PACKAGING_FAIL, + componentsDirs[i], + errorDescription + ) + ); + logger.warn(strings.messages.cli.RETRYING_10_SECONDS); + setTimeout(() => { + packaging = false; + packageComponents(componentsDirs); + }, 10000); + } else { packaging = false; - packageComponents(componentsDirs); - }, 10000); - } else { - packaging = false; - logger.ok('OK'); - cb(); + logger.ok('OK'); + cb(); + } } - }); + ); } }; - const loadDependencies = function(components, cb){ + const loadDependencies = function(components, cb) { logger.warn(strings.messages.cli.CHECKING_DEPENDENCIES, true); const dependencies = getComponentsDependencies(components), missing = getMissingDeps(dependencies.withVersions, components); - if(_.isEmpty(missing)){ + if (_.isEmpty(missing)) { logger.ok('OK'); return cb(dependencies); } @@ -115,39 +136,48 @@ module.exports = function(dependencies){ }); }; - const registerPlugins = function(registry){ + const registerPlugins = function(registry) { const mockedPlugins = getMockedPlugins(logger, componentsDir); - mockedPlugins.forEach((p) => { + mockedPlugins.forEach(p => { registry.register(p); }); - registry.on('request', (data) => { - if(data.errorCode === 'PLUGIN_MISSING_FROM_REGISTRY'){ - logger.err(format(strings.errors.cli.PLUGIN_MISSING_FROM_REGISTRY, data.errorDetails, colors.blue(strings.commands.cli.MOCK_PLUGIN))); - } else if(data.errorCode === 'PLUGIN_MISSING_FROM_COMPONENT'){ - logger.err(format(strings.errors.cli.PLUGIN_MISSING_FROM_COMPONENT, data.errorDetails)); + registry.on('request', data => { + if (data.errorCode === 'PLUGIN_MISSING_FROM_REGISTRY') { + logger.err( + format( + strings.errors.cli.PLUGIN_MISSING_FROM_REGISTRY, + data.errorDetails, + colors.blue(strings.commands.cli.MOCK_PLUGIN) + ) + ); + } else if (data.errorCode === 'PLUGIN_MISSING_FROM_COMPONENT') { + logger.err( + format( + strings.errors.cli.PLUGIN_MISSING_FROM_COMPONENT, + data.errorDetails + ) + ); } }); }; logger.warn(strings.messages.cli.SCANNING_COMPONENTS, true); local.getComponentsByDir(componentsDir, (err, components) => { - - if(_.isEmpty(components)){ + if (_.isEmpty(components)) { err = format(errors.DEV_FAIL, errors.COMPONENTS_NOT_FOUND); callback(err); return logger.err(err); } logger.ok('OK'); - _.forEach(components, (component) => { + _.forEach(components, component => { logger.log(colors.green('├── ') + component); }); - loadDependencies(components, (dependencies) => { + loadDependencies(components, dependencies => { packageComponents(components, () => { - const registry = new oc.Registry({ local: true, hotReloading: hotReloading, @@ -165,10 +195,9 @@ module.exports = function(dependencies){ registerPlugins(registry); logger.warn(format(strings.messages.cli.REGISTRY_STARTING, baseUrl)); - registry.start((err) => { - - if(err){ - if(err.code === 'EADDRINUSE'){ + registry.start(err => { + if (err) { + if (err.code === 'EADDRINUSE') { err = format(strings.errors.cli.PORT_IS_BUSY, port); } diff --git a/src/cli/facade/init.js b/src/cli/facade/init.js index 6ad2163eb..da02cc605 100644 --- a/src/cli/facade/init.js +++ b/src/cli/facade/init.js @@ -6,26 +6,26 @@ const _ = require('lodash'); const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const local = dependencies.local, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { const componentName = opts.componentName, - templateType = _.isUndefined(opts.templateType) ? 'handlebars' : opts.templateType, + templateType = _.isUndefined(opts.templateType) + ? 'handlebars' + : opts.templateType, errors = strings.errors.cli; callback = wrapCliCallback(callback); - local.init(componentName, templateType, (err) => { - if(err){ - if(err === 'name not valid'){ + local.init(componentName, templateType, err => { + if (err) { + if (err === 'name not valid') { err = errors.NAME_NOT_VALID; } - if(err === 'template type not valid'){ + if (err === 'template type not valid') { err = errors.TEMPLATE_TYPE_NOT_VALID; } diff --git a/src/cli/facade/mock.js b/src/cli/facade/mock.js index 434681cc2..d046468f6 100644 --- a/src/cli/facade/mock.js +++ b/src/cli/facade/mock.js @@ -5,17 +5,21 @@ const format = require('stringformat'); const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const local = dependencies.local, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { callback = wrapCliCallback(callback); local.mock(opts, (err, res) => { - logger.ok(format(strings.messages.cli.MOCKED_PLUGIN, opts.targetName, opts.targetValue)); + logger.ok( + format( + strings.messages.cli.MOCKED_PLUGIN, + opts.targetName, + opts.targetValue + ) + ); callback(err, res); }); }; diff --git a/src/cli/facade/package.js b/src/cli/facade/package.js index 5b02e900a..b44cc64ef 100644 --- a/src/cli/facade/package.js +++ b/src/cli/facade/package.js @@ -21,7 +21,7 @@ module.exports = function(dependencies) { componentPath: path.resolve(componentPath) }; local.package(packageOptions, (err, component) => { - if(err){ + if (err) { logger.err(format(strings.errors.cli.PACKAGE_CREATION_FAIL, err)); return callback(err); } @@ -29,14 +29,18 @@ module.exports = function(dependencies) { logger.ok(format(strings.messages.cli.PACKAGED, packageDir)); if (opts.compress) { - logger.warn(format(strings.messages.cli.COMPRESSING, compressedPackagePath)); + logger.warn( + format(strings.messages.cli.COMPRESSING, compressedPackagePath) + ); - local.compress(packageDir, compressedPackagePath, (err) => { - if(err){ + local.compress(packageDir, compressedPackagePath, err => { + if (err) { logger.err(format(strings.errors.cli.PACKAGE_CREATION_FAIL, err)); return callback(err); } - logger.ok(format(strings.messages.cli.COMPRESSED, compressedPackagePath)); + logger.ok( + format(strings.messages.cli.COMPRESSED, compressedPackagePath) + ); callback(null, component); }); } else { diff --git a/src/cli/facade/preview.js b/src/cli/facade/preview.js index 6fa0ae60a..73af29400 100644 --- a/src/cli/facade/preview.js +++ b/src/cli/facade/preview.js @@ -5,17 +5,15 @@ const opn = require('opn'); const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const logger = dependencies.logger, registry = dependencies.registry; - return function(opts, callback){ - + return function(opts, callback) { callback = wrapCliCallback(callback); registry.getComponentPreviewUrlByUrl(opts.componentHref, (err, href) => { - if(err){ + if (err) { logger.err(strings.errors.cli.COMPONENT_HREF_NOT_FOUND); return callback(strings.errors.cli.COMPONENT_HREF_NOT_FOUND); } diff --git a/src/cli/facade/publish.js b/src/cli/facade/publish.js index 925080199..9b3fbf39a 100644 --- a/src/cli/facade/publish.js +++ b/src/cli/facade/publish.js @@ -10,14 +10,12 @@ const _ = require('lodash'); const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const registry = dependencies.registry, local = dependencies.local, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { const componentPath = opts.componentPath, packageDir = path.resolve(componentPath, '_package'), compressedPackagePath = path.resolve(componentPath, 'package.tar.gz'); @@ -26,8 +24,8 @@ module.exports = function(dependencies){ callback = wrapCliCallback(callback); - const getCredentials = function(cb){ - if(opts.username && opts.password){ + const getCredentials = function(cb) { + if (opts.username && opts.password) { logger.ok(strings.messages.cli.USING_CREDS); return cb(null, _.pick(opts, 'username', 'password')); } @@ -38,37 +36,47 @@ module.exports = function(dependencies){ logger.warn(strings.messages.cli.ENTER_PASSWORD); read({ silent: true }, (err, password) => { - cb(null, { username: username, password: password}); + cb(null, { username: username, password: password }); }); }); }; - const packageAndCompress = function(cb){ + const packageAndCompress = function(cb) { logger.warn(format(strings.messages.cli.PACKAGING, packageDir)); const packageOptions = { componentPath: path.resolve(componentPath) }; local.package(packageOptions, (err, component) => { - if(err){ return cb(err); } + if (err) { + return cb(err); + } - logger.warn(format(strings.messages.cli.COMPRESSING, compressedPackagePath)); + logger.warn( + format(strings.messages.cli.COMPRESSING, compressedPackagePath) + ); - local.compress(packageDir, compressedPackagePath, (err) => { - if(err){ return cb(err); } + local.compress(packageDir, compressedPackagePath, err => { + if (err) { + return cb(err); + } cb(null, component); }); }); }; - const putComponentToRegistry = function(options, cb){ + const putComponentToRegistry = function(options, cb) { logger.warn(format(strings.messages.cli.PUBLISHING, options.route)); - registry.putComponent(options, (err) => { - - if(err){ - if(err === 'Unauthorized'){ - if(!!options.username || !!options.password){ - logger.err(format(strings.errors.cli.PUBLISHING_FAIL, strings.errors.cli.INVALID_CREDENTIALS)); + registry.putComponent(options, err => { + if (err) { + if (err === 'Unauthorized') { + if (!!options.username || !!options.password) { + logger.err( + format( + strings.errors.cli.PUBLISHING_FAIL, + strings.errors.cli.INVALID_CREDENTIALS + ) + ); return cb(err); } @@ -77,16 +85,27 @@ module.exports = function(dependencies){ return getCredentials((err, credentials) => { putComponentToRegistry(_.extend(options, credentials), cb); }); - - } else if(err.code === 'cli_version_not_valid') { - const upgradeCommand = format(strings.commands.cli.UPGRADE, err.details.suggestedVersion), - errorDetails = format(strings.errors.cli.OC_CLI_VERSION_NEEDS_UPGRADE, colors.blue(upgradeCommand)); - - errorMessage = format(strings.errors.cli.PUBLISHING_FAIL, errorDetails); + } else if (err.code === 'cli_version_not_valid') { + const upgradeCommand = format( + strings.commands.cli.UPGRADE, + err.details.suggestedVersion + ), + errorDetails = format( + strings.errors.cli.OC_CLI_VERSION_NEEDS_UPGRADE, + colors.blue(upgradeCommand) + ); + + errorMessage = format( + strings.errors.cli.PUBLISHING_FAIL, + errorDetails + ); logger.err(errorMessage); return cb(errorMessage); - } else if(err.code === 'node_version_not_valid') { - const details = format(strings.errors.cli.NODE_CLI_VERSION_NEEDS_UPGRADE, err.details.suggestedVersion); + } else if (err.code === 'node_version_not_valid') { + const details = format( + strings.errors.cli.NODE_CLI_VERSION_NEEDS_UPGRADE, + err.details.suggestedVersion + ); errorMessage = format(strings.errors.cli.PUBLISHING_FAIL, details); logger.err(errorMessage); @@ -104,30 +123,46 @@ module.exports = function(dependencies){ }; registry.get((err, registryLocations) => { - if(err){ + if (err) { logger.err(err); return callback(err); } packageAndCompress((err, component) => { - if(err){ + if (err) { errorMessage = format(strings.errors.cli.PACKAGE_CREATION_FAIL, err); logger.err(errorMessage); return callback(errorMessage); } - async.eachSeries(registryLocations, (registryUrl, next) => { - const registryLength = registryUrl.length, - registryNormalised = registryUrl.slice(registryLength - 1) === '/' ? registryUrl.slice(0, registryLength - 1) : registryUrl, - componentRoute = format('{0}/{1}/{2}', registryNormalised, component.name, component.version); - - putComponentToRegistry({ route: componentRoute, path: compressedPackagePath}, next); - }, (err) => { - local.cleanup(compressedPackagePath, (err2, res) => { - if(err){ return callback(err); } - callback(err2, res); - }); - }); + async.eachSeries( + registryLocations, + (registryUrl, next) => { + const registryLength = registryUrl.length, + registryNormalised = registryUrl.slice(registryLength - 1) === '/' + ? registryUrl.slice(0, registryLength - 1) + : registryUrl, + componentRoute = format( + '{0}/{1}/{2}', + registryNormalised, + component.name, + component.version + ); + + putComponentToRegistry( + { route: componentRoute, path: compressedPackagePath }, + next + ); + }, + err => { + local.cleanup(compressedPackagePath, (err2, res) => { + if (err) { + return callback(err); + } + callback(err2, res); + }); + } + ); }); }); }; diff --git a/src/cli/facade/registry-add.js b/src/cli/facade/registry-add.js index b7e6c8d2e..b44241876 100644 --- a/src/cli/facade/registry-add.js +++ b/src/cli/facade/registry-add.js @@ -3,17 +3,15 @@ const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const registry = dependencies.registry, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { callback = wrapCliCallback(callback); - registry.add(opts.registryUrl, (err) => { - if(err){ + registry.add(opts.registryUrl, err => { + if (err) { logger.err(err); return callback(err); } diff --git a/src/cli/facade/registry-ls.js b/src/cli/facade/registry-ls.js index 769ea54a1..633f67335 100644 --- a/src/cli/facade/registry-ls.js +++ b/src/cli/facade/registry-ls.js @@ -6,29 +6,27 @@ const _ = require('lodash'); const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const registry = dependencies.registry, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { callback = wrapCliCallback(callback); registry.get((err, registries) => { - if(err){ + if (err) { logger.err(format(strings.errors.generic, err)); return callback(err); } else { logger.warn(strings.messages.cli.REGISTRY_LIST); - if(registries.length === 0){ + if (registries.length === 0) { err = strings.errors.cli.REGISTRY_NOT_FOUND; logger.err(err); return callback(err); } - _.forEach(registries, (registryLocation) => { + _.forEach(registries, registryLocation => { logger.ok(registryLocation); }); diff --git a/src/cli/facade/registry-remove.js b/src/cli/facade/registry-remove.js index c5ed3cacd..90e58e13b 100644 --- a/src/cli/facade/registry-remove.js +++ b/src/cli/facade/registry-remove.js @@ -3,17 +3,15 @@ const strings = require('../../resources/index'); const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(dependencies){ - +module.exports = function(dependencies) { const registry = dependencies.registry, logger = dependencies.logger; - return function(opts, callback){ - + return function(opts, callback) { callback = wrapCliCallback(callback); - registry.remove(opts.registryUrl, (err) => { - if(err){ + registry.remove(opts.registryUrl, err => { + if (err) { logger.err(err); return callback(err); } diff --git a/src/cli/facade/registry.js b/src/cli/facade/registry.js index d6981cd91..110da69e9 100644 --- a/src/cli/facade/registry.js +++ b/src/cli/facade/registry.js @@ -2,9 +2,8 @@ const wrapCliCallback = require('../wrap-cli-callback'); -module.exports = function(){ - - return function(opts, callback){ +module.exports = function() { + return function(opts, callback) { callback = wrapCliCallback(callback); callback(null, 'ok'); }; diff --git a/src/cli/index.js b/src/cli/index.js index 06ed42cd7..f741626c8 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -16,44 +16,47 @@ const dependencies = { registry: new Registry() }; -function processCommand(command, commandName, cli, level, prefix){ +function processCommand(command, commandName, cli, level, prefix) { prefix = prefix || ''; level = (level || 0) + 1; const facade = require(`./facade/${prefix}${commandName}`)(dependencies); - cli - .command( - command.cmd || commandName, - command.description, - (yargs) => { - yargs.usage(command.usage); + cli.command( + command.cmd || commandName, + command.description, + yargs => { + yargs.usage(command.usage); - if(command.options){ - yargs.options(command.options); - } + if (command.options) { + yargs.options(command.options); + } - if(command.commands){ - yargs - .check((argv) => validateCommand(argv, level)) - .epilogue(strings.messages.cli.HELP_HINT); + if (command.commands) { + yargs + .check(argv => validateCommand(argv, level)) + .epilogue(strings.messages.cli.HELP_HINT); - const newPrefix = (prefix ? prefix + '-' : '') + commandName + '-'; + const newPrefix = (prefix ? prefix + '-' : '') + commandName + '-'; - _.mapValues(command.commands, (commandConfiguration, commandName) => { - processCommand(commandConfiguration, commandName, yargs, level, newPrefix); - }); - } + _.mapValues(command.commands, (commandConfiguration, commandName) => { + processCommand( + commandConfiguration, + commandName, + yargs, + level, + newPrefix + ); + }); + } - if(command.example){ - yargs - .example( - command.example.cmd, - command.example.description); - } + if (command.example) { + yargs.example(command.example.cmd, command.example.description); + } - return yargs; - }, facade - ); + return yargs; + }, + facade + ); } _.forEach(commands.commands, (command, commandName) => { @@ -62,15 +65,14 @@ _.forEach(commands.commands, (command, commandName) => { const argv = cli .completion() - .check((argv) => validateCommand(argv, 0)) + .check(argv => validateCommand(argv, 0)) .usage(commands.usage) .epilogue(strings.messages.cli.HELP_HINT) .help('h') .alias('h', 'help') .version() - .wrap(cli.terminalWidth()) - .argv; + .wrap(cli.terminalWidth()).argv; -if(argv._.length === 0 ) { +if (argv._.length === 0) { cli.showHelp(); } diff --git a/src/cli/logger.js b/src/cli/logger.js index fcbb8e896..d53cc33c1 100644 --- a/src/cli/logger.js +++ b/src/cli/logger.js @@ -7,7 +7,8 @@ const logger = { write: msg => process.stdout.write(msg.toString()) }; -const log = (msg, color, newLine) => logger[newLine ? 'writeLn' : 'write'](color ? colors[color](msg) : msg); +const log = (msg, color, newLine) => + logger[newLine ? 'writeLn' : 'write'](color ? colors[color](msg) : msg); module.exports = { err: (msg, noNewLine) => log(msg, 'red', !noNewLine), diff --git a/src/cli/validate-command.js b/src/cli/validate-command.js index 373b7af2a..ccbb0772d 100644 --- a/src/cli/validate-command.js +++ b/src/cli/validate-command.js @@ -12,7 +12,9 @@ const validateCommand = (argv, level) => { } if (argv._.length > level && !_.includes(keys, argv._[level])) { - throw new Error(format(strings.messages.cli.NO_SUCH_COMMAND, argv._[level])); + throw new Error( + format(strings.messages.cli.NO_SUCH_COMMAND, argv._[level]) + ); } return true; }; diff --git a/src/cli/wrap-cli-callback.js b/src/cli/wrap-cli-callback.js index 0870a1939..95ada00ab 100644 --- a/src/cli/wrap-cli-callback.js +++ b/src/cli/wrap-cli-callback.js @@ -2,13 +2,13 @@ const _ = require('lodash'); -module.exports = function(callback){ - if(_.isFunction(callback)){ +module.exports = function(callback) { + if (_.isFunction(callback)) { return callback; } - return function(error){ - if(error){ + return function(error) { + if (error) { return process.exit(1); } }; diff --git a/src/components/oc-client/src/oc-client.js b/src/components/oc-client/src/oc-client.js index f8b38405e..86a748f78 100644 --- a/src/components/oc-client/src/oc-client.js +++ b/src/components/oc-client/src/oc-client.js @@ -4,21 +4,25 @@ var oc = oc || {}; -(function (root, factory) { +(function(root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module define(['exports', 'jquery'], function(exports, $) { $.extend(exports, root.oc); factory((root.oc = exports), $, root.head, root.document, root.window); }); - } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') { + } else if ( + typeof exports === 'object' && + typeof exports.nodeName !== 'string' + ) { // Common JS factory(exports, require('jquery'), root.head, root.document, root.window); } else { // Browser globals factory((root.oc = oc), root.$, root.head, root.document, root.window); } -}(this, function (exports, $, head, $document, $window) { // jshint ignore:line +})(this, function(exports, $, head, $document, $window) { + // jshint ignore:line // public variables oc.conf = oc.conf || {}; oc.cmd = oc.cmd || []; @@ -26,7 +30,7 @@ var oc = oc || {}; oc.status = oc.status || false; // If oc client is already inside the page, we do nothing. - if(oc.status){ + if (oc.status) { return oc; } else { oc.status = 'loading'; @@ -34,40 +38,53 @@ var oc = oc || {}; // varants var CDNJS_BASEURL = 'https://cdnjs.cloudflare.com/ajax/libs/', - IE9_AJAX_POLYFILL_URL = CDNJS_BASEURL + 'jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js', + IE9_AJAX_POLYFILL_URL = + CDNJS_BASEURL + + 'jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js', JQUERY_URL = CDNJS_BASEURL + 'jquery/1.11.2/jquery.min.js', RETRY_INTERVAL = oc.conf.retryInterval || 5000, RETRY_LIMIT = oc.conf.retryLimit || 30, RETRY_SEND_NUMBER = oc.conf.retrySendNumber || true, POLLING_INTERVAL = oc.conf.pollingInterval || 500, OC_TAG = oc.conf.tag || 'oc-component', - MESSAGES_ERRORS_BASEURL_PARAMETER_IS_REQUIRED ='baseUrl parameter is required', + MESSAGES_ERRORS_BASEURL_PARAMETER_IS_REQUIRED = + 'baseUrl parameter is required', MESSAGES_ERRORS_HREF_MISSING = 'Href parameter missing', - MESSAGES_ERRORS_NAME_PARAMETER_IS_REQUIRED ='name parameter is required', - MESSAGES_ERRORS_RETRY_FAILED = 'Failed to load {0} component {1} times. Giving up'.replace('{1}', RETRY_LIMIT), + MESSAGES_ERRORS_NAME_PARAMETER_IS_REQUIRED = 'name parameter is required', + MESSAGES_ERRORS_RETRY_FAILED = 'Failed to load {0} component {1} times. Giving up'.replace( + '{1}', + RETRY_LIMIT + ), MESSAGES_ERRORS_LOADING_COMPILED_VIEW = 'Error getting compiled view: {0}', MESSAGES_ERRORS_RENDERING = 'Error rendering component: {0}, error: {1}', - MESSAGES_ERRORS_RETRIEVING = 'Failed to retrieve the component. Retrying in {0} seconds...'.replace('{0}', RETRY_INTERVAL/1000), - MESSAGES_ERRORS_VIEW_ENGINE_NOT_SUPPORTED = 'Error loading component: view engine "{0}" not supported', + MESSAGES_ERRORS_RETRIEVING = 'Failed to retrieve the component. Retrying in {0} seconds...'.replace( + '{0}', + RETRY_INTERVAL / 1000 + ), + MESSAGES_ERRORS_VIEW_ENGINE_NOT_SUPPORTED = + 'Error loading component: view engine "{0}" not supported', MESSAGES_LOADING_COMPONENT = oc.conf.loadingMessage || '', - MESSAGES_RENDERED = 'Component \'{0}\' correctly rendered', - MESSAGES_RETRIEVING = 'Unrendered component found. Trying to retrieve it...'; + MESSAGES_RENDERED = "Component '{0}' correctly rendered", + MESSAGES_RETRIEVING = + 'Unrendered component found. Trying to retrieve it...'; // The code var debug = oc.conf.debug || false, - noop = function(){}, + noop = function() {}, nav = $window.navigator.userAgent, - is9 = !!(nav.match(/MSIE 9/)), + is9 = !!nav.match(/MSIE 9/), initialised = false, initialising = false, retries = {}, - isBool = function(a){ return typeof(a) === 'boolean'; }; + isBool = function(a) { + return typeof a === 'boolean'; + }; var logger = { - error: function(msg){ + error: function(msg) { return console.log(msg); }, - info: function(msg){ + info: function(msg) { return debug ? console.log(msg) : false; } }; @@ -75,19 +92,27 @@ var oc = oc || {}; var registeredTemplates = { 'oc-template-handlebars': { externals: [ - { global: 'Handlebars', url: 'https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.runtime.min.js' } + { + global: 'Handlebars', + url: + 'https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.runtime.min.js' + } ] }, 'oc-template-jade': { externals: [ - { global: 'jade', url: 'https://cdnjs.cloudflare.com/ajax/libs/jade/1.11.0/runtime.min.js' } + { + global: 'jade', + url: + 'https://cdnjs.cloudflare.com/ajax/libs/jade/1.11.0/runtime.min.js' + } ] } }; function registerTemplates(templates) { templates = Array.isArray(templates) ? templates : [templates]; - templates.forEach(function(template){ + templates.forEach(function(template) { if (!registeredTemplates[template.type]) { registeredTemplates[template.type] = { externals: template.externals @@ -100,25 +125,25 @@ var oc = oc || {}; registerTemplates(oc.conf.templates); } - var retry = function(component, cb, failedRetryCb){ - if(retries[component] === undefined){ + var retry = function(component, cb, failedRetryCb) { + if (retries[component] === undefined) { retries[component] = RETRY_LIMIT; } - if(retries[component] <= 0){ + if (retries[component] <= 0) { return failedRetryCb(); } - setTimeout(function(){ + setTimeout(function() { cb(RETRY_LIMIT - retries[component] + 1); }, RETRY_INTERVAL); retries[component]--; }; - var addParametersToHref = function (href, parameters) { - if(href && parameters) { + var addParametersToHref = function(href, parameters) { + if (href && parameters) { var param = oc.$.param(parameters); - if(href.indexOf('?') > -1) { + if (href.indexOf('?') > -1) { return href + '&' + param; } else { return href + '?' + param; @@ -128,34 +153,34 @@ var oc = oc || {}; return href; }; - oc.registerTemplates = function (templates) { + oc.registerTemplates = function(templates) { registerTemplates(templates); oc.ready(oc.renderUnloadedComponents); return registeredTemplates; }; // A minimal require.js-ish that uses head.js - oc.require = function(nameSpace, url, callback){ - if(typeof(url) === 'function'){ + oc.require = function(nameSpace, url, callback) { + if (typeof url === 'function') { callback = url; url = nameSpace; nameSpace = undefined; } - if(typeof(nameSpace) === 'string'){ + if (typeof nameSpace === 'string') { nameSpace = [nameSpace]; } - var needsToBeLoaded = function(){ + var needsToBeLoaded = function() { var base = $window; - if(typeof(nameSpace) === 'undefined'){ + if (typeof nameSpace === 'undefined') { return true; } - for(var i = 0; i < nameSpace.length; i++){ + for (var i = 0; i < nameSpace.length; i++) { base = base[nameSpace[i]]; - if(!base){ + if (!base) { return true; } } @@ -163,16 +188,16 @@ var oc = oc || {}; return false; }; - var getObj = function(){ + var getObj = function() { var base = $window; - if(typeof(nameSpace) === 'undefined'){ + if (typeof nameSpace === 'undefined') { return undefined; } - for(var i = 0; i < nameSpace.length; i++){ + for (var i = 0; i < nameSpace.length; i++) { base = base[nameSpace[i]]; - if(!base){ + if (!base) { return undefined; } } @@ -180,8 +205,8 @@ var oc = oc || {}; return base; }; - if(needsToBeLoaded()){ - head.load(url, function(){ + if (needsToBeLoaded()) { + head.load(url, function() { callback(getObj()); }); } else { @@ -189,10 +214,8 @@ var oc = oc || {}; } }; - - var processHtml = function($component, data, callback){ - - data.id = Math.floor(Math.random()*9999999999); + var processHtml = function($component, data, callback) { + data.id = Math.floor(Math.random() * 9999999999); $component.html(data.html); $component.attr('id', data.id); @@ -200,11 +223,11 @@ var oc = oc || {}; $component.attr('data-rendering', false); $component.attr('data-version', data.version); - if(data.key){ + if (data.key) { $component.attr('data-hash', data.key); } - if(data.name){ + if (data.name) { $component.attr('data-name', data.name); oc.renderedComponents[data.name] = data.version; oc.events.fire('oc:rendered', data); @@ -213,20 +236,19 @@ var oc = oc || {}; callback(); }; - oc.build = function(options){ - - if(!options.baseUrl){ + oc.build = function(options) { + if (!options.baseUrl) { throw MESSAGES_ERRORS_BASEURL_PARAMETER_IS_REQUIRED; } - if(!options.name){ + if (!options.name) { throw MESSAGES_ERRORS_NAME_PARAMETER_IS_REQUIRED; } - var withFinalSlash = function(s){ + var withFinalSlash = function(s) { s = s || ''; - if(s.slice(-1) !== '/'){ + if (s.slice(-1) !== '/') { s += '/'; } @@ -235,14 +257,14 @@ var oc = oc || {}; var href = withFinalSlash(options.baseUrl) + withFinalSlash(options.name); - if(options.version){ + if (options.version) { href += withFinalSlash(options.version); } - if(options.parameters){ + if (options.parameters) { href += '?'; - for(var parameter in options.parameters){ - if(options.parameters.hasOwnProperty(parameter)){ + for (var parameter in options.parameters) { + if (options.parameters.hasOwnProperty(parameter)) { href += parameter + '=' + options.parameters[parameter] + '&'; } } @@ -254,40 +276,37 @@ var oc = oc || {}; oc.events = {}; - oc.ready = function(callback){ - - if(initialised){ + oc.ready = function(callback) { + if (initialised) { return callback(); - } else if(initialising) { + } else if (initialising) { oc.cmd.push(callback); } else { - initialising = true; - var requirePolyfills = function($, cb){ - if(is9 && !$.IE_POLYFILL_LOADED){ + var requirePolyfills = function($, cb) { + if (is9 && !$.IE_POLYFILL_LOADED) { oc.require(IE9_AJAX_POLYFILL_URL, cb); } else { cb(); } }; - var done = function(){ + var done = function() { initialised = true; initialising = false; - oc.events = (function(){ - + oc.events = (function() { var obj = oc.$({}); return { - fire: function(key, data){ + fire: function(key, data) { return obj.trigger(key, data); }, - on: function(key, cb){ + on: function(key, cb) { return obj.on(key, cb || noop); }, - reset: function(){ + reset: function() { return obj.off(); } }; @@ -298,20 +317,21 @@ var oc = oc || {}; oc.events.fire('oc:ready', oc); oc.status = 'ready'; - for(var i = 0; i < oc.cmd.length; i++){ + for (var i = 0; i < oc.cmd.length; i++) { oc.cmd[i](oc); } oc.cmd = { - push: function(f){ f(oc); } + push: function(f) { + f(oc); + } }; }; var wasDollarThereAlready = !!$window.$; - oc.require('jQuery', JQUERY_URL, function(jQuery){ - - requirePolyfills(jQuery, function(){ - if(wasDollarThereAlready){ + oc.require('jQuery', JQUERY_URL, function(jQuery) { + requirePolyfills(jQuery, function() { + if (wasDollarThereAlready) { // jQuery was already there. The client shares the same instance. oc.$ = jQuery; } else { @@ -326,61 +346,87 @@ var oc = oc || {}; } }; - oc.render = function(compiledViewInfo, model, callback){ - oc.ready(function(){ + oc.render = function(compiledViewInfo, model, callback) { + oc.ready(function() { var type = compiledViewInfo.type; - if (type === 'jade') { type = 'oc-template-jade'; } - if (type === 'handlebars') { type = 'oc-template-handlebars'; } + if (type === 'jade') { + type = 'oc-template-jade'; + } + if (type === 'handlebars') { + type = 'oc-template-handlebars'; + } var template = registeredTemplates[type]; - if(template){ - oc.require(['oc', 'components', compiledViewInfo.key], compiledViewInfo.src, function(compiledView){ - if(!compiledView){ - callback(MESSAGES_ERRORS_LOADING_COMPILED_VIEW.replace('{0}', compiledViewInfo.src)); - } else { - - var externals = template.externals; - var externalsRequired = 0; - - externals.forEach(function(library, _index, externals){ - oc.require(library.global, library.url, function(){ - externalsRequired++; - if(externalsRequired === externals.length) { - if(type === 'oc-template-handlebars'){ - try { - var linked = $window.Handlebars.template(compiledView, []); - callback(null, linked(model)); - } catch(e){ - callback(e.toString()); + if (template) { + oc.require( + ['oc', 'components', compiledViewInfo.key], + compiledViewInfo.src, + function(compiledView) { + if (!compiledView) { + callback( + MESSAGES_ERRORS_LOADING_COMPILED_VIEW.replace( + '{0}', + compiledViewInfo.src + ) + ); + } else { + var externals = template.externals; + var externalsRequired = 0; + + externals.forEach(function(library, _index, externals) { + oc.require(library.global, library.url, function() { + externalsRequired++; + if (externalsRequired === externals.length) { + if (type === 'oc-template-handlebars') { + try { + var linked = $window.Handlebars.template( + compiledView, + [] + ); + callback(null, linked(model)); + } catch (e) { + callback(e.toString()); + } + } else { + callback(null, compiledView(model)); } - } else { - callback(null, compiledView(model)); } - } + }); }); - }); + } } - }); + ); } else { - callback(MESSAGES_ERRORS_VIEW_ENGINE_NOT_SUPPORTED.replace('{0}', compiledViewInfo.type)); + callback( + MESSAGES_ERRORS_VIEW_ENGINE_NOT_SUPPORTED.replace( + '{0}', + compiledViewInfo.type + ) + ); } }); }; - oc.renderNestedComponent = function($component, callback){ - oc.ready(function(){ + oc.renderNestedComponent = function($component, callback) { + oc.ready(function() { var dataRendering = $component.attr('data-rendering'), dataRendered = $component.attr('data-rendered'), - isRendering = isBool(dataRendering) ? dataRendering : (dataRendering === 'true'), - isRendered = isBool(dataRendered) ? dataRendered : (dataRendered === 'true'); - - if(!isRendering && !isRendered){ + isRendering = isBool(dataRendering) + ? dataRendering + : dataRendering === 'true', + isRendered = isBool(dataRendered) + ? dataRendered + : dataRendered === 'true'; + + if (!isRendering && !isRendered) { logger.info(MESSAGES_RETRIEVING); $component.attr('data-rendering', true); - $component.html('
' + MESSAGES_LOADING_COMPONENT + '
'); + $component.html( + '
' + MESSAGES_LOADING_COMPONENT + '
' + ); - oc.renderByHref($component.attr('href'), function(err, data){ - if(err || !data){ + oc.renderByHref($component.attr('href'), function(err, data) { + if (err || !data) { $component.html(''); logger.error(err); return callback(); @@ -394,38 +440,47 @@ var oc = oc || {}; }); }; - oc.renderByHref = function(href, retryNumberOrCallback, cb){ + oc.renderByHref = function(href, retryNumberOrCallback, cb) { var callback = cb, retryNumber = retryNumberOrCallback; - if(typeof retryNumberOrCallback === 'function') { + if (typeof retryNumberOrCallback === 'function') { callback = retryNumberOrCallback; retryNumber = 0; } - oc.ready(function(){ - - if(href !== ''){ + oc.ready(function() { + if (href !== '') { var hrefWithCount = href; - if(RETRY_SEND_NUMBER) { + if (RETRY_SEND_NUMBER) { hrefWithCount = addParametersToHref(hrefWithCount, { - '__oc_Retry': retryNumber + __oc_Retry: retryNumber }); } oc.$.ajax({ url: hrefWithCount, - headers: { 'Accept': 'application/vnd.oc.unrendered+json' }, + headers: { Accept: 'application/vnd.oc.unrendered+json' }, contentType: 'text/plain', crossDomain: true, async: true, - success: function(apiResponse){ - if(apiResponse.renderMode === 'unrendered'){ - oc.render(apiResponse.template, apiResponse.data, function(err, html){ - if(err){ - return callback(MESSAGES_ERRORS_RENDERING.replace('{0}', apiResponse.href).replace('{1}', err)); + success: function(apiResponse) { + if (apiResponse.renderMode === 'unrendered') { + oc.render(apiResponse.template, apiResponse.data, function( + err, + html + ) { + if (err) { + return callback( + MESSAGES_ERRORS_RENDERING.replace( + '{0}', + apiResponse.href + ).replace('{1}', err) + ); } - logger.info(MESSAGES_RENDERED.replace('{0}', apiResponse.template.src)); + logger.info( + MESSAGES_RENDERED.replace('{0}', apiResponse.template.src) + ); callback(null, { html: html, key: apiResponse.template.key, @@ -433,13 +488,17 @@ var oc = oc || {}; name: apiResponse.name }); }); - } else if(apiResponse.renderMode === 'rendered'){ + } else if (apiResponse.renderMode === 'rendered') { logger.info(MESSAGES_RENDERED.replace('{0}', apiResponse.href)); - if(apiResponse.html.indexOf('<' + OC_TAG) === 0){ - - var innerHtmlPlusEnding = apiResponse.html.slice(apiResponse.html.indexOf('>') + 1), - innerHtml = innerHtmlPlusEnding.slice(0, innerHtmlPlusEnding.lastIndexOf('<')); + if (apiResponse.html.indexOf('<' + OC_TAG) === 0) { + var innerHtmlPlusEnding = apiResponse.html.slice( + apiResponse.html.indexOf('>') + 1 + ), + innerHtml = innerHtmlPlusEnding.slice( + 0, + innerHtmlPlusEnding.lastIndexOf('<') + ); apiResponse.html = innerHtml; } @@ -450,51 +509,57 @@ var oc = oc || {}; }); } }, - error: function(){ + error: function() { logger.error(MESSAGES_ERRORS_RETRIEVING); - retry(href, function(requestNumber) { - oc.renderByHref(href, requestNumber, callback); - }, function(){ - callback(MESSAGES_ERRORS_RETRY_FAILED.replace('{0}', href)); - }); + retry( + href, + function(requestNumber) { + oc.renderByHref(href, requestNumber, callback); + }, + function() { + callback(MESSAGES_ERRORS_RETRY_FAILED.replace('{0}', href)); + } + ); } }); } else { - return callback(MESSAGES_ERRORS_RENDERING.replace('{1}', MESSAGES_ERRORS_HREF_MISSING)); + return callback( + MESSAGES_ERRORS_RENDERING.replace('{1}', MESSAGES_ERRORS_HREF_MISSING) + ); } }); }; - oc.renderUnloadedComponents = function(){ - oc.ready(function(){ + oc.renderUnloadedComponents = function() { + oc.ready(function() { var $unloadedComponents = oc.$(OC_TAG + '[data-rendered!=true]'), toDo = $unloadedComponents.length; - var done = function(){ + var done = function() { toDo--; - if(!toDo){ + if (!toDo) { oc.renderUnloadedComponents(); } }; - if(toDo > 0){ - for(var i = 0; i < $unloadedComponents.length; i++){ + if (toDo > 0) { + for (var i = 0; i < $unloadedComponents.length; i++) { oc.renderNestedComponent(oc.$($unloadedComponents[i]), done); } } }); }; - oc.load = function(placeholder, href, callback){ - oc.ready(function(){ - if(typeof(callback) !== 'function'){ + oc.load = function(placeholder, href, callback) { + oc.ready(function() { + if (typeof callback !== 'function') { callback = noop; } - if(oc.$(placeholder)){ + if (oc.$(placeholder)) { oc.$(placeholder).html('<' + OC_TAG + ' href="' + href + '" />'); var newComponent = oc.$(OC_TAG, placeholder); - oc.renderNestedComponent(newComponent, function(){ + oc.renderNestedComponent(newComponent, function() { callback(newComponent); }); } @@ -506,4 +571,4 @@ var oc = oc || {}; // expose public variables and methods exports = oc; -})); +}); diff --git a/src/registry/app-start.js b/src/registry/app-start.js index e5d1c97ec..7a57c41a5 100644 --- a/src/registry/app-start.js +++ b/src/registry/app-start.js @@ -7,42 +7,62 @@ const _ = require('lodash'); const packageInfo = require('../components/oc-client/_package/package'); -module.exports = function(repository, options, callback){ - - if(options.local){ +module.exports = function(repository, options, callback) { + if (options.local) { return callback(null, 'ok'); } const logger = options.verbosity ? console : { log: _.noop }; - logger.log(format(colors.yellow('Connecting to library: {0}/{1}'), options.s3.bucket, options.s3.componentsDir)); + logger.log( + format( + colors.yellow('Connecting to library: {0}/{1}'), + options.s3.bucket, + options.s3.componentsDir + ) + ); repository.getComponentVersions('oc-client', (err, componentInfo) => { - - if(err){ + if (err) { return logger.log(colors.red(err)); } - logger.log(format(colors.yellow('Ensuring oc-client@{0} is available on library...'), packageInfo.version)); - - if(!_.includes(componentInfo, packageInfo.version)){ + logger.log( + format( + colors.yellow('Ensuring oc-client@{0} is available on library...'), + packageInfo.version + ) + ); + if (!_.includes(componentInfo, packageInfo.version)) { logger.log(colors.yellow('Component not found. Publishing it...')); const pkgInfo = { - outputFolder: path.resolve(__dirname, '../components/oc-client/_package'), + outputFolder: path.resolve( + __dirname, + '../components/oc-client/_package' + ), packageJson: packageInfo }; - repository.publishComponent(pkgInfo, 'oc-client', packageInfo.version, (err, res) => { - if(!err){ - logger.log(colors.green('Component published.')); - } else { - logger.log(colors.red(format('Component not published: {0}', _.first(err).message))); - } + repository.publishComponent( + pkgInfo, + 'oc-client', + packageInfo.version, + (err, res) => { + if (!err) { + logger.log(colors.green('Component published.')); + } else { + logger.log( + colors.red( + format('Component not published: {0}', _.first(err).message) + ) + ); + } - callback(err, res); - }); + callback(err, res); + } + ); } else { logger.log(colors.green('Component is available on library.')); callback(null, 'ok'); diff --git a/src/registry/domain/authentication.js b/src/registry/domain/authentication.js index d5777af41..65ca9745d 100644 --- a/src/registry/domain/authentication.js +++ b/src/registry/domain/authentication.js @@ -8,14 +8,17 @@ const strings = require('../../resources/'); const builtin = { basic: { - validate: function(authConfig){ + validate: function(authConfig) { const isValid = authConfig.username && authConfig.password; return { isValid: isValid, - message: isValid ? '' : strings.errors.registry.CONFIGURATION_PUBLISH_BASIC_AUTH_CREDENTIALS_MISSING + message: isValid + ? '' + : strings.errors.registry + .CONFIGURATION_PUBLISH_BASIC_AUTH_CREDENTIALS_MISSING }; }, - middleware: function(authConfig){ + middleware: function(authConfig) { return basicAuth(authConfig.username, authConfig.password); } } @@ -23,11 +26,10 @@ const builtin = { let scheme; -module.exports.validate = function(authConfig){ - if(builtin[authConfig.type]){ +module.exports.validate = function(authConfig) { + if (builtin[authConfig.type]) { scheme = builtin[authConfig.type]; - } - else { + } else { const cwd = process.cwd(); module.paths.push(cwd, path.join(cwd, 'node_modules')); @@ -35,10 +37,13 @@ module.exports.validate = function(authConfig){ try { scheme = require(moduleName); - } catch(err){ + } catch (err) { return { isValid: false, - message: format(strings.errors.registry.CONFIGURATION_PUBLISH_AUTH_MODULE_NOT_FOUND, moduleName) + message: format( + strings.errors.registry.CONFIGURATION_PUBLISH_AUTH_MODULE_NOT_FOUND, + moduleName + ) }; } } @@ -46,6 +51,6 @@ module.exports.validate = function(authConfig){ return scheme.validate(authConfig); }; -module.exports.middleware = function(authConfig){ +module.exports.middleware = function(authConfig) { return scheme.middleware(authConfig); }; diff --git a/src/registry/domain/components-cache/components-list.js b/src/registry/domain/components-cache/components-list.js index c69f3228c..94ee6ffae 100644 --- a/src/registry/domain/components-cache/components-list.js +++ b/src/registry/domain/components-cache/components-list.js @@ -7,26 +7,29 @@ const _ = require('lodash'); const getUnixUTCTimestamp = require('../../../utils/get-unix-utc-timestamp'); module.exports = (conf, cdn) => { - const filePath = () => `${conf.s3.componentsDir}/components.json`; const componentsList = { - getFromJson: callback => cdn.getJson(filePath(), true, callback), - getFromDirectories: (callback) => { + getFromDirectories: callback => { const componentsInfo = {}; const getVersionsForComponent = (componentName, cb) => { - cdn.listSubDirectories(`${conf.s3.componentsDir}/${componentName}`, (err, versions) => { - if(err){ return cb(err); } - cb(null, versions.sort(semver.compare)); - }); + cdn.listSubDirectories( + `${conf.s3.componentsDir}/${componentName}`, + (err, versions) => { + if (err) { + return cb(err); + } + cb(null, versions.sort(semver.compare)); + } + ); }; cdn.listSubDirectories(conf.s3.componentsDir, (err, components) => { - if(err){ - if(err.code === 'dir_not_found'){ + if (err) { + if (err.code === 'dir_not_found') { return callback(null, { lastEdit: getUnixUTCTimestamp(), components: [] @@ -37,7 +40,9 @@ module.exports = (conf, cdn) => { } async.map(components, getVersionsForComponent, (errors, versions) => { - if(errors){ return callback(errors); } + if (errors) { + return callback(errors); + } _.forEach(components, (component, i) => { componentsInfo[component] = versions[i]; @@ -51,17 +56,22 @@ module.exports = (conf, cdn) => { }); }, - refresh: (callback) => { + refresh: callback => { componentsList.getFromDirectories((err, components) => { - if(err){ return callback(err); } - componentsList.save(components, (err) => { - if(err){ return callback(err); } + if (err) { + return callback(err); + } + componentsList.save(components, err => { + if (err) { + return callback(err); + } callback(err, components); }); }); }, - save: (data, callback) => cdn.putFileContent(JSON.stringify(data), filePath(), true, callback) + save: (data, callback) => + cdn.putFileContent(JSON.stringify(data), filePath(), true, callback) }; return componentsList; diff --git a/src/registry/domain/components-cache/index.js b/src/registry/domain/components-cache/index.js index 38f43164c..5b84f6c3f 100644 --- a/src/registry/domain/components-cache/index.js +++ b/src/registry/domain/components-cache/index.js @@ -7,25 +7,28 @@ const eventsHandler = require('../events-handler'); const getUnixUTCTimestamp = require('../../../utils/get-unix-utc-timestamp'); module.exports = (conf, cdn) => { - let cachedComponentsList, refreshLoop; const componentsList = ComponentsList(conf, cdn); - const poll = () => setTimeout(() => { - componentsList.getFromJson((err, data) => { - if(err){ - eventsHandler.fire('error', { code: 'components_list_get', message: err }); - } else { - eventsHandler.fire('cache-poll', getUnixUTCTimestamp()); + const poll = () => + setTimeout(() => { + componentsList.getFromJson((err, data) => { + if (err) { + eventsHandler.fire('error', { + code: 'components_list_get', + message: err + }); + } else { + eventsHandler.fire('cache-poll', getUnixUTCTimestamp()); - if(data.lastEdit > cachedComponentsList.lastEdit){ - cachedComponentsList = data; + if (data.lastEdit > cachedComponentsList.lastEdit) { + cachedComponentsList = data; + } } - } - refreshLoop = poll(); - }); - }, conf.pollingInterval * 1000); + refreshLoop = poll(); + }); + }, conf.pollingInterval * 1000); const cacheDataAndStartPolling = (data, callback) => { cachedComponentsList = data; @@ -39,23 +42,29 @@ module.exports = (conf, cdn) => { }; return { - get: (callback) => { - if(!cachedComponentsList){ - return returnError('components_cache_empty', `The component's cache was empty`, callback); + get: callback => { + if (!cachedComponentsList) { + return returnError( + 'components_cache_empty', + `The component's cache was empty`, + callback + ); } callback(null, cachedComponentsList); }, - load: (callback) => { - + load: callback => { componentsList.getFromJson((jsonErr, jsonComponents) => { componentsList.getFromDirectories((dirErr, dirComponents) => { - if(dirErr){ + if (dirErr) { return returnError('components_list_get', dirErr, callback); - } else if(jsonErr || !_.isEqual(dirComponents.components, jsonComponents.components)){ - componentsList.save(dirComponents, (saveErr) => { - if(saveErr){ + } else if ( + jsonErr || + !_.isEqual(dirComponents.components, jsonComponents.components) + ) { + componentsList.save(dirComponents, saveErr => { + if (saveErr) { return returnError('components_list_save', saveErr, callback); } cacheDataAndStartPolling(dirComponents, callback); @@ -66,10 +75,10 @@ module.exports = (conf, cdn) => { }); }); }, - refresh: (callback) => { + refresh: callback => { clearTimeout(refreshLoop); componentsList.refresh((err, components) => { - if(err){ + if (err) { return returnError('components_cache_refresh', err, callback); } diff --git a/src/registry/domain/components-details.js b/src/registry/domain/components-details.js index 90f274b02..ef826fefb 100644 --- a/src/registry/domain/components-details.js +++ b/src/registry/domain/components-details.js @@ -7,7 +7,6 @@ const eventsHandler = require('./events-handler'); const getUnixUTCTimestamp = require('../../utils/get-unix-utc-timestamp'); module.exports = (conf, cdn) => { - const returnError = (code, message, callback) => { eventsHandler.fire('error', { code, message }); return callback(code); @@ -18,42 +17,61 @@ module.exports = (conf, cdn) => { const getFromJson = callback => cdn.getJson(filePath(), true, callback); const getFromDirectories = (options, callback) => { - const details = _.extend({}, _.cloneDeep(options.details)); details.components = details.components || {}; - async.eachOfSeries(options.componentsList.components, (versions, name, done) => { - - details.components[name] = details.components[name] || {}; - - async.eachLimit(versions, cdn.maxConcurrentRequests, (version, next) => { - if(details.components[name][version]){ - next(); - } else { - cdn.getJson(`${conf.s3.componentsDir}/${name}/${version}/package.json`, true, (err, content) => { - if(err){ return next(err); } - details.components[name][version] = { publishDate: content.oc.date || 0 }; - next(); - }); - } - }, done); - }, (err) => callback(err, { - lastEdit: getUnixUTCTimestamp(), - components: details.components - })); + async.eachOfSeries( + options.componentsList.components, + (versions, name, done) => { + details.components[name] = details.components[name] || {}; + + async.eachLimit( + versions, + cdn.maxConcurrentRequests, + (version, next) => { + if (details.components[name][version]) { + next(); + } else { + cdn.getJson( + `${conf.s3.componentsDir}/${name}/${version}/package.json`, + true, + (err, content) => { + if (err) { + return next(err); + } + details.components[name][version] = { + publishDate: content.oc.date || 0 + }; + next(); + } + ); + } + }, + done + ); + }, + err => + callback(err, { + lastEdit: getUnixUTCTimestamp(), + components: details.components + }) + ); }; - const save = (data, callback) => cdn.putFileContent(JSON.stringify(data), filePath(), true, callback); + const save = (data, callback) => + cdn.putFileContent(JSON.stringify(data), filePath(), true, callback); const refresh = (componentsList, callback) => { - getFromJson((jsonErr, details) => { getFromDirectories({ componentsList, details }, (dirErr, dirDetails) => { - if(dirErr){ + if (dirErr) { return returnError('components_details_get', dirErr, callback); - } else if(jsonErr || !_.isEqual(dirDetails.components, details.components)){ - save(dirDetails, (saveErr) => { - if(saveErr){ + } else if ( + jsonErr || + !_.isEqual(dirDetails.components, details.components) + ) { + save(dirDetails, saveErr => { + if (saveErr) { return returnError('components_details_save', saveErr, callback); } diff --git a/src/registry/domain/events-handler.js b/src/registry/domain/events-handler.js index d9cb196e0..32f588681 100644 --- a/src/registry/domain/events-handler.js +++ b/src/registry/domain/events-handler.js @@ -7,25 +7,25 @@ const strings = require('../../resources'); let subscriptions = {}; module.exports = { - fire: function(eventName, eventData){ - if(subscriptions[eventName]){ - _.forEach(subscriptions[eventName], (callback) => { + fire: function(eventName, eventData) { + if (subscriptions[eventName]) { + _.forEach(subscriptions[eventName], callback => { callback(eventData); }); } }, - on: function(eventName, callback){ - if(!_.isFunction(callback)){ - throw(strings.errors.registry.CONFIGURATION_ONREQUEST_MUST_BE_FUNCTION); + on: function(eventName, callback) { + if (!_.isFunction(callback)) { + throw strings.errors.registry.CONFIGURATION_ONREQUEST_MUST_BE_FUNCTION; } - if(!subscriptions[eventName]){ + if (!subscriptions[eventName]) { subscriptions[eventName] = []; } subscriptions[eventName].push(callback); }, - reset: function(){ + reset: function() { subscriptions = {}; } }; diff --git a/src/registry/domain/extract-package.js b/src/registry/domain/extract-package.js index cf3dcc943..29abae9d1 100644 --- a/src/registry/domain/extract-package.js +++ b/src/registry/domain/extract-package.js @@ -5,25 +5,32 @@ const targz = require('targz'); const getPackageJsonFromTempDir = require('./get-package-json-from-temp-dir'); -module.exports = function(files, callback){ - +module.exports = function(files, callback) { const packageFile = files[0], packagePath = path.resolve(packageFile.path), - packageUntarOutput = path.resolve(packageFile.path, '..', packageFile.filename.replace('.tar.gz', '')), + packageUntarOutput = path.resolve( + packageFile.path, + '..', + packageFile.filename.replace('.tar.gz', '') + ), packageOutput = path.resolve(packageUntarOutput, '_package'); - targz.decompress({ - src: packagePath, - dest: packageUntarOutput - }, (err) => { - - if(err){ return callback(err); } + targz.decompress( + { + src: packagePath, + dest: packageUntarOutput + }, + err => { + if (err) { + return callback(err); + } - getPackageJsonFromTempDir(packageOutput, (err, packageJson) => { - callback(err, { - outputFolder: packageOutput, - packageJson: packageJson + getPackageJsonFromTempDir(packageOutput, (err, packageJson) => { + callback(err, { + outputFolder: packageOutput, + packageJson: packageJson + }); }); - }); - }); + } + ); }; diff --git a/src/registry/domain/get-package-json-from-temp-dir.js b/src/registry/domain/get-package-json-from-temp-dir.js index 170b57515..658687145 100644 --- a/src/registry/domain/get-package-json-from-temp-dir.js +++ b/src/registry/domain/get-package-json-from-temp-dir.js @@ -3,6 +3,6 @@ const fs = require('fs-extra'); const path = require('path'); -module.exports = function(tempDirPath, callback){ +module.exports = function(tempDirPath, callback) { return fs.readJson(path.join(tempDirPath, 'package.json'), callback); }; diff --git a/src/registry/domain/nested-renderer.js b/src/registry/domain/nested-renderer.js index 37add48b6..c92167370 100644 --- a/src/registry/domain/nested-renderer.js +++ b/src/registry/domain/nested-renderer.js @@ -7,21 +7,21 @@ const settings = require('../../resources/settings'); const strings = require('../../resources'); const sanitise = { - componentParams: function(component, options, callback){ + componentParams: function(component, options, callback) { return _.extend(sanitise.options(options, callback), { componentName: component }); }, - componentsParams: function(components, options, callback){ + componentsParams: function(components, options, callback) { return _.extend(sanitise.options(options, callback), { components: components }); }, - headers: function(h){ + headers: function(h) { return _.extend({}, h, { accept: settings.registry.acceptRenderedHeader }); }, - options: function(options, callback){ - if(!callback && _.isFunction(options)){ + options: function(options, callback) { + if (!callback && _.isFunction(options)) { callback = options; options = {}; } @@ -34,65 +34,86 @@ const sanitise = { }; const validate = { - callback: function(c){ - if(!c || !_.isFunction(c)){ - throw new Error(strings.errors.registry.NESTED_RENDERER_CALLBACK_IS_NOT_VALID); + callback: function(c) { + if (!c || !_.isFunction(c)) { + throw new Error( + strings.errors.registry.NESTED_RENDERER_CALLBACK_IS_NOT_VALID + ); } }, - componentParams: function(params){ - if(!params.componentName){ - throw new Error(strings.errors.registry.NESTED_RENDERER_COMPONENT_NAME_IS_NOT_VALID); + componentParams: function(params) { + if (!params.componentName) { + throw new Error( + strings.errors.registry.NESTED_RENDERER_COMPONENT_NAME_IS_NOT_VALID + ); } validate.callback(params.callback); }, - componentsParams: function(params){ - if(_.isEmpty(params.components)){ - throw new Error(strings.errors.registry.NESTED_RENDERER_COMPONENTS_IS_NOT_VALID); + componentsParams: function(params) { + if (_.isEmpty(params.components)) { + throw new Error( + strings.errors.registry.NESTED_RENDERER_COMPONENTS_IS_NOT_VALID + ); } validate.callback(params.callback); } }; -module.exports = function(renderer, conf){ +module.exports = function(renderer, conf) { return { - renderComponent: function(componentName, renderOptions, callback){ - - const p = sanitise.componentParams(componentName, renderOptions, callback); + renderComponent: function(componentName, renderOptions, callback) { + const p = sanitise.componentParams( + componentName, + renderOptions, + callback + ); validate.componentParams(p); - return renderer({ - conf: conf, - headers: sanitise.headers(p.options.headers), - name: componentName, - parameters: p.options.parameters || {}, - version: p.options.version || '' - }, (result) => { - if(result.response.error){ - return p.callback(result.response.error); - } else { - return p.callback(null, result.response.html); + return renderer( + { + conf: conf, + headers: sanitise.headers(p.options.headers), + name: componentName, + parameters: p.options.parameters || {}, + version: p.options.version || '' + }, + result => { + if (result.response.error) { + return p.callback(result.response.error); + } else { + return p.callback(null, result.response.html); + } } - }); + ); }, - renderComponents: function(components, renderOptions, callback){ - + renderComponents: function(components, renderOptions, callback) { const p = sanitise.componentsParams(components, renderOptions, callback); validate.componentsParams(p); - async.map(p.components, (component, cb) => { - renderer({ - conf: conf, - headers: sanitise.headers(p.options.headers), - name: component.name, - parameters: _.extend(_.clone(p.options.parameters) || {}, component.parameters || {}), - version: component.version || '' - }, (result) => { - const error = result.response.error; - cb(null, error ? new Error(error) : result.response.html); - }); - }, p.callback); + async.map( + p.components, + (component, cb) => { + renderer( + { + conf: conf, + headers: sanitise.headers(p.options.headers), + name: component.name, + parameters: _.extend( + _.clone(p.options.parameters) || {}, + component.parameters || {} + ), + version: component.version || '' + }, + result => { + const error = result.response.error; + cb(null, error ? new Error(error) : result.response.html); + } + ); + }, + p.callback + ); } }; }; diff --git a/src/registry/domain/options-sanitiser.js b/src/registry/domain/options-sanitiser.js index f0d6fa217..bdfc1bcc1 100644 --- a/src/registry/domain/options-sanitiser.js +++ b/src/registry/domain/options-sanitiser.js @@ -5,44 +5,49 @@ const _ = require('lodash'); const settings = require('../../resources/settings'); const auth = require('./authentication'); -module.exports = function(input){ +module.exports = function(input) { const options = _.clone(input); - if(!options.publishAuth){ - options.beforePublish = function(req, res, next){ next(); }; + if (!options.publishAuth) { + options.beforePublish = function(req, res, next) { + next(); + }; } else { options.beforePublish = auth.middleware(options.publishAuth); } - if(!options.publishValidation){ - options.publishValidation = function(){ + if (!options.publishValidation) { + options.publishValidation = function() { return { isValid: true }; }; } - if(!options.prefix){ + if (!options.prefix) { options.prefix = '/'; } - if(!options.tempDir){ + if (!options.tempDir) { options.tempDir = settings.registry.defaultTempPath; } - if(!_.isBoolean(options.hotReloading)){ + if (!_.isBoolean(options.hotReloading)) { options.hotReloading = !!options.local; } - if(_.isUndefined(options.verbosity)){ + if (_.isUndefined(options.verbosity)) { options.verbosity = 0; } - if(!_.isUndefined(options.fallbackRegistryUrl) && - _.last(options.fallbackRegistryUrl) !== '/'){ + if ( + !_.isUndefined(options.fallbackRegistryUrl) && + _.last(options.fallbackRegistryUrl) !== '/' + ) { options.fallbackRegistryUrl += '/'; } - options.customHeadersToSkipOnWeakVersion = (options.customHeadersToSkipOnWeakVersion || []) - .map((s) => s.toLowerCase()); + options.customHeadersToSkipOnWeakVersion = (options.customHeadersToSkipOnWeakVersion || + []) + .map(s => s.toLowerCase()); options.port = process.env.PORT || options.port; diff --git a/src/registry/domain/plugins-detective.js b/src/registry/domain/plugins-detective.js index d1844b534..ac18439c3 100644 --- a/src/registry/domain/plugins-detective.js +++ b/src/registry/domain/plugins-detective.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports.parse = (code) => { +module.exports.parse = code => { const names = []; const parts = code.split('plugins'); for (let index = 1; index < parts.length; index++) { diff --git a/src/registry/domain/plugins-initialiser.js b/src/registry/domain/plugins-initialiser.js index 882bfe61d..aeeded024 100644 --- a/src/registry/domain/plugins-initialiser.js +++ b/src/registry/domain/plugins-initialiser.js @@ -7,36 +7,40 @@ const DepGraph = require('dependency-graph').DepGraph; const strings = require('../../resources'); -const validatePlugins = function(plugins){ +const validatePlugins = function(plugins) { let c = 0; - plugins.forEach((plugin) => { + plugins.forEach(plugin => { c++; - if(!_.isObject(plugin.register) || !_.isFunction(plugin.register.register) || - !_.isFunction(plugin.register.execute) || !_.isString(plugin.name)){ - - throw new Error(format(strings.errors.registry.PLUGIN_NOT_VALID, plugin.name || c)); + if ( + !_.isObject(plugin.register) || + !_.isFunction(plugin.register.register) || + !_.isFunction(plugin.register.execute) || + !_.isString(plugin.name) + ) { + throw new Error( + format(strings.errors.registry.PLUGIN_NOT_VALID, plugin.name || c) + ); } }); }; -const checkDependencies = function(plugins){ +const checkDependencies = function(plugins) { const graph = new DepGraph(); - plugins.forEach((p) => { + plugins.forEach(p => { graph.addNode(p.name); }); - plugins.forEach((p) => { - if(!p.register.dependencies){ + plugins.forEach(p => { + if (!p.register.dependencies) { return; } - p.register.dependencies.forEach((d) => { + p.register.dependencies.forEach(d => { try { graph.addDependency(p.name, d); - } - catch(err) { + } catch (err) { throw new Error('unknown plugin dependency: ' + d); } }); @@ -46,31 +50,29 @@ const checkDependencies = function(plugins){ }; let deferredLoads = []; -const defer = function(plugin, cb){ +const defer = function(plugin, cb) { deferredLoads.push(plugin); return cb(); }; -module.exports.init = function(pluginsToRegister, callback){ - +module.exports.init = function(pluginsToRegister, callback) { const registered = {}; try { validatePlugins(pluginsToRegister); checkDependencies(pluginsToRegister); - } - catch(err){ + } catch (err) { return callback(err); } - const dependenciesRegistered = function(dependencies){ - if(dependencies.length === 0){ + const dependenciesRegistered = function(dependencies) { + if (dependencies.length === 0) { return true; } let present = true; - dependencies.forEach((d) => { - if(!registered[d]){ + dependencies.forEach(d => { + if (!registered[d]) { present = false; } }); @@ -78,28 +80,32 @@ module.exports.init = function(pluginsToRegister, callback){ return present; }; - const loadPlugin = function(plugin, cb){ - if(registered[plugin.name]){ + const loadPlugin = function(plugin, cb) { + if (registered[plugin.name]) { return cb(); } - if(!plugin.register.dependencies){ + if (!plugin.register.dependencies) { plugin.register.dependencies = []; } - if(!dependenciesRegistered(plugin.register.dependencies)){ + if (!dependenciesRegistered(plugin.register.dependencies)) { return defer(plugin, cb); } const dependencies = _.pick(registered, plugin.register.dependencies); - plugin.register.register(plugin.options || {}, dependencies, plugin.callback || _.noop); + plugin.register.register( + plugin.options || {}, + dependencies, + plugin.callback || _.noop + ); registered[plugin.name] = plugin.register.execute; cb(); }; - const terminator = function(err){ - if(deferredLoads.length > 0){ + const terminator = function(err) { + if (deferredLoads.length > 0) { const deferredPlugins = _.clone(deferredLoads); deferredLoads = []; diff --git a/src/registry/domain/repository.js b/src/registry/domain/repository.js index 16ad350de..07adb41dd 100644 --- a/src/registry/domain/repository.js +++ b/src/registry/domain/repository.js @@ -15,45 +15,57 @@ const strings = require('../../resources'); const validator = require('./validators'); const versionHandler = require('./version-handler'); -module.exports = function(conf){ - +module.exports = function(conf) { const cdn = !conf.local && new S3(conf); const repositorySource = conf.local ? 'local repository' : 's3 cdn'; const componentsCache = ComponentsCache(conf, cdn); const componentsDetails = ComponentsDetails(conf, cdn); - const getFilePath = (component, version, filePath) => `${conf.s3.componentsDir}/${component}/${version}/${filePath}`; + const getFilePath = (component, version, filePath) => + `${conf.s3.componentsDir}/${component}/${version}/${filePath}`; const coreTemplates = ['oc-template-jade', 'oc-template-handlebars']; - const templates = _ - .union(coreTemplates, conf.templates) - .map((template) => { - try { - const ocTemplate = requireTemplate(template); - const info = ocTemplate.getInfo(); - return { - type: info.type, - version: info.version, - externals: info.externals - }; - } catch (err) { - throw err; - } - }); + const templates = _.union(coreTemplates, conf.templates).map(template => { + try { + const ocTemplate = requireTemplate(template); + const info = ocTemplate.getInfo(); + return { + type: info.type, + version: info.version, + externals: info.externals + }; + } catch (err) { + throw err; + } + }); const local = { - getCompiledView: (componentName) => { - if(componentName === 'oc-client'){ - return fs.readFileSync(path.join(__dirname, '../../components/oc-client/_package/template.js')).toString(); + getCompiledView: componentName => { + if (componentName === 'oc-client') { + return fs + .readFileSync( + path.join( + __dirname, + '../../components/oc-client/_package/template.js' + ) + ) + .toString(); } - return fs.readFileSync(path.join(conf.path, `${componentName}/_package/template.js`)).toString(); + return fs + .readFileSync( + path.join(conf.path, `${componentName}/_package/template.js`) + ) + .toString(); }, getComponents: () => { - - const validComponents = fs.readdirSync(conf.path).filter((file) => { + const validComponents = fs.readdirSync(conf.path).filter(file => { const isDir = fs.lstatSync(path.join(conf.path, file)).isDirectory(); - const isValidComponent = isDir ? (fs.readdirSync(path.join(conf.path, file)).filter((file) => file === '_package').length === 1) : false; + const isValidComponent = isDir + ? fs + .readdirSync(path.join(conf.path, file)) + .filter(file => file === '_package').length === 1 + : false; return isValidComponent; }); @@ -62,189 +74,308 @@ module.exports = function(conf){ return validComponents; }, getComponentVersions: (componentName, callback) => { - if(componentName === 'oc-client'){ - return callback(null, [fs.readJsonSync(path.join(__dirname, '../../../package.json')).version]); + if (componentName === 'oc-client') { + return callback(null, [ + fs.readJsonSync(path.join(__dirname, '../../../package.json')).version + ]); } - if(!_.includes(local.getComponents(), componentName)){ - return callback(format(strings.errors.registry.COMPONENT_NOT_FOUND, componentName, repositorySource)); + if (!_.includes(local.getComponents(), componentName)) { + return callback( + format( + strings.errors.registry.COMPONENT_NOT_FOUND, + componentName, + repositorySource + ) + ); } - callback(null, [fs.readJsonSync(path.join(conf.path, `${componentName}/package.json`)).version]); + callback(null, [ + fs.readJsonSync(path.join(conf.path, `${componentName}/package.json`)) + .version + ]); }, - getDataProvider: (componentName) => { - if(componentName === 'oc-client'){ - return fs.readFileSync(path.join(__dirname, '../../components/oc-client/_package/server.js')).toString(); + getDataProvider: componentName => { + if (componentName === 'oc-client') { + return fs + .readFileSync( + path.join( + __dirname, + '../../components/oc-client/_package/server.js' + ) + ) + .toString(); } - return fs.readFileSync(path.join(conf.path, `${componentName}/_package/server.js`)).toString(); + return fs + .readFileSync( + path.join(conf.path, `${componentName}/_package/server.js`) + ) + .toString(); } }; const repository = { getCompiledView: (componentName, componentVersion, callback) => { - if(conf.local){ - return callback(null, local.getCompiledView(componentName, componentVersion)); + if (conf.local) { + return callback( + null, + local.getCompiledView(componentName, componentVersion) + ); } - cdn.getFile(getFilePath(componentName, componentVersion, 'template.js'), callback); + cdn.getFile( + getFilePath(componentName, componentVersion, 'template.js'), + callback + ); }, getComponent: (componentName, componentVersion, callback) => { - - if(_.isFunction(componentVersion)){ + if (_.isFunction(componentVersion)) { callback = componentVersion; componentVersion = undefined; } repository.getComponentVersions(componentName, (err, allVersions) => { - - if(err){ + if (err) { return callback(err); } - if(allVersions.length === 0){ - return callback(format(strings.errors.registry.COMPONENT_NOT_FOUND, componentName, repositorySource)); + if (allVersions.length === 0) { + return callback( + format( + strings.errors.registry.COMPONENT_NOT_FOUND, + componentName, + repositorySource + ) + ); } - const version = versionHandler.getAvailableVersion(componentVersion, allVersions); - - if(!version){ - return callback(format(strings.errors.registry.COMPONENT_VERSION_NOT_FOUND, componentName, componentVersion, repositorySource)); + const version = versionHandler.getAvailableVersion( + componentVersion, + allVersions + ); + + if (!version) { + return callback( + format( + strings.errors.registry.COMPONENT_VERSION_NOT_FOUND, + componentName, + componentVersion, + repositorySource + ) + ); } - repository.getComponentInfo(componentName, version, (err, component) => { - if(err){ - return callback(`component not available: ${err}`, null); + repository.getComponentInfo( + componentName, + version, + (err, component) => { + if (err) { + return callback(`component not available: ${err}`, null); + } + callback(null, _.extend(component, { allVersions })); } - callback(null, _.extend(component, { allVersions })); - }); + ); }); }, getComponentInfo: (componentName, componentVersion, callback) => { - if(conf.local){ + if (conf.local) { let componentInfo; - if(componentName === 'oc-client'){ - componentInfo = fs.readJsonSync(path.join(__dirname, '../../components/oc-client/_package/package.json')); + if (componentName === 'oc-client') { + componentInfo = fs.readJsonSync( + path.join( + __dirname, + '../../components/oc-client/_package/package.json' + ) + ); } else { - componentInfo = fs.readJsonSync(path.join(conf.path, `${componentName}/_package/package.json`)); + componentInfo = fs.readJsonSync( + path.join(conf.path, `${componentName}/_package/package.json`) + ); } - if(componentInfo.version === componentVersion){ + if (componentInfo.version === componentVersion) { return callback(null, componentInfo); } else { return callback('version not available'); } } - cdn.getJson(getFilePath(componentName, componentVersion, 'package.json'), callback); + cdn.getJson( + getFilePath(componentName, componentVersion, 'package.json'), + callback + ); }, getComponentPath: (componentName, componentVersion) => { - const prefix = conf.local ? conf.baseUrl : `https:${conf.s3.path}${conf.s3.componentsDir}/`; + const prefix = conf.local + ? conf.baseUrl + : `https:${conf.s3.path}${conf.s3.componentsDir}/`; return `${prefix}${componentName}/${componentVersion}/`; }, - getComponents: (callback) => { - if(conf.local){ + getComponents: callback => { + if (conf.local) { return callback(null, local.getComponents()); } - componentsCache.get((err, res) => callback(err, res ? _.keys(res.components) : null)); + componentsCache.get((err, res) => + callback(err, res ? _.keys(res.components) : null) + ); }, - getComponentsDetails: (callback) => { - if(conf.local){ + getComponentsDetails: callback => { + if (conf.local) { return callback(); } componentsDetails.get(callback); }, getComponentVersions: (componentName, callback) => { - if(conf.local){ + if (conf.local) { return local.getComponentVersions(componentName, callback); } componentsCache.get((err, res) => { - callback(err, (!!res && !!_.has(res.components, componentName)) ? res.components[componentName] : []); + callback( + err, + !!res && !!_.has(res.components, componentName) + ? res.components[componentName] + : [] + ); }); }, getDataProvider: (componentName, componentVersion, callback) => { - if(conf.local){ + if (conf.local) { return callback(null, local.getDataProvider(componentName)); } - cdn.getFile(getFilePath(componentName, componentVersion, 'server.js'), callback); + cdn.getFile( + getFilePath(componentName, componentVersion, 'server.js'), + callback + ); }, getStaticClientPath: () => - `https:${conf.s3.path}${getFilePath('oc-client', packageInfo.version, 'src/oc-client.min.js')}`, + `https:${conf.s3.path}${getFilePath( + 'oc-client', + packageInfo.version, + 'src/oc-client.min.js' + )}`, getStaticClientMapPath: () => - `https:${conf.s3.path}${getFilePath('oc-client', packageInfo.version, 'src/oc-client.min.map')}`, + `https:${conf.s3.path}${getFilePath( + 'oc-client', + packageInfo.version, + 'src/oc-client.min.map' + )}`, getStaticFilePath: (componentName, componentVersion, filePath) => - `${repository.getComponentPath(componentName, componentVersion)}${(conf.local ? settings.registry.localStaticRedirectorPath : '')}${filePath}`, + `${repository.getComponentPath( + componentName, + componentVersion + )}${conf.local + ? settings.registry.localStaticRedirectorPath + : ''}${filePath}`, getTemplates: () => templates, - init: (callback) => { - if(conf.local){ + init: callback => { + if (conf.local) { return callback(null, 'ok'); } componentsCache.load((err, componentsList) => { - if(err){ return callback(err); } - componentsDetails.refresh(componentsList, (err) => callback(err, componentsList)); + if (err) { + return callback(err); + } + componentsDetails.refresh(componentsList, err => + callback(err, componentsList) + ); }); }, - publishComponent: (pkgDetails, componentName, componentVersion, callback) => { - if(conf.local){ + publishComponent: ( + pkgDetails, + componentName, + componentVersion, + callback + ) => { + if (conf.local) { return callback({ code: strings.errors.registry.LOCAL_PUBLISH_NOT_ALLOWED_CODE, msg: strings.errors.registry.LOCAL_PUBLISH_NOT_ALLOWED }); } - if(!validator.validateComponentName(componentName)){ + if (!validator.validateComponentName(componentName)) { return callback({ code: strings.errors.registry.COMPONENT_NAME_NOT_VALID_CODE, msg: strings.errors.registry.COMPONENT_NAME_NOT_VALID }); } - if(!validator.validateVersion(componentVersion)){ + if (!validator.validateVersion(componentVersion)) { return callback({ code: strings.errors.registry.COMPONENT_VERSION_NOT_VALID_CODE, - msg: format(strings.errors.registry.COMPONENT_VERSION_NOT_VALID, componentVersion) + msg: format( + strings.errors.registry.COMPONENT_VERSION_NOT_VALID, + componentVersion + ) }); } - const validationResult = validator.validatePackageJson(_.extend(pkgDetails, { - componentName, - customValidator: conf.publishValidation - })); + const validationResult = validator.validatePackageJson( + _.extend(pkgDetails, { + componentName, + customValidator: conf.publishValidation + }) + ); - if(!validationResult.isValid){ + if (!validationResult.isValid) { return callback({ code: strings.errors.registry.COMPONENT_PUBLISHVALIDATION_FAIL_CODE, - msg: format(strings.errors.registry.COMPONENT_PUBLISHVALIDATION_FAIL, validationResult.error) + msg: format( + strings.errors.registry.COMPONENT_PUBLISHVALIDATION_FAIL, + validationResult.error + ) }); } - repository.getComponentVersions(componentName, (err, componentVersions) => { + repository.getComponentVersions( + componentName, + (err, componentVersions) => { + if ( + !versionHandler.validateNewVersion( + componentVersion, + componentVersions + ) + ) { + return callback({ + code: + strings.errors.registry.COMPONENT_VERSION_ALREADY_FOUND_CODE, + msg: format( + strings.errors.registry.COMPONENT_VERSION_ALREADY_FOUND, + componentName, + componentVersion, + repositorySource + ) + }); + } - if(!versionHandler.validateNewVersion(componentVersion, componentVersions)){ - return callback({ - code: strings.errors.registry.COMPONENT_VERSION_ALREADY_FOUND_CODE, - msg: format(strings.errors.registry.COMPONENT_VERSION_ALREADY_FOUND, componentName, componentVersion, repositorySource) - }); + cdn.putDir( + pkgDetails.outputFolder, + `${conf.s3.componentsDir}/${componentName}/${componentVersion}`, + err => { + if (err) { + return callback(err); + } + componentsCache.refresh((err, componentsList) => { + if (err) { + return callback(err); + } + componentsDetails.refresh(componentsList, callback); + }); + } + ); } - - cdn.putDir(pkgDetails.outputFolder, `${conf.s3.componentsDir}/${componentName}/${componentVersion}`, (err) => { - if(err){ return callback(err); } - componentsCache.refresh((err, componentsList) => { - if(err){ return callback(err); } - componentsDetails.refresh(componentsList, callback); - }); - }); - }); + ); } }; diff --git a/src/registry/domain/require-wrapper.js b/src/registry/domain/require-wrapper.js index a5e8fa87a..d3c6dc7e1 100644 --- a/src/registry/domain/require-wrapper.js +++ b/src/registry/domain/require-wrapper.js @@ -8,29 +8,34 @@ const _ = require('lodash'); const strings = require('../../resources'); -const isCoreDependency = (x) => _.includes(coreModules, x); -const requireCoreDependency = (x) => isCoreDependency(x) && tryRequire(x) || undefined; +const isCoreDependency = x => _.includes(coreModules, x); +const requireCoreDependency = x => + (isCoreDependency(x) && tryRequire(x)) || undefined; -const requireDependency = (requirePath) => { +const requireDependency = requirePath => { const nodeModulesPath = path.resolve('.', 'node_modules'); const modulePath = path.resolve(nodeModulesPath, requirePath); return tryRequire(modulePath); }; -const throwError = (requirePath) => { +const throwError = requirePath => { throw { code: strings.errors.registry.DEPENDENCY_NOT_FOUND_CODE, missing: [requirePath] }; }; -module.exports = (injectedDependencies) => (requirePath) => { +module.exports = injectedDependencies => requirePath => { const moduleName = requirePackageName(requirePath); const isAllowed = _.includes(injectedDependencies, moduleName); - if(!isAllowed){ + if (!isAllowed) { return throwError(requirePath); } - return requireDependency(requirePath) || requireCoreDependency(requirePath) || throwError(requirePath); + return ( + requireDependency(requirePath) || + requireCoreDependency(requirePath) || + throwError(requirePath) + ); }; diff --git a/src/registry/domain/s3.js b/src/registry/domain/s3.js index 267eea033..37f9a8d69 100644 --- a/src/registry/domain/s3.js +++ b/src/registry/domain/s3.js @@ -12,8 +12,7 @@ const getFileInfo = require('../../utils/get-file-info'); const getNextYear = require('../../utils/get-next-year'); const strings = require('../../resources'); -module.exports = function(conf){ - +module.exports = function(conf) { AWS.config.update({ accessKeyId: conf.s3.key, secretAccessKey: conf.s3.secret, @@ -30,40 +29,48 @@ module.exports = function(conf){ const getClient = () => new AWS.S3(); const getFile = (filePath, force, callback) => { - - if(_.isFunction(force)){ + if (_.isFunction(force)) { callback = force; force = false; } - const getFromAws = (cb) => { - getClient().getObject({ - Bucket: bucket, - Key: filePath - }, (err, data) => { - if(err){ - return callback(err.code === 'NoSuchKey' ? { - code: strings.errors.s3.FILE_NOT_FOUND_CODE, - msg: format(strings.errors.s3.FILE_NOT_FOUND, filePath) - } : err); + const getFromAws = cb => { + getClient().getObject( + { + Bucket: bucket, + Key: filePath + }, + (err, data) => { + if (err) { + return callback( + err.code === 'NoSuchKey' + ? { + code: strings.errors.s3.FILE_NOT_FOUND_CODE, + msg: format(strings.errors.s3.FILE_NOT_FOUND, filePath) + } + : err + ); + } + + cb(null, data.Body.toString()); } - - cb(null, data.Body.toString()); - }); + ); }; - if(force){ + if (force) { return getFromAws(callback); } const cached = cache.get('s3-file', filePath); - if(cached){ + if (cached) { return callback(null, cached); } getFromAws((err, result) => { - if(err){ return callback(err); } + if (err) { + return callback(err); + } cache.set('s3-file', filePath, result); cache.sub('s3-file', filePath, getFromAws); callback(null, result); @@ -71,18 +78,19 @@ module.exports = function(conf){ }; const getJson = (filePath, force, callback) => { - - if(_.isFunction(force)){ + if (_.isFunction(force)) { callback = force; force = false; } getFile(filePath, force, (err, file) => { - if(err){ return callback(err); } + if (err) { + return callback(err); + } try { callback(null, JSON.parse(file)); - } catch(er){ + } catch (er) { return callback({ code: strings.errors.s3.FILE_NOT_VALID_CODE, msg: format(strings.errors.s3.FILE_NOT_VALID, filePath) @@ -91,54 +99,67 @@ module.exports = function(conf){ }); }; - const getUrl = (componentName, version, fileName) => `${conf.s3.path}${componentName}/${version}/${fileName}`; + const getUrl = (componentName, version, fileName) => + `${conf.s3.path}${componentName}/${version}/${fileName}`; const listSubDirectories = (dir, callback) => { + const normalisedPath = dir.lastIndexOf('/') === dir.length - 1 && + dir.length > 0 + ? dir + : dir + '/'; - const normalisedPath = dir.lastIndexOf('/') === (dir.length - 1) && dir.length > 0 ? dir : dir + '/'; - - getClient().listObjects({ - Bucket: bucket, - Prefix: normalisedPath, - Delimiter: '/' - }, (err, data) => { - if(err){ return callback(err); } + getClient().listObjects( + { + Bucket: bucket, + Prefix: normalisedPath, + Delimiter: '/' + }, + (err, data) => { + if (err) { + return callback(err); + } - if(data.CommonPrefixes.length === 0){ - return callback({ - code: strings.errors.s3.DIR_NOT_FOUND_CODE, - msg: format(strings.errors.s3.DIR_NOT_FOUND, dir) - }); - } + if (data.CommonPrefixes.length === 0) { + return callback({ + code: strings.errors.s3.DIR_NOT_FOUND_CODE, + msg: format(strings.errors.s3.DIR_NOT_FOUND, dir) + }); + } - const result = _.map(data.CommonPrefixes, (commonPrefix) => - commonPrefix.Prefix.substr(normalisedPath.length, commonPrefix.Prefix.length - normalisedPath.length - 1)); + const result = _.map(data.CommonPrefixes, commonPrefix => + commonPrefix.Prefix.substr( + normalisedPath.length, + commonPrefix.Prefix.length - normalisedPath.length - 1 + ) + ); - callback(null, result); - }); + callback(null, result); + } + ); }; const putDir = (dirInput, dirOutput, callback) => { - nodeDir.paths(dirInput, (err, paths) => { - - async.each(paths.files, (file, cb) => { - const relativeFile = file.substr(dirInput.length), - url = (dirOutput + relativeFile).replace(/\\/g, '/'); - - putFile(file, url, relativeFile === '/server.js', cb); - }, (errors) => { - if(errors){ - return callback(_.compact(errors)); + async.each( + paths.files, + (file, cb) => { + const relativeFile = file.substr(dirInput.length), + url = (dirOutput + relativeFile).replace(/\\/g, '/'); + + putFile(file, url, relativeFile === '/server.js', cb); + }, + errors => { + if (errors) { + return callback(_.compact(errors)); + } + + callback(null, 'ok'); } - - callback(null, 'ok'); - }); + ); }); }; const putFileContent = (fileContent, fileName, isPrivate, callback) => { - const fileInfo = getFileInfo(fileName), obj = { Bucket: bucket, @@ -149,11 +170,11 @@ module.exports = function(conf){ Expires: getNextYear() }; - if(fileInfo.mimeType){ + if (fileInfo.mimeType) { obj.ContentType = fileInfo.mimeType; } - if(fileInfo.gzip){ + if (fileInfo.gzip) { obj.ContentEncoding = 'gzip'; } @@ -162,7 +183,9 @@ module.exports = function(conf){ const putFile = (filePath, fileName, isPrivate, callback) => { fs.readFile(filePath, (err, fileContent) => { - if(err){ return callback(err); } + if (err) { + return callback(err); + } putFileContent(fileContent, fileName, isPrivate, callback); }); }; diff --git a/src/registry/domain/sanitiser.js b/src/registry/domain/sanitiser.js index ec22f0829..be8e951a0 100644 --- a/src/registry/domain/sanitiser.js +++ b/src/registry/domain/sanitiser.js @@ -3,29 +3,29 @@ const _ = require('lodash'); const sanitise = { - booleanParameter: function(variable){ - if(_.isString(variable)){ - if(variable === 'true'){ + booleanParameter: function(variable) { + if (_.isString(variable)) { + if (variable === 'true') { return true; - } else if(variable === 'false'){ + } else if (variable === 'false') { return false; } } return variable; }, - numberParameter: function(variable){ - return variable*1; + numberParameter: function(variable) { + return variable * 1; }, - stringParameter: function(variable){ + stringParameter: function(variable) { return _.isNull(variable) ? '' : variable; }, - parameter: function(variable, type){ - if(type === 'boolean'){ + parameter: function(variable, type) { + if (type === 'boolean') { return sanitise.booleanParameter(variable); - } else if(type === 'number'){ + } else if (type === 'number') { return sanitise.numberParameter(variable); - } else if(type === 'string'){ + } else if (type === 'string') { return sanitise.stringParameter(variable); } @@ -36,21 +36,23 @@ const sanitise = { const toRemove = ['__ocAcceptLanguage']; module.exports = { - sanitiseComponentParameters: function(requestParameters, expectedParameters){ - + sanitiseComponentParameters: function(requestParameters, expectedParameters) { const result = {}; - _.forEach(requestParameters, (requestParameter, requestParameterName) => { - if(_.has(expectedParameters, requestParameterName)){ - - const expectedType = expectedParameters[requestParameterName].type, - sanitised = sanitise.parameter(requestParameter, expectedType); - - result[requestParameterName] = sanitised; - } else if(!_.includes(toRemove, requestParameterName)){ - result[requestParameterName] = requestParameter; - } - }, this); + _.forEach( + requestParameters, + (requestParameter, requestParameterName) => { + if (_.has(expectedParameters, requestParameterName)) { + const expectedType = expectedParameters[requestParameterName].type, + sanitised = sanitise.parameter(requestParameter, expectedType); + + result[requestParameterName] = sanitised; + } else if (!_.includes(toRemove, requestParameterName)) { + result[requestParameterName] = requestParameter; + } + }, + this + ); return result; } diff --git a/src/registry/domain/url-builder.js b/src/registry/domain/url-builder.js index c49bf7e7a..01db5ab22 100644 --- a/src/registry/domain/url-builder.js +++ b/src/registry/domain/url-builder.js @@ -6,7 +6,7 @@ const _ = require('lodash'); function componentForType(component, baseUrl, type) { if (_.isString(component)) { - component = {name: component}; + component = { name: component }; } let href = url.resolve(baseUrl, component.name) + '/'; @@ -21,9 +21,9 @@ function componentForType(component, baseUrl, type) { } const build = { - component: function (component, baseUrl) { + component: function(component, baseUrl) { if (_.isString(component)) { - component = {name: component}; + component = { name: component }; } let componentUrl = url.resolve(baseUrl, component.name); @@ -36,10 +36,10 @@ const build = { return componentUrl; }, - componentInfo: function (component, baseUrl) { + componentInfo: function(component, baseUrl) { return componentForType(component, baseUrl, 'info'); }, - componentPreview: function (component, baseUrl) { + componentPreview: function(component, baseUrl) { let href = componentForType(component, baseUrl, 'preview'); if (!!component.parameters && !_.isEmpty(component.parameters)) { href += '/?' + querystring.stringify(component.parameters); @@ -49,7 +49,7 @@ const build = { return href; }, - queryString: function (parameters) { + queryString: function(parameters) { let qs = ''; if (_.keys(parameters).length > 0) { diff --git a/src/registry/domain/validators/component-parameters.js b/src/registry/domain/validators/component-parameters.js index d1e01143f..3a7691e5d 100644 --- a/src/registry/domain/validators/component-parameters.js +++ b/src/registry/domain/validators/component-parameters.js @@ -5,79 +5,107 @@ const _ = require('lodash'); const strings = require('../../../resources'); -const validateParameter = function(parameter, expectedType){ +const validateParameter = function(parameter, expectedType) { const expected = expectedType.toLowerCase(); - if(expected === 'boolean'){ + if (expected === 'boolean') { return _.isBoolean(parameter); - } else if(expected === 'number'){ + } else if (expected === 'number') { return _.isNumber(parameter); - } else if(expected === 'string'){ + } else if (expected === 'string') { return _.isString(parameter); } return false; }; -module.exports = function(requestParameters, expectedParameters){ - +module.exports = function(requestParameters, expectedParameters) { const result = { isValid: true, errors: {} }, mandatoryParameters = []; - _.forEach(expectedParameters, (expectedParameter, expectedParameterName) => { - if(expectedParameter.mandatory){ - mandatoryParameters.push(expectedParameterName); - } - }, this); - - _.forEach(mandatoryParameters, (mandatoryParameterName) => { - if(!_.has(requestParameters, mandatoryParameterName)){ - if(!result.errors.mandatory){ - result.errors.mandatory = {}; - result.isValid = false; + _.forEach( + expectedParameters, + (expectedParameter, expectedParameterName) => { + if (expectedParameter.mandatory) { + mandatoryParameters.push(expectedParameterName); } - - result.errors.mandatory[mandatoryParameterName] = strings.errors.registry.MANDATORY_PARAMETER_MISSING_CODE; - } - }, this); - - _.forEach(requestParameters, (requestParameter, requestParameterName) => { - if(_.has(expectedParameters, requestParameterName)){ - - const expectedType = expectedParameters[requestParameterName].type; - - if(!validateParameter(requestParameter, expectedType)){ - if(!result.errors.types){ - result.errors.types = {}; + }, + this + ); + + _.forEach( + mandatoryParameters, + mandatoryParameterName => { + if (!_.has(requestParameters, mandatoryParameterName)) { + if (!result.errors.mandatory) { + result.errors.mandatory = {}; result.isValid = false; } - result.errors.types[requestParameterName] = strings.errors.registry.PARAMETER_WRONG_FORMAT_CODE; + result.errors.mandatory[mandatoryParameterName] = + strings.errors.registry.MANDATORY_PARAMETER_MISSING_CODE; } - } - }, this); + }, + this + ); + + _.forEach( + requestParameters, + (requestParameter, requestParameterName) => { + if (_.has(expectedParameters, requestParameterName)) { + const expectedType = expectedParameters[requestParameterName].type; + + if (!validateParameter(requestParameter, expectedType)) { + if (!result.errors.types) { + result.errors.types = {}; + result.isValid = false; + } + + result.errors.types[requestParameterName] = + strings.errors.registry.PARAMETER_WRONG_FORMAT_CODE; + } + } + }, + this + ); - result.errors.message = (function(){ + result.errors.message = (function() { let errorString = ''; - if(_.keys(result.errors.mandatory).length > 0){ - - const missingParams = _.map(result.errors.mandatory, (mandatoryParameter, mandatoryParameterName) => mandatoryParameterName + ', ').join('').slice(0, -2); - - errorString += format(strings.errors.registry.MANDATORY_PARAMETER_MISSING, missingParams); + if (_.keys(result.errors.mandatory).length > 0) { + const missingParams = _.map( + result.errors.mandatory, + (mandatoryParameter, mandatoryParameterName) => + mandatoryParameterName + ', ' + ) + .join('') + .slice(0, -2); + + errorString += format( + strings.errors.registry.MANDATORY_PARAMETER_MISSING, + missingParams + ); } - if(_.keys(result.errors.types).length > 0){ - if(errorString.length > 0){ + if (_.keys(result.errors.types).length > 0) { + if (errorString.length > 0) { errorString += '; '; } - const badParams = _.map(result.errors.types, (parameter, parameterName) => parameterName + ', ').join('').slice(0, -2); - - errorString += format(strings.errors.registry.PARAMETER_WRONG_FORMAT, badParams); + const badParams = _.map( + result.errors.types, + (parameter, parameterName) => parameterName + ', ' + ) + .join('') + .slice(0, -2); + + errorString += format( + strings.errors.registry.PARAMETER_WRONG_FORMAT, + badParams + ); } return errorString; - }()); + })(); return result; }; diff --git a/src/registry/domain/validators/index.js b/src/registry/domain/validators/index.js index 1982e9631..84be7c8a2 100644 --- a/src/registry/domain/validators/index.js +++ b/src/registry/domain/validators/index.js @@ -12,8 +12,10 @@ const uploadedPackageValidator = require('./uploaded-package'); const nodeVersionValidator = require('./node-version'); module.exports = { - validateComponentName: function(componentName){ - return !/[^a-zA-Z0-9\-\_]/.test(componentName) && componentName !== '_package'; + validateComponentName: function(componentName) { + return ( + !/[^a-zA-Z0-9\-\_]/.test(componentName) && componentName !== '_package' + ); }, validateComponentParameters: componentParametersValidator, validateNodeVersion: nodeVersionValidator, @@ -22,10 +24,10 @@ module.exports = { validatePackageJson: packageJsonValidator, validatePluginsRequirements: pluginsRequirementsValidator, validateRegistryConfiguration: registryConfigurationValidator, - validateTemplateType: function(templateType){ + validateTemplateType: function(templateType) { return _.includes(['handlebars', 'jade'], templateType); }, - validateVersion: function(version){ + validateVersion: function(version) { return !!semver.valid(version); } }; diff --git a/src/registry/domain/validators/node-version.js b/src/registry/domain/validators/node-version.js index b9a6d60ee..7d13dd91f 100644 --- a/src/registry/domain/validators/node-version.js +++ b/src/registry/domain/validators/node-version.js @@ -5,28 +5,28 @@ const semver = require('semver'); const packageInfo = require('../../../../package.json'); module.exports = function(userAgent, nodeVersion) { - const result = { isValid: false}; + const result = { isValid: false }; const error = { suggestedVersion: packageInfo.engines.node || '*', registryNodeVersion: nodeVersion, cliNodeVersion: '' }; - if(!userAgent) { + if (!userAgent) { result.error = error; result.error.code = 'empty'; return result; } const matchVersion = /.*\/v([\w|.]+)-.*/.exec(userAgent); - if(!matchVersion) { + if (!matchVersion) { result.error = error; result.error.code = result.error.nodeVersion = 'not_valid'; return result; } const cliNodeVersion = matchVersion[1]; - if(!semver.satisfies(cliNodeVersion, packageInfo.engines.node)) { + if (!semver.satisfies(cliNodeVersion, packageInfo.engines.node)) { result.error = error; result.error.code = 'not_matching'; result.error.cliNodeVersion = cliNodeVersion; diff --git a/src/registry/domain/validators/oc-cli-version.js b/src/registry/domain/validators/oc-cli-version.js index 922f12a7d..22f60c61b 100644 --- a/src/registry/domain/validators/oc-cli-version.js +++ b/src/registry/domain/validators/oc-cli-version.js @@ -6,28 +6,32 @@ const semver = require('semver'); const packageInfo = require('../../../../package.json'); module.exports = function(userAgent) { - const result = { isValid: false}; + const result = { isValid: false }; const error = { - suggestedVersion: format('{0}.{1}.X', semver.major(packageInfo.version), semver.minor(packageInfo.version)), + suggestedVersion: format( + '{0}.{1}.X', + semver.major(packageInfo.version), + semver.minor(packageInfo.version) + ), registryVersion: packageInfo.version, cliVersion: '' }; - if(!userAgent) { + if (!userAgent) { result.error = error; result.error.code = 'empty'; return result; } const matchVersion = /oc-cli-([\w|.]+).*/.exec(userAgent); - if(!matchVersion) { + if (!matchVersion) { result.error = error; result.error.code = result.error.cliVersion = 'not_valid'; return result; } const cliVersion = matchVersion[1]; - if(semver.lt(cliVersion, packageInfo.version)) { + if (semver.lt(cliVersion, packageInfo.version)) { result.error = error; result.error.code = 'old_version'; result.error.cliVersion = cliVersion; diff --git a/src/registry/domain/validators/package-json-validator.js b/src/registry/domain/validators/package-json-validator.js index c1bfe10ba..5687e15f3 100644 --- a/src/registry/domain/validators/package-json-validator.js +++ b/src/registry/domain/validators/package-json-validator.js @@ -4,9 +4,8 @@ const _ = require('lodash'); const strings = require('../../../resources'); -module.exports = function(pkgDetails){ - - if(pkgDetails.packageJson.name !== pkgDetails.componentName){ +module.exports = function(pkgDetails) { + if (pkgDetails.packageJson.name !== pkgDetails.componentName) { return { isValid: false, error: strings.errors.registry.COMPONENT_PUBLISHNAME_CONFLICT @@ -15,10 +14,10 @@ module.exports = function(pkgDetails){ let result = pkgDetails.customValidator(pkgDetails.packageJson); - if(_.isBoolean(result)){ + if (_.isBoolean(result)) { result = { isValid: result }; - if(!result.isValid){ + if (!result.isValid) { result.error = 'unknown'; } } diff --git a/src/registry/domain/validators/plugins-requirements.js b/src/registry/domain/validators/plugins-requirements.js index 5a4bfcc35..46e737d92 100644 --- a/src/registry/domain/validators/plugins-requirements.js +++ b/src/registry/domain/validators/plugins-requirements.js @@ -2,17 +2,21 @@ const _ = require('lodash'); -module.exports = function(componentRequirements, registryPlugins){ +module.exports = function(componentRequirements, registryPlugins) { const result = { isValid: true }, missing = []; - _.forEach(componentRequirements || [], (requiredPlugin) => { - if(!registryPlugins || _.isEmpty(registryPlugins) || !_.includes(_.keys(registryPlugins), requiredPlugin)){ + _.forEach(componentRequirements || [], requiredPlugin => { + if ( + !registryPlugins || + _.isEmpty(registryPlugins) || + !_.includes(_.keys(registryPlugins), requiredPlugin) + ) { missing.push(requiredPlugin); } }); - if(!_.isEmpty(missing)){ + if (!_.isEmpty(missing)) { return { isValid: false, missing: missing diff --git a/src/registry/domain/validators/registry-configuration.js b/src/registry/domain/validators/registry-configuration.js index bc2bc27a5..7e93c92e3 100644 --- a/src/registry/domain/validators/registry-configuration.js +++ b/src/registry/domain/validators/registry-configuration.js @@ -6,85 +6,114 @@ const _ = require('lodash'); const auth = require('../authentication'); const strings = require('../../../resources'); -module.exports = function(conf){ - +module.exports = function(conf) { const response = { isValid: true }; - const returnError = function(message){ + const returnError = function(message) { response.isValid = false; response.message = message || 'registry configuration is not valid'; return response; }; - if(!conf || !_.isObject(conf) || _.keys(conf).length === 0){ + if (!conf || !_.isObject(conf) || _.keys(conf).length === 0) { return returnError(strings.errors.registry.CONFIGURATION_EMPTY); } const prefix = conf.prefix; - if(prefix){ - if(prefix.substr(0, 1) !== '/'){ - return returnError(strings.errors.registry.CONFIGURATION_PREFIX_DOES_NOT_START_WITH_SLASH); + if (prefix) { + if (prefix.substr(0, 1) !== '/') { + return returnError( + strings.errors.registry.CONFIGURATION_PREFIX_DOES_NOT_START_WITH_SLASH + ); } - if(prefix.substr(prefix.length - 1) !== '/'){ - return returnError(strings.errors.registry.CONFIGURATION_PREFIX_DOES_NOT_END_WITH_SLASH); + if (prefix.substr(prefix.length - 1) !== '/') { + return returnError( + strings.errors.registry.CONFIGURATION_PREFIX_DOES_NOT_END_WITH_SLASH + ); } } const publishAuth = conf.publishAuth; - if(publishAuth){ + if (publishAuth) { const res = auth.validate(publishAuth); - if(!res.isValid){ + if (!res.isValid) { return returnError(res.message); } } const dependencies = conf.dependencies; - if(!!dependencies && !_.isArray(dependencies)){ - return returnError(strings.errors.registry.CONFIGURATION_DEPENDENCIES_MUST_BE_ARRAY); + if (!!dependencies && !_.isArray(dependencies)) { + return returnError( + strings.errors.registry.CONFIGURATION_DEPENDENCIES_MUST_BE_ARRAY + ); } const routes = conf.routes; - if(!!routes && !_.isArray(routes)){ - return returnError(strings.errors.registry.CONFIGURATION_ROUTES_MUST_BE_ARRAY); + if (!!routes && !_.isArray(routes)) { + return returnError( + strings.errors.registry.CONFIGURATION_ROUTES_MUST_BE_ARRAY + ); } else { - _.forEach(routes, (route) => { - if(!route.route || !route.handler || !route.method){ - return returnError(strings.errors.registry.CONFIGURATION_ROUTES_NOT_VALID); + _.forEach(routes, route => { + if (!route.route || !route.handler || !route.method) { + return returnError( + strings.errors.registry.CONFIGURATION_ROUTES_NOT_VALID + ); } - if(!_.isFunction(route.handler)){ - return returnError(strings.errors.registry.CONFIGURATION_ROUTES_HANDLER_MUST_BE_FUNCTION); + if (!_.isFunction(route.handler)) { + return returnError( + strings.errors.registry.CONFIGURATION_ROUTES_HANDLER_MUST_BE_FUNCTION + ); } - if(route.route.indexOf(prefix) === 0){ - return returnError(format(strings.errors.registry.CONFIGURATION_ROUTES_ROUTE_CONTAINS_PREFIX, prefix)); + if (route.route.indexOf(prefix) === 0) { + return returnError( + format( + strings.errors.registry.CONFIGURATION_ROUTES_ROUTE_CONTAINS_PREFIX, + prefix + ) + ); } }); } - if(!conf.local){ + if (!conf.local) { // S3 settings should either specify both key/secret or // skip both when leveraging IAM Role based S3 access from EC2 - if (!conf.s3 || !conf.s3.bucket || !conf.s3.region || - (conf.s3.key && !conf.s3.secret) || (!conf.s3.key && conf.s3.secret)) { + if ( + !conf.s3 || + !conf.s3.bucket || + !conf.s3.region || + (conf.s3.key && !conf.s3.secret) || + (!conf.s3.key && conf.s3.secret) + ) { return returnError(strings.errors.registry.CONFIGURATION_S3_NOT_VALID); } } if (conf.customHeadersToSkipOnWeakVersion) { if (!_.isArray(conf.customHeadersToSkipOnWeakVersion)) { - return returnError(strings.errors.registry.CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY); + return returnError( + strings.errors.registry + .CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY + ); } - const hasNonStringElements = conf.customHeadersToSkipOnWeakVersion.find((element) => typeof(element) !== 'string'); + const hasNonStringElements = conf.customHeadersToSkipOnWeakVersion.find( + element => typeof element !== 'string' + ); if (hasNonStringElements) { - return returnError(strings.errors.registry.CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY); + return returnError( + strings.errors.registry + .CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY + ); } } diff --git a/src/registry/domain/validators/uploaded-package.js b/src/registry/domain/validators/uploaded-package.js index cdb7848b2..ab70acf55 100644 --- a/src/registry/domain/validators/uploaded-package.js +++ b/src/registry/domain/validators/uploaded-package.js @@ -2,26 +2,30 @@ const _ = require('lodash'); -module.exports = function(input){ +module.exports = function(input) { const response = { isValid: true }; - const returnError = function(message){ + const returnError = function(message) { response.isValid = false; response.message = message || 'uploaded package is not valid'; return response; }; - if(!input || !_.isObject(input) || _.keys(input).length === 0){ + if (!input || !_.isObject(input) || _.keys(input).length === 0) { return returnError('empty'); } - if(_.keys(input).length !== 1){ + if (_.keys(input).length !== 1) { return returnError('not_valid'); } const file = input[0]; - if(file.mimetype !== 'application/octet-stream' || file.truncated || file.filename.indexOf('.tar.gz') < 0){ + if ( + file.mimetype !== 'application/octet-stream' || + file.truncated || + file.filename.indexOf('.tar.gz') < 0 + ) { return returnError('not_valid'); } diff --git a/src/registry/domain/version-handler.js b/src/registry/domain/version-handler.js index e2f48d99b..0211799ac 100644 --- a/src/registry/domain/version-handler.js +++ b/src/registry/domain/version-handler.js @@ -5,18 +5,18 @@ const semverExtra = require('semver-extra'); const _ = require('lodash'); module.exports = { - getAvailableVersion: function(requestedVersion, availableVersions){ - - if(_.isUndefined(requestedVersion)){ + getAvailableVersion: function(requestedVersion, availableVersions) { + if (_.isUndefined(requestedVersion)) { requestedVersion = ''; } - const version = semver.maxSatisfying(availableVersions, requestedVersion) || undefined; + const version = + semver.maxSatisfying(availableVersions, requestedVersion) || undefined; const max = semverExtra.max(availableVersions); const isLatest = requestedVersion === ''; return version || (isLatest && max) || undefined; }, - validateNewVersion: function(requestedVersion, availableVersions){ + validateNewVersion: function(requestedVersion, availableVersions) { return !_.includes(availableVersions, requestedVersion); } }; diff --git a/src/registry/index.js b/src/registry/index.js index a3e002b65..9e999105c 100644 --- a/src/registry/index.js +++ b/src/registry/index.js @@ -15,93 +15,100 @@ const router = require('./router'); const sanitiseOptions = require('./domain/options-sanitiser'); const validator = require('./domain/validators'); -module.exports = function(options){ - +module.exports = function(options) { let repository, server; const self = this, validationResult = validator.validateRegistryConfiguration(options), plugins = []; - if(!validationResult.isValid){ + if (!validationResult.isValid) { throw validationResult.message; } options = sanitiseOptions(options); this.on = eventsHandler.on; - this.close = function(callback){ - if(server){ + this.close = function(callback) { + if (server) { server.close(callback); } else { callback('not opened'); } }; - this.init = function(){ + this.init = function() { self.app = middleware.bind(express(), options); repository = new Repository(options); }; - this.register = function(plugin, callback){ + this.register = function(plugin, callback) { plugins.push(_.extend(plugin, { callback })); }; - this.start = function(callback){ - + this.start = function(callback) { const ok = msg => console.log(colors.green(msg)); - if(!_.isFunction(callback)){ + if (!_.isFunction(callback)) { callback = _.noop; } router.create(this.app, options, repository); - async.waterfall([ - - cb => pluginsInitialiser.init(plugins, cb), - - (plugins, cb) => { - options.plugins = plugins; - repository.init(cb); - }, - - (componentsInfo, cb) => { - appStart(repository, options, (err) => cb(err ? err.msg : null, componentsInfo)); - } - ], - (err, componentsInfo) => { - if(err){ return callback(err); } - - server = http.createServer(self.app); + async.waterfall( + [ + cb => pluginsInitialiser.init(plugins, cb), - server.listen(options.port, (err) => { + (plugins, cb) => { + options.plugins = plugins; + repository.init(cb); + }, - if(err){ return callback(err); } + (componentsInfo, cb) => { + appStart(repository, options, err => + cb(err ? err.msg : null, componentsInfo) + ); + } + ], + (err, componentsInfo) => { + if (err) { + return callback(err); + } - eventsHandler.fire('start', {}); + server = http.createServer(self.app); - if(options.verbosity){ + server.listen(options.port, err => { + if (err) { + return callback(err); + } - ok(`Registry started at port ${self.app.get('port')}`); + eventsHandler.fire('start', {}); - if(_.isObject(componentsInfo)){ + if (options.verbosity) { + ok(`Registry started at port ${self.app.get('port')}`); - const componentsNumber = _.keys(componentsInfo.components).length; - const componentsReleases = _.reduce(componentsInfo.components, (memo, component) => (parseInt(memo, 10) + component.length)); + if (_.isObject(componentsInfo)) { + const componentsNumber = _.keys(componentsInfo.components).length; + const componentsReleases = _.reduce( + componentsInfo.components, + (memo, component) => parseInt(memo, 10) + component.length + ); - ok(`Registry serving ${componentsNumber} components for a total of ${componentsReleases} releases.`); + ok( + `Registry serving ${componentsNumber} components for a total of ${componentsReleases} releases.` + ); + } } - } - callback(null, { app: self.app, server }); - }); + callback(null, { app: self.app, server }); + }); - server.on('error', (message) => { - eventsHandler.fire('error', { code: 'EXPRESS_ERROR', message }); - callback(message); - }); - }); + server.on('error', message => { + eventsHandler.fire('error', { code: 'EXPRESS_ERROR', message }); + callback(message); + }); + } + ); }; this.init(); diff --git a/src/registry/middleware/base-url-handler.js b/src/registry/middleware/base-url-handler.js index 46b0adb8a..5d7ddb8d4 100644 --- a/src/registry/middleware/base-url-handler.js +++ b/src/registry/middleware/base-url-handler.js @@ -2,11 +2,12 @@ const _ = require('lodash'); -module.exports = function(req, res, next){ +module.exports = function(req, res, next) { + res.conf.baseUrlFunc = + res.conf.baseUrlFunc || + (_.isFunction(res.conf.baseUrl) ? res.conf.baseUrl : undefined); - res.conf.baseUrlFunc = res.conf.baseUrlFunc || (_.isFunction(res.conf.baseUrl) ? res.conf.baseUrl : undefined); - - if(!_.isUndefined(res.conf.baseUrlFunc)){ + if (!_.isUndefined(res.conf.baseUrlFunc)) { res.conf.baseUrl = res.conf.baseUrlFunc({ host: req.headers.host, secure: req.secure diff --git a/src/registry/middleware/cors.js b/src/registry/middleware/cors.js index 783717887..f0d636483 100644 --- a/src/registry/middleware/cors.js +++ b/src/registry/middleware/cors.js @@ -1,10 +1,13 @@ 'use strict'; -module.exports = function(req, res, next){ +module.exports = function(req, res, next) { res.removeHeader('X-Powered-By'); res.header('Access-Control-Allow-Credentials', 'true'); res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + res.header( + 'Access-Control-Allow-Headers', + 'Origin, X-Requested-With, Content-Type, Accept' + ); res.header('Access-Control-Allow-Methods', 'GET, OPTIONS, PUT, POST'); next(); }; diff --git a/src/registry/middleware/discovery-handler.js b/src/registry/middleware/discovery-handler.js index d87a8fb82..23a2bc4cc 100644 --- a/src/registry/middleware/discovery-handler.js +++ b/src/registry/middleware/discovery-handler.js @@ -2,11 +2,12 @@ const _ = require('lodash'); -module.exports = function(req, res, next){ +module.exports = function(req, res, next) { + res.conf.discoveryFunc = + res.conf.discoveryFunc || + (_.isFunction(res.conf.discovery) ? res.conf.discovery : undefined); - res.conf.discoveryFunc = res.conf.discoveryFunc || (_.isFunction(res.conf.discovery) ? res.conf.discovery : undefined); - - if(!_.isUndefined(res.conf.discoveryFunc)){ + if (!_.isUndefined(res.conf.discoveryFunc)) { res.conf.discovery = res.conf.discoveryFunc({ host: req.headers.host, secure: req.secure diff --git a/src/registry/middleware/file-uploads.js b/src/registry/middleware/file-uploads.js index dbddd71a2..3dd96ae33 100644 --- a/src/registry/middleware/file-uploads.js +++ b/src/registry/middleware/file-uploads.js @@ -2,13 +2,13 @@ const multer = require('multer'); -module.exports = function(req, res, next){ - - if(res.conf.local){ +module.exports = function(req, res, next) { + if (res.conf.local) { return next(); } - const normaliseFileName = (x) => x.replace('.tar.gz', '').replace(/\W+/g, '-').toLowerCase(); + const normaliseFileName = x => + x.replace('.tar.gz', '').replace(/\W+/g, '-').toLowerCase(); const upload = multer({ limits: { @@ -16,7 +16,8 @@ module.exports = function(req, res, next){ }, storage: multer.diskStorage({ destination: res.conf.tempDir, - filename: (req, file, cb) => cb(null, `${normaliseFileName(file.originalname)}-${Date.now()}.tar.gz`) + filename: (req, file, cb) => + cb(null, `${normaliseFileName(file.originalname)}-${Date.now()}.tar.gz`) }) }); diff --git a/src/registry/middleware/index.js b/src/registry/middleware/index.js index c0b9a3641..7c41aee40 100644 --- a/src/registry/middleware/index.js +++ b/src/registry/middleware/index.js @@ -11,8 +11,7 @@ const discoveryHandler = require('./discovery-handler'); const fileUploads = require('./file-uploads'); const requestHandler = require('./request-handler'); -module.exports.bind = function(app, options){ - +module.exports.bind = function(app, options) { app.set('port', options.port); app.set('json spaces', 0); @@ -33,11 +32,11 @@ module.exports.bind = function(app, options){ app.set('view engine', 'pug'); app.set('view cache', true); - if(options.verbosity){ + if (options.verbosity) { app.use(morgan('dev')); } - if(options.local){ + if (options.local) { app.use(errorhandler({ dumpExceptions: true, showStack: true })); } diff --git a/src/registry/middleware/request-handler.js b/src/registry/middleware/request-handler.js index cc5c20073..b0cc9f89d 100644 --- a/src/registry/middleware/request-handler.js +++ b/src/registry/middleware/request-handler.js @@ -4,10 +4,8 @@ const responseTime = require('response-time'); const eventsHandler = require('../domain/events-handler'); -module.exports = function(){ - +module.exports = function() { return responseTime((req, res, time) => { - const data = { body: req.body, duration: parseInt(time * 1000, 10), @@ -20,11 +18,11 @@ module.exports = function(){ statusCode: res.statusCode }; - if(res.errorDetails){ + if (res.errorDetails) { data.errorDetails = res.errorDetails; } - if(res.errorCode){ + if (res.errorCode) { data.errorCode = res.errorCode; } diff --git a/src/registry/router.js b/src/registry/router.js index 0561e1037..09d2f12e5 100644 --- a/src/registry/router.js +++ b/src/registry/router.js @@ -12,7 +12,7 @@ const PublishRoute = require('./routes/publish'); const settings = require('../resources/settings'); const StaticRedirectorRoute = require('./routes/static-redirector'); -module.exports.create = function(app, conf, repository){ +module.exports.create = function(app, conf, repository) { const routes = { component: new ComponentRoute(conf, repository), components: new ComponentsRoute(conf, repository), @@ -23,34 +23,75 @@ module.exports.create = function(app, conf, repository){ staticRedirector: new StaticRedirectorRoute(repository) }; - if(conf.prefix !== '/'){ - app.get('/', (req, res) => { res.redirect(conf.prefix); }); + if (conf.prefix !== '/') { + app.get('/', (req, res) => { + res.redirect(conf.prefix); + }); app.get(conf.prefix.substr(0, conf.prefix.length - 1), routes.index); } app.get(conf.prefix + 'oc-client/client.js', routes.staticRedirector); app.get(conf.prefix + 'oc-client/oc-client.min.map', routes.staticRedirector); - if(conf.local){ - app.get(format('{0}:componentName/:componentVersion/{1}*', conf.prefix, settings.registry.localStaticRedirectorPath), routes.staticRedirector); + if (conf.local) { + app.get( + format( + '{0}:componentName/:componentVersion/{1}*', + conf.prefix, + settings.registry.localStaticRedirectorPath + ), + routes.staticRedirector + ); } else { - app.put(conf.prefix + ':componentName/:componentVersion', conf.beforePublish, routes.publish); + app.put( + conf.prefix + ':componentName/:componentVersion', + conf.beforePublish, + routes.publish + ); } app.get(conf.prefix, routes.index); app.post(conf.prefix, routes.components); - app.get(format('{0}:componentName/:componentVersion{1}', conf.prefix, settings.registry.componentInfoPath), routes.componentInfo); - app.get(format('{0}:componentName{1}', conf.prefix, settings.registry.componentInfoPath), routes.componentInfo); + app.get( + format( + '{0}:componentName/:componentVersion{1}', + conf.prefix, + settings.registry.componentInfoPath + ), + routes.componentInfo + ); + app.get( + format( + '{0}:componentName{1}', + conf.prefix, + settings.registry.componentInfoPath + ), + routes.componentInfo + ); - app.get(format('{0}:componentName/:componentVersion{1}', conf.prefix, settings.registry.componentPreviewPath), routes.componentPreview); - app.get(format('{0}:componentName{1}', conf.prefix, settings.registry.componentPreviewPath), routes.componentPreview); + app.get( + format( + '{0}:componentName/:componentVersion{1}', + conf.prefix, + settings.registry.componentPreviewPath + ), + routes.componentPreview + ); + app.get( + format( + '{0}:componentName{1}', + conf.prefix, + settings.registry.componentPreviewPath + ), + routes.componentPreview + ); app.get(conf.prefix + ':componentName/:componentVersion', routes.component); app.get(conf.prefix + ':componentName', routes.component); - if(conf.routes){ - _.forEach(conf.routes, (route) => { + if (conf.routes) { + _.forEach(conf.routes, route => { app[route.method.toLowerCase()](route.route, route.handler); }); } diff --git a/src/registry/routes/component-info.js b/src/registry/routes/component-info.js index 907740a84..a963c28d9 100644 --- a/src/registry/routes/component-info.js +++ b/src/registry/routes/component-info.js @@ -9,13 +9,19 @@ const urlBuilder = require('../domain/url-builder'); function getParams(component) { let params = {}; - if(component.oc.parameters){ - const mandatoryParams = _.filter(_.keys(component.oc.parameters), (paramName) => { - const param = component.oc.parameters[paramName]; - return !!param.mandatory && !!param.example; - }); + if (component.oc.parameters) { + const mandatoryParams = _.filter( + _.keys(component.oc.parameters), + paramName => { + const param = component.oc.parameters[paramName]; + return !!param.mandatory && !!param.example; + } + ); - params = _.mapValues(_.pick(component.oc.parameters, mandatoryParams), x => x.example); + params = _.mapValues( + _.pick(component.oc.parameters, mandatoryParams), + x => x.example + ); } return params; @@ -41,15 +47,15 @@ function addGetRepositoryUrlFunction(component) { } function componentInfo(err, req, res, component) { - if(err) { + if (err) { res.errorDetails = err.registryError || err; return res.status(404).json(err); } - const isHtmlRequest = !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0; - - if(isHtmlRequest && !!res.conf.discovery){ + const isHtmlRequest = + !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0; + if (isHtmlRequest && !!res.conf.discovery) { const params = getParams(component); const parsedAuthor = getParsedAuthor(component); let href = res.conf.baseUrl; @@ -57,7 +63,7 @@ function componentInfo(err, req, res, component) { addGetRepositoryUrlFunction(component); isUrlDiscoverable(href, (err, result) => { - if(!result.isDiscoverable){ + if (!result.isDiscoverable) { href = '//' + req.headers.host + res.conf.prefix; } @@ -69,24 +75,35 @@ function componentInfo(err, req, res, component) { sandBoxDefaultQs: urlBuilder.queryString(params) }); }); - } else { - res.status(200).json(_.extend(component, { - requestVersion: req.params.componentVersion || '' - })); + res.status(200).json( + _.extend(component, { + requestVersion: req.params.componentVersion || '' + }) + ); } } -module.exports = function(conf, repository){ - return function(req, res){ - repository.getComponent(req.params.componentName, req.params.componentVersion, (registryError, component) => { - if(registryError && conf.fallbackRegistryUrl) { - return getComponentFallback.getComponentInfo(conf, req, res, registryError, (fallbackError, fallbackComponent) => { - componentInfo(fallbackError, req, res, fallbackComponent); - }); +module.exports = function(conf, repository) { + return function(req, res) { + repository.getComponent( + req.params.componentName, + req.params.componentVersion, + (registryError, component) => { + if (registryError && conf.fallbackRegistryUrl) { + return getComponentFallback.getComponentInfo( + conf, + req, + res, + registryError, + (fallbackError, fallbackComponent) => { + componentInfo(fallbackError, req, res, fallbackComponent); + } + ); + } + + componentInfo(registryError, req, res, component); } - - componentInfo(registryError, req, res, component); - }); + ); }; }; diff --git a/src/registry/routes/component-preview.js b/src/registry/routes/component-preview.js index 1e3c90a1c..fe2b458e1 100644 --- a/src/registry/routes/component-preview.js +++ b/src/registry/routes/component-preview.js @@ -6,16 +6,16 @@ const urlBuilder = require('../domain/url-builder'); const getComponentFallback = require('./helpers/get-component-fallback'); function componentPreview(err, req, res, component, templates) { - if(err) { + if (err) { res.errorDetails = err.registryError || err; res.errorCode = 'NOT_FOUND'; return res.status(404).json(err); } - const isHtmlRequest = !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0; - - if(isHtmlRequest && !!res.conf.discovery){ + const isHtmlRequest = + !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0; + if (isHtmlRequest && !!res.conf.discovery) { return res.render('component-preview', { component: component, dependencies: _.keys(component.dependencies), @@ -23,26 +23,47 @@ function componentPreview(err, req, res, component, templates) { qs: urlBuilder.queryString(req.query), templates: templates }); - } else { - res.status(200).json(_.extend(component, { - requestVersion: req.params.componentVersion || '' - })); + res.status(200).json( + _.extend(component, { + requestVersion: req.params.componentVersion || '' + }) + ); } } -module.exports = function(conf, repository){ - return function(req, res){ - - repository.getComponent(req.params.componentName, req.params.componentVersion, (registryError, component) => { +module.exports = function(conf, repository) { + return function(req, res) { + repository.getComponent( + req.params.componentName, + req.params.componentVersion, + (registryError, component) => { + if (registryError && conf.fallbackRegistryUrl) { + return getComponentFallback.getComponentPreview( + conf, + req, + res, + registryError, + (fallbackError, fallbackComponent) => { + componentPreview( + fallbackError, + req, + res, + fallbackComponent, + repository.getTemplates() + ); + } + ); + } - if(registryError && conf.fallbackRegistryUrl) { - return getComponentFallback.getComponentPreview(conf, req, res, registryError, (fallbackError, fallbackComponent) => { - componentPreview(fallbackError, req, res, fallbackComponent, repository.getTemplates()); - }); + componentPreview( + registryError, + req, + res, + component, + repository.getTemplates() + ); } - - componentPreview(registryError, req, res, component, repository.getTemplates()); - }); + ); }; }; diff --git a/src/registry/routes/component.js b/src/registry/routes/component.js index 7c21b47a8..f35f84bc3 100644 --- a/src/registry/routes/component.js +++ b/src/registry/routes/component.js @@ -3,28 +3,30 @@ const GetComponentHelper = require('./helpers/get-component'); const _ = require('lodash'); -module.exports = function(conf, repository){ - +module.exports = function(conf, repository) { const getComponent = new GetComponentHelper(conf, repository); - return function(req, res){ - getComponent({ - conf: res.conf, - headers: req.headers, - name: req.params.componentName, - parameters: req.query, - version: req.params.componentVersion - }, (result) => { - if(result.response.error){ - res.errorCode = result.response.code; - res.errorDetails = result.response.error; - } + return function(req, res) { + getComponent( + { + conf: res.conf, + headers: req.headers, + name: req.params.componentName, + parameters: req.query, + version: req.params.componentVersion + }, + result => { + if (result.response.error) { + res.errorCode = result.response.code; + res.errorDetails = result.response.error; + } - if (!_.isEmpty(result.headers)) { - res.set(result.headers); - } + if (!_.isEmpty(result.headers)) { + res.set(result.headers); + } - return res.status(result.status).json(result.response); - }); + return res.status(result.status).json(result.response); + } + ); }; }; diff --git a/src/registry/routes/components.js b/src/registry/routes/components.js index e6a3a6463..4b1166732 100644 --- a/src/registry/routes/components.js +++ b/src/registry/routes/components.js @@ -7,49 +7,64 @@ const _ = require('lodash'); const GetComponentHelper = require('./helpers/get-component'); const strings = require('../../resources'); -module.exports = function(conf, repository){ - +module.exports = function(conf, repository) { const getComponent = new GetComponentHelper(conf, repository); - return function(req, res){ - + return function(req, res) { const components = req.body.components, registryErrors = strings.errors.registry; - const returnError = function(message){ + const returnError = function(message) { return res.status(400).json({ code: registryErrors.BATCH_ROUTE_BODY_NOT_VALID_CODE, error: format(registryErrors.BATCH_ROUTE_BODY_NOT_VALID, message) }); }; - if(!components){ - return returnError(registryErrors.BATCH_ROUTE_COMPONENTS_PROPERTY_MISSING); - } else if(!_.isArray(components)){ + if (!components) { + return returnError( + registryErrors.BATCH_ROUTE_COMPONENTS_PROPERTY_MISSING + ); + } else if (!_.isArray(components)) { return returnError(registryErrors.BATCH_ROUTE_COMPONENTS_NOT_ARRAY); } - if(!_.isEmpty(components)){ - const errors = _.compact(_.map(components, (component, index) => { - if(!component.name){ - return format(registryErrors.BATCH_ROUTE_COMPONENT_NAME_MISSING, index); - } - })); + if (!_.isEmpty(components)) { + const errors = _.compact( + _.map(components, (component, index) => { + if (!component.name) { + return format( + registryErrors.BATCH_ROUTE_COMPONENT_NAME_MISSING, + index + ); + } + }) + ); - if(!_.isEmpty(errors)){ + if (!_.isEmpty(errors)) { return returnError(errors.join(', ')); } } - async.map(components, (component, callback) => { - getComponent(_.extend(component, { - conf: res.conf, - headers: req.headers, - omitHref: !!req.body.omitHref, - parameters: _.extend(_.clone(req.body.parameters) || {}, component.parameters || {}) - }), (result) => { - callback(null, result); - }); - }, (err, results) => res.status(200).json(results)); + async.map( + components, + (component, callback) => { + getComponent( + _.extend(component, { + conf: res.conf, + headers: req.headers, + omitHref: !!req.body.omitHref, + parameters: _.extend( + _.clone(req.body.parameters) || {}, + component.parameters || {} + ) + }), + result => { + callback(null, result); + } + ); + }, + (err, results) => res.status(200).json(results) + ); }; }; diff --git a/src/registry/routes/helpers/apply-default-values.js b/src/registry/routes/helpers/apply-default-values.js index 609480631..b25bd0947 100644 --- a/src/registry/routes/helpers/apply-default-values.js +++ b/src/registry/routes/helpers/apply-default-values.js @@ -3,14 +3,20 @@ const _ = require('lodash'); module.exports = function(requestParameters, expectedParameters) { - const optionalParametersWithDefaults = _.pickBy(expectedParameters, (parameter) => !(parameter.mandatory || _.isUndefined(parameter.default))); + const optionalParametersWithDefaults = _.pickBy( + expectedParameters, + parameter => !(parameter.mandatory || _.isUndefined(parameter.default)) + ); - _.forEach(optionalParametersWithDefaults, (expectedParameter, expectedParameterName) => { - const param = requestParameters[expectedParameterName]; - if(_.isUndefined(param) || _.isNull(param)) { - requestParameters[expectedParameterName] = expectedParameter.default; + _.forEach( + optionalParametersWithDefaults, + (expectedParameter, expectedParameterName) => { + const param = requestParameters[expectedParameterName]; + if (_.isUndefined(param) || _.isNull(param)) { + requestParameters[expectedParameterName] = expectedParameter.default; + } } - }); + ); return requestParameters; }; diff --git a/src/registry/routes/helpers/get-available-dependencies.js b/src/registry/routes/helpers/get-available-dependencies.js index 03fb6698c..bee12aa04 100644 --- a/src/registry/routes/helpers/get-available-dependencies.js +++ b/src/registry/routes/helpers/get-available-dependencies.js @@ -5,13 +5,15 @@ const _ = require('lodash'); const RequireWrapper = require('../../domain/require-wrapper'); -module.exports = (dependencies) => _.map(dependencies, (dependency) => { +module.exports = dependencies => + _.map(dependencies, dependency => { + const requirer = RequireWrapper(dependencies); + const core = _.includes(coreModules, dependency); + const packageJson = !core && requirer(`${dependency}/package.json`); + const version = packageJson && packageJson.version; + const link = core + ? `https://nodejs.org/api/${dependency}.html` + : packageJson.homepage; - const requirer = RequireWrapper(dependencies); - const core = _.includes(coreModules, dependency); - const packageJson = !core && requirer(`${dependency}/package.json`); - const version = packageJson && packageJson.version; - const link = core ? `https://nodejs.org/api/${dependency}.html` : packageJson.homepage; - - return { core, name: dependency, version, link }; -}); + return { core, name: dependency, version, link }; + }); diff --git a/src/registry/routes/helpers/get-component-fallback.js b/src/registry/routes/helpers/get-component-fallback.js index f4f8fc480..ed96e2e02 100644 --- a/src/registry/routes/helpers/get-component-fallback.js +++ b/src/registry/routes/helpers/get-component-fallback.js @@ -5,66 +5,103 @@ const url = require('url'); const urlBuilder = require('../../domain/url-builder'); const _ = require('lodash'); -function getComponentFallbackForViewType(buildUrl, conf, req, res, registryError, callback) { - const path = buildUrl({ - name: req.params.componentName, - version: req.params.componentVersion - }, conf.fallbackRegistryUrl); +function getComponentFallbackForViewType( + buildUrl, + conf, + req, + res, + registryError, + callback +) { + const path = buildUrl( + { + name: req.params.componentName, + version: req.params.componentVersion + }, + conf.fallbackRegistryUrl + ); - return request({ - method: 'get', - url: path, - headers: _.extend({}, req.headers, { - 'host': url.parse(conf.fallbackRegistryUrl).host, - 'accept': 'application/json' - }) - }, (fallbackErr, fallbackResponse) => { - if (fallbackErr === 304) { - return res.status(304).send(''); - } + return request( + { + method: 'get', + url: path, + headers: _.extend({}, req.headers, { + host: url.parse(conf.fallbackRegistryUrl).host, + accept: 'application/json' + }) + }, + (fallbackErr, fallbackResponse) => { + if (fallbackErr === 304) { + return res.status(304).send(''); + } - if (fallbackErr) { - return callback({registryError: registryError, fallbackError: fallbackErr}); - } + if (fallbackErr) { + return callback({ + registryError: registryError, + fallbackError: fallbackErr + }); + } - try { - return callback(null, JSON.parse(fallbackResponse)); - } catch (parseError) { - return callback({registryError: registryError, fallbackError: 'Could not parse fallback response: ' + fallbackResponse}); + try { + return callback(null, JSON.parse(fallbackResponse)); + } catch (parseError) { + return callback({ + registryError: registryError, + fallbackError: + 'Could not parse fallback response: ' + fallbackResponse + }); + } } - }); + ); } module.exports = { - getComponent: function (fallbackRegistryUrl, headers, component, callback) { - return request({ - method: 'post', - url: fallbackRegistryUrl, - headers: _.extend({}, headers, {'host': url.parse(fallbackRegistryUrl).host}), - json: true, - body: { - components: [ - component - ] - } - }, (err, res) => { - if (err || !res || res.length === 0) { - return callback({ - status: 404, - response: { - code: 'NOT_FOUND', - error: err - } - }); - } + getComponent: function(fallbackRegistryUrl, headers, component, callback) { + return request( + { + method: 'post', + url: fallbackRegistryUrl, + headers: _.extend({}, headers, { + host: url.parse(fallbackRegistryUrl).host + }), + json: true, + body: { + components: [component] + } + }, + (err, res) => { + if (err || !res || res.length === 0) { + return callback({ + status: 404, + response: { + code: 'NOT_FOUND', + error: err + } + }); + } - return callback(res[0]); - }); + return callback(res[0]); + } + ); }, - getComponentPreview: function (conf, req, res, registryError, callback) { - getComponentFallbackForViewType(urlBuilder.componentPreview, conf, req, res, registryError, callback); + getComponentPreview: function(conf, req, res, registryError, callback) { + getComponentFallbackForViewType( + urlBuilder.componentPreview, + conf, + req, + res, + registryError, + callback + ); }, - getComponentInfo: function (conf, req, res, registryError, callback) { - getComponentFallbackForViewType(urlBuilder.componentInfo, conf, req, res, registryError, callback); + getComponentInfo: function(conf, req, res, registryError, callback) { + getComponentFallbackForViewType( + urlBuilder.componentInfo, + conf, + req, + res, + registryError, + callback + ); } }; diff --git a/src/registry/routes/helpers/get-component-retrieving-info.js b/src/registry/routes/helpers/get-component-retrieving-info.js index 31f5b3775..32b5439be 100644 --- a/src/registry/routes/helpers/get-component-retrieving-info.js +++ b/src/registry/routes/helpers/get-component-retrieving-info.js @@ -2,8 +2,7 @@ const _ = require('lodash'); -module.exports = function(options){ - +module.exports = function(options) { let eventData = { headers: options.headers, name: options.name, @@ -14,11 +13,10 @@ module.exports = function(options){ const start = process.hrtime(); return { - extend: function(obj){ + extend: function(obj) { eventData = _.extend(eventData, obj); }, - getData: function(){ - + getData: function() { const delta = process.hrtime(start), nanosec = delta[0] * 1e9 + delta[1]; diff --git a/src/registry/routes/helpers/get-component.js b/src/registry/routes/helpers/get-component.js index 9d883a3ff..720ebb62d 100644 --- a/src/registry/routes/helpers/get-component.js +++ b/src/registry/routes/helpers/get-component.js @@ -22,25 +22,26 @@ const urlBuilder = require('../../domain/url-builder'); const validator = require('../../domain/validators'); const requireTemplate = require('../../../utils/require-template'); -module.exports = function(conf, repository){ +module.exports = function(conf, repository) { const client = new Client(), cache = new Cache({ verbose: !!conf.verbosity, refreshInterval: conf.refreshInterval }); - const renderer = function(options, cb){ + const renderer = function(options, cb) { const nestedRenderer = new NestedRenderer(renderer, options.conf), retrievingInfo = new GetComponentRetrievingInfo(options); let responseHeaders = {}; - const getLanguage = function(){ - const paramOverride = !!options.parameters && options.parameters['__ocAcceptLanguage']; + const getLanguage = function() { + const paramOverride = + !!options.parameters && options.parameters['__ocAcceptLanguage']; return paramOverride || options.headers['accept-language']; }; - const callback = function(result){ - if(result.response.error){ + const callback = function(result) { + if (result.response.error) { retrievingInfo.extend(result.response); } @@ -62,318 +63,409 @@ module.exports = function(conf, repository){ parameters: options.parameters }; - repository.getComponent(requestedComponent.name, requestedComponent.version, (err, component) => { - - // check route exist for component and version - if(err){ - if(conf.fallbackRegistryUrl) { - return getComponentFallback.getComponent(conf.fallbackRegistryUrl, options.headers, requestedComponent, callback); - } - - return callback({ - status: 404, - response: { - code: 'NOT_FOUND', - error: err - } - }); - } - - // Skip rendering and return only the component info in case of 'accept: application/vnd.oc.info+json' - if (options.headers.accept === settings.registry.acceptInfoHeader) { - return callback({ - status: 200, - response: { - type: conf.local ? 'oc-component-local' : 'oc-component', - version: component.version, - requestVersion: requestedComponent.version, - name: requestedComponent.name, - } - }); - } - - // check component requirements are satisfied by registry - const pluginsCompatibility = validator.validatePluginsRequirements(component.oc.plugins, conf.plugins); - - if(!pluginsCompatibility.isValid){ - return callback({ - status: 501, - response: { - code: 'PLUGIN_MISSING_FROM_REGISTRY', - error: format(strings.errors.registry.PLUGIN_NOT_IMPLEMENTED, pluginsCompatibility.missing.join(', ')), - missingPlugins: pluginsCompatibility.missing - } - }); - } - - // sanitise and check params - const appliedParams = applyDefaultValues(requestedComponent.parameters, component.oc.parameters), - params = sanitiser.sanitiseComponentParameters(appliedParams, component.oc.parameters), - validationResult = validator.validateComponentParameters(params, component.oc.parameters); - - if(!validationResult.isValid){ - return callback({ - status: 400, - response: { - code: 'NOT_VALID_REQUEST', - error: validationResult.errors.message + repository.getComponent( + requestedComponent.name, + requestedComponent.version, + (err, component) => { + // check route exist for component and version + if (err) { + if (conf.fallbackRegistryUrl) { + return getComponentFallback.getComponent( + conf.fallbackRegistryUrl, + options.headers, + requestedComponent, + callback + ); } - }); - } - - const filterCustomHeaders = function(headers, requestedVersion, actualVersion) { - - const needFiltering = !_.isEmpty(headers) && - !_.isEmpty(conf.customHeadersToSkipOnWeakVersion) && - requestedVersion !== actualVersion; - - return needFiltering ? _.omit(headers, conf.customHeadersToSkipOnWeakVersion) : headers; - }; - - const returnComponent = function(err, data){ - if(componentCallbackDone){ return; } - componentCallbackDone = true; - - if(!!err || !data){ - err = err || new Error(strings.errors.registry.DATA_OBJECT_IS_UNDEFINED); return callback({ - status: 500, + status: 404, response: { - code: 'GENERIC_ERROR', - error: format(strings.errors.registry.COMPONENT_EXECUTION_ERROR, err.message || ''), - details: { message: err.message, stack: err.stack, originalError: err } + code: 'NOT_FOUND', + error: err } }); } - const componentHref = urlBuilder.component({ - name: component.name, - version: requestedComponent.version, - parameters: params - }, conf.baseUrl); - - const isUnrendered = options.headers.accept === settings.registry.acceptUnrenderedHeader, - renderMode = isUnrendered ? 'unrendered' : 'rendered'; - - const response = { - type: conf.local ? 'oc-component-local' : 'oc-component', - version: component.version, - requestVersion: requestedComponent.version, - name: requestedComponent.name, - renderMode: renderMode - }; - - if(!options.omitHref){ - response.href = componentHref; - } - - retrievingInfo.extend({ - href: componentHref, - version: component.version, - renderMode: renderMode - }); - - responseHeaders = filterCustomHeaders(responseHeaders, requestedComponent.version, component.version); - - if (isUnrendered) { - callback({ + // Skip rendering and return only the component info in case of 'accept: application/vnd.oc.info+json' + if (options.headers.accept === settings.registry.acceptInfoHeader) { + return callback({ status: 200, - headers: responseHeaders, - response: _.extend(response, { - data: data, - template: { - src: repository.getStaticFilePath(component.name, component.version, 'template.js'), - type: component.oc.files.template.type, - key: component.oc.files.template.hashKey - } - }) + response: { + type: conf.local ? 'oc-component-local' : 'oc-component', + version: component.version, + requestVersion: requestedComponent.version, + name: requestedComponent.name + } }); - } else { + } - const cacheKey = format('{0}/{1}/template.js', component.name, component.version), - cached = cache.get('file-contents', cacheKey), - key = component.oc.files.template.hashKey, - renderOptions = { - href: componentHref, - key: key, - version: component.version, - name: component.name, - templateType: component.oc.files.template.type, - container: component.oc.container, - renderInfo: component.oc.renderInfo - }; + // check component requirements are satisfied by registry + const pluginsCompatibility = validator.validatePluginsRequirements( + component.oc.plugins, + conf.plugins + ); - const returnResult = function(template){ - client.renderTemplate(template, data, renderOptions, (err, html) => { + if (!pluginsCompatibility.isValid) { + return callback({ + status: 501, + response: { + code: 'PLUGIN_MISSING_FROM_REGISTRY', + error: format( + strings.errors.registry.PLUGIN_NOT_IMPLEMENTED, + pluginsCompatibility.missing.join(', ') + ), + missingPlugins: pluginsCompatibility.missing + } + }); + } - if(err){ - return callback({ - status: 500, - response: { - code: 'INTERNAL_SERVER_ERROR', - error: err - } - }); - } + // sanitise and check params + const appliedParams = applyDefaultValues( + requestedComponent.parameters, + component.oc.parameters + ), + params = sanitiser.sanitiseComponentParameters( + appliedParams, + component.oc.parameters + ), + validationResult = validator.validateComponentParameters( + params, + component.oc.parameters + ); + + if (!validationResult.isValid) { + return callback({ + status: 400, + response: { + code: 'NOT_VALID_REQUEST', + error: validationResult.errors.message + } + }); + } - callback({ - status: 200, - headers: responseHeaders, - response: _.extend(response, { html: html }) - }); - }); - }; + const filterCustomHeaders = function( + headers, + requestedVersion, + actualVersion + ) { + const needFiltering = + !_.isEmpty(headers) && + !_.isEmpty(conf.customHeadersToSkipOnWeakVersion) && + requestedVersion !== actualVersion; + + return needFiltering + ? _.omit(headers, conf.customHeadersToSkipOnWeakVersion) + : headers; + }; - if(!!cached && !conf.hotReloading){ - returnResult(cached); - } else { - repository.getCompiledView(component.name, component.version, (err, templateText) => { - let ocTemplate; - let type = component.oc.files.template.type; - if (type === 'jade') { type = 'oc-template-jade'; } - if (type === 'handlebars') { type = 'oc-template-handlebars'; } - - try { - ocTemplate = requireTemplate(type); - } catch (err) { - throw err; + const returnComponent = function(err, data) { + if (componentCallbackDone) { + return; + } + componentCallbackDone = true; + + if (!!err || !data) { + err = + err || + new Error(strings.errors.registry.DATA_OBJECT_IS_UNDEFINED); + return callback({ + status: 500, + response: { + code: 'GENERIC_ERROR', + error: format( + strings.errors.registry.COMPONENT_EXECUTION_ERROR, + err.message || '' + ), + details: { + message: err.message, + stack: err.stack, + originalError: err + } } - - const template = ocTemplate.getCompiledTemplate(templateText, key); - cache.set('file-contents', cacheKey, template); - returnResult(template); }); } - } - }; - if(!component.oc.files.dataProvider){ - returnComponent(null, {}); - } else { - - const cacheKey = format('{0}/{1}/server.js', component.name, component.version), - cached = cache.get('file-contents', cacheKey), - domain = Domain.create(), - contextObj = { - acceptLanguage: acceptLanguageParser.parse(acceptLanguage), - baseUrl: conf.baseUrl, - env: conf.env, - params: params, - plugins: conf.plugins, - renderComponent: nestedRenderer.renderComponent, - renderComponents: nestedRenderer.renderComponents, - requestHeaders: options.headers, - staticPath: repository.getStaticFilePath(component.name, component.version, '').replace('https:', ''), - setHeader: function(header, value) { - if (!(typeof(header) === 'string' && typeof(value) === 'string')) { - throw strings.errors.registry.COMPONENT_SET_HEADER_PARAMETERS_NOT_VALID; - } - - if (header && value) { - responseHeaders = responseHeaders || {}; - responseHeaders[header.toLowerCase()] = value; - } + const componentHref = urlBuilder.component( + { + name: component.name, + version: requestedComponent.version, + parameters: params }, - templates: repository.getTemplates() - }; + conf.baseUrl + ); - const setCallbackTimeout = function(){ - if(conf.executionTimeout){ - setTimeout(() => { - returnComponent({ - message: format('timeout ({0}ms)', conf.executionTimeout * 1000) - }); - domain.exit(); - }, conf.executionTimeout * 1000); - } - }; + const isUnrendered = + options.headers.accept === settings.registry.acceptUnrenderedHeader, + renderMode = isUnrendered ? 'unrendered' : 'rendered'; - if(!!cached && !conf.hotReloading){ - domain.on('error', returnComponent); + const response = { + type: conf.local ? 'oc-component-local' : 'oc-component', + version: component.version, + requestVersion: requestedComponent.version, + name: requestedComponent.name, + renderMode: renderMode + }; - try { - domain.run(() => { - cached(contextObj, returnComponent); - setCallbackTimeout(); - }); - } catch(e){ - return returnComponent(e); + if (!options.omitHref) { + response.href = componentHref; } - } else { - repository.getDataProvider(component.name, component.version, (err, dataProcessorJs) => { - if(err){ - componentCallbackDone = true; + retrievingInfo.extend({ + href: componentHref, + version: component.version, + renderMode: renderMode + }); - return callback({ - status: 502, - response: { - code: 'DATA_RESOLVING_ERROR', - error: strings.errors.registry.RESOLVING_ERROR + responseHeaders = filterCustomHeaders( + responseHeaders, + requestedComponent.version, + component.version + ); + + if (isUnrendered) { + callback({ + status: 200, + headers: responseHeaders, + response: _.extend(response, { + data: data, + template: { + src: repository.getStaticFilePath( + component.name, + component.version, + 'template.js' + ), + type: component.oc.files.template.type, + key: component.oc.files.template.hashKey } - }); - } + }) + }); + } else { + const cacheKey = format( + '{0}/{1}/template.js', + component.name, + component.version + ), + cached = cache.get('file-contents', cacheKey), + key = component.oc.files.template.hashKey, + renderOptions = { + href: componentHref, + key: key, + version: component.version, + name: component.name, + templateType: component.oc.files.template.type, + container: component.oc.container, + renderInfo: component.oc.renderInfo + }; + + const returnResult = function(template) { + client.renderTemplate( + template, + data, + renderOptions, + (err, html) => { + if (err) { + return callback({ + status: 500, + response: { + code: 'INTERNAL_SERVER_ERROR', + error: err + } + }); + } - const context = { - require: RequireWrapper(conf.dependencies), - module: { exports: {}}, - console: conf.local ? console : { log: _.noop }, - setTimeout: setTimeout, - Buffer: Buffer + callback({ + status: 200, + headers: responseHeaders, + response: _.extend(response, { html: html }) + }); + } + ); }; - const handleError = function(err){ - - if(err.code === 'DEPENDENCY_MISSING_FROM_REGISTRY'){ - componentCallbackDone = true; + if (!!cached && !conf.hotReloading) { + returnResult(cached); + } else { + repository.getCompiledView( + component.name, + component.version, + (err, templateText) => { + let ocTemplate; + let type = component.oc.files.template.type; + if (type === 'jade') { + type = 'oc-template-jade'; + } + if (type === 'handlebars') { + type = 'oc-template-handlebars'; + } - return callback({ - status: 501, - response: { - code: err.code, - error: format(strings.errors.registry.DEPENDENCY_NOT_FOUND, err.missing.join(', ')), - missingDependencies: err.missing + try { + ocTemplate = requireTemplate(type); + } catch (err) { + throw err; } - }); - } - const usedPlugins = detective.parse(dataProcessorJs), - unRegisteredPlugins = _.difference(usedPlugins, _.keys(conf.plugins)); + const template = ocTemplate.getCompiledTemplate( + templateText, + key + ); + cache.set('file-contents', cacheKey, template); + returnResult(template); + } + ); + } + } + }; - if(!_.isEmpty(unRegisteredPlugins)){ - componentCallbackDone = true; + if (!component.oc.files.dataProvider) { + returnComponent(null, {}); + } else { + const cacheKey = format( + '{0}/{1}/server.js', + component.name, + component.version + ), + cached = cache.get('file-contents', cacheKey), + domain = Domain.create(), + contextObj = { + acceptLanguage: acceptLanguageParser.parse(acceptLanguage), + baseUrl: conf.baseUrl, + env: conf.env, + params: params, + plugins: conf.plugins, + renderComponent: nestedRenderer.renderComponent, + renderComponents: nestedRenderer.renderComponents, + requestHeaders: options.headers, + staticPath: repository + .getStaticFilePath(component.name, component.version, '') + .replace('https:', ''), + setHeader: function(header, value) { + if ( + !(typeof header === 'string' && typeof value === 'string') + ) { + throw strings.errors.registry + .COMPONENT_SET_HEADER_PARAMETERS_NOT_VALID; + } - return callback({ - status: 501, - response: { - code: 'PLUGIN_MISSING_FROM_COMPONENT', - error: format(strings.errors.registry.PLUGIN_NOT_FOUND, unRegisteredPlugins.join(' ,')), - missingPlugins: unRegisteredPlugins - } + if (header && value) { + responseHeaders = responseHeaders || {}; + responseHeaders[header.toLowerCase()] = value; + } + }, + templates: repository.getTemplates() + }; + + const setCallbackTimeout = function() { + if (conf.executionTimeout) { + setTimeout(() => { + returnComponent({ + message: format( + 'timeout ({0}ms)', + conf.executionTimeout * 1000 + ) }); - } + domain.exit(); + }, conf.executionTimeout * 1000); + } + }; - returnComponent(err); - }; + if (!!cached && !conf.hotReloading) { + domain.on('error', returnComponent); try { - vm.runInNewContext(dataProcessorJs, context); - const processData = context.module.exports.data; - cache.set('file-contents', cacheKey, processData); - - domain.on('error', handleError); domain.run(() => { - processData(contextObj, returnComponent); + cached(contextObj, returnComponent); setCallbackTimeout(); }); - } catch(err){ - handleError(err); + } catch (e) { + return returnComponent(e); } - }); + } else { + repository.getDataProvider( + component.name, + component.version, + (err, dataProcessorJs) => { + if (err) { + componentCallbackDone = true; + + return callback({ + status: 502, + response: { + code: 'DATA_RESOLVING_ERROR', + error: strings.errors.registry.RESOLVING_ERROR + } + }); + } + + const context = { + require: RequireWrapper(conf.dependencies), + module: { exports: {} }, + console: conf.local ? console : { log: _.noop }, + setTimeout: setTimeout, + Buffer: Buffer + }; + + const handleError = function(err) { + if (err.code === 'DEPENDENCY_MISSING_FROM_REGISTRY') { + componentCallbackDone = true; + + return callback({ + status: 501, + response: { + code: err.code, + error: format( + strings.errors.registry.DEPENDENCY_NOT_FOUND, + err.missing.join(', ') + ), + missingDependencies: err.missing + } + }); + } + + const usedPlugins = detective.parse(dataProcessorJs), + unRegisteredPlugins = _.difference( + usedPlugins, + _.keys(conf.plugins) + ); + + if (!_.isEmpty(unRegisteredPlugins)) { + componentCallbackDone = true; + + return callback({ + status: 501, + response: { + code: 'PLUGIN_MISSING_FROM_COMPONENT', + error: format( + strings.errors.registry.PLUGIN_NOT_FOUND, + unRegisteredPlugins.join(' ,') + ), + missingPlugins: unRegisteredPlugins + } + }); + } + + returnComponent(err); + }; + + try { + vm.runInNewContext(dataProcessorJs, context); + const processData = context.module.exports.data; + cache.set('file-contents', cacheKey, processData); + + domain.on('error', handleError); + domain.run(() => { + processData(contextObj, returnComponent); + setCallbackTimeout(); + }); + } catch (err) { + handleError(err); + } + } + ); + } } } - }); + ); }; return renderer; diff --git a/src/registry/routes/helpers/get-components-history.js b/src/registry/routes/helpers/get-components-history.js index a7dbd4a59..6b32cc1ec 100644 --- a/src/registry/routes/helpers/get-components-history.js +++ b/src/registry/routes/helpers/get-components-history.js @@ -4,7 +4,7 @@ const _ = require('lodash'); const dateStringified = require('../../../utils/date-stringify'); -module.exports = (history) => { +module.exports = history => { const result = []; _.each(history.components, (versions, name) => { @@ -17,12 +17,11 @@ module.exports = (history) => { }); }); - return _ - .sortBy(result, 'publishDate') - .reverse() - .map(x => ({ - name: x.name, - version: x.version, - publishDate: !x.publishDate ? 'Unknown' : dateStringified(new Date(x.publishDate)) - })); + return _.sortBy(result, 'publishDate').reverse().map(x => ({ + name: x.name, + version: x.version, + publishDate: !x.publishDate + ? 'Unknown' + : dateStringified(new Date(x.publishDate)) + })); }; diff --git a/src/registry/routes/helpers/is-url-discoverable.js b/src/registry/routes/helpers/is-url-discoverable.js index cd0144251..968ccc8d1 100644 --- a/src/registry/routes/helpers/is-url-discoverable.js +++ b/src/registry/routes/helpers/is-url-discoverable.js @@ -2,16 +2,20 @@ const request = require('minimal-request'); -module.exports = function(url, callback){ - request({ - url: url, - headers: { accept: 'text/html' } - }, (err, body, details) => { +module.exports = function(url, callback) { + request( + { + url: url, + headers: { accept: 'text/html' } + }, + (err, body, details) => { + const isHtml = function() { + return ( + details.response.headers['content-type'].indexOf('text/html') >= 0 + ); + }; - const isHtml = function(){ - return details.response.headers['content-type'].indexOf('text/html') >= 0; - }; - - callback(null, { isDiscoverable: !err && isHtml() }); - }); + callback(null, { isDiscoverable: !err && isHtml() }); + } + ); }; diff --git a/src/registry/routes/index.js b/src/registry/routes/index.js index 6e19758e4..71fe4fc8f 100644 --- a/src/registry/routes/index.js +++ b/src/registry/routes/index.js @@ -9,73 +9,94 @@ const getAvailableDependencies = require('./helpers/get-available-dependencies') const packageInfo = require('../../../package.json'); const urlBuilder = require('../domain/url-builder'); -module.exports = function(repository){ - return function(req, res, next){ - +module.exports = function(repository) { + return function(req, res, next) { repository.getComponents((err, components) => { - if(err){ + if (err) { res.errorDetails = 'cdn not available'; return res.status(404).json({ error: res.errorDetails }); } - const isHtmlRequest = !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0, + const isHtmlRequest = + !!req.headers.accept && req.headers.accept.indexOf('text/html') >= 0, baseResponse = { href: res.conf.baseUrl, ocVersion: packageInfo.version, type: res.conf.local ? 'oc-registry-local' : 'oc-registry' }; - if(isHtmlRequest && !!res.conf.discovery){ - - let componentsInfo = [], componentsReleases = 0; + if (isHtmlRequest && !!res.conf.discovery) { + let componentsInfo = [], + componentsReleases = 0; const stateCounts = {}; - async.each(components, (component, callback) => repository.getComponent(component, (err, result) => { - if(err){ return callback(err); } - - if(result.oc && result.oc.date) { - result.oc.stringifiedDate = dateStringified(new Date(result.oc.date)); + async.each( + components, + (component, callback) => + repository.getComponent(component, (err, result) => { + if (err) { + return callback(err); + } + + if (result.oc && result.oc.date) { + result.oc.stringifiedDate = dateStringified( + new Date(result.oc.date) + ); + } + + componentsInfo.push(result); + componentsReleases += result.allVersions.length; + callback(); + }), + err => { + if (err) { + return next(err); + } + + componentsInfo = _.sortBy(componentsInfo, 'name'); + + repository.getComponentsDetails((err, details) => { + res.render( + 'index', + _.extend(baseResponse, { + availableDependencies: getAvailableDependencies( + res.conf.dependencies + ), + availablePlugins: res.conf.plugins, + components: componentsInfo, + componentsReleases, + componentsList: _.map(componentsInfo, component => { + const state = !!component.oc && !!component.oc.state + ? component.oc.state + : ''; + + if (state) { + stateCounts[state] = stateCounts[state] || 0; + stateCounts[state] += 1; + } + + return { + name: component.name, + state: state + }; + }), + componentsHistory: + !res.conf.local && getComponentsHistory(details), + q: req.query.q || '', + stateCounts + }) + ); + }); } - - componentsInfo.push(result); - componentsReleases += result.allVersions.length; - callback(); - }), (err) => { - if(err){ return next(err); } - - componentsInfo = _.sortBy(componentsInfo, 'name'); - - repository.getComponentsDetails((err, details) => { - - res.render('index', _.extend(baseResponse, { - availableDependencies: getAvailableDependencies(res.conf.dependencies), - availablePlugins: res.conf.plugins, - components: componentsInfo, - componentsReleases, - componentsList: _.map(componentsInfo, (component) => { - - const state = (!!component.oc && !!component.oc.state) ? component.oc.state : ''; - - if(state){ - stateCounts[state] = stateCounts[state] || 0; - stateCounts[state] += 1; - } - - return { - name: component.name, - state: state - }; - }), - componentsHistory: !res.conf.local && getComponentsHistory(details), - q: req.query.q || '', - stateCounts - })); - }); - }); + ); } else { - res.status(200).json(_.extend(baseResponse, { - components: _.map(components, (component) => urlBuilder.component(component, res.conf.baseUrl)) - })); + res.status(200).json( + _.extend(baseResponse, { + components: _.map(components, component => + urlBuilder.component(component, res.conf.baseUrl) + ) + }) + ); } }); }; diff --git a/src/registry/routes/publish.js b/src/registry/routes/publish.js index b2c2f68ae..e0e7eee6f 100644 --- a/src/registry/routes/publish.js +++ b/src/registry/routes/publish.js @@ -6,23 +6,27 @@ const extractPackage = require('../domain/extract-package'); const strings = require('../../resources/index'); const validator = require('../domain/validators'); -module.exports = function(repository){ - - return function(req, res){ - - if(!req.params.componentName || !req.params.componentVersion){ +module.exports = function(repository) { + return function(req, res) { + if (!req.params.componentName || !req.params.componentVersion) { res.errorDetails = 'malformed request'; return res.status(409).json({ error: res.errorDetails }); } - if(!validator.validatePackage(req.files).isValid){ + if (!validator.validatePackage(req.files).isValid) { res.errorDetails = 'package is not valid'; return res.status(409).json({ error: res.errorDetails }); } - let validationResult = validator.validateOcCliVersion(req.headers['user-agent']); - if(!validationResult.isValid) { - res.errorDetails = format(strings.errors.registry.OC_CLI_VERSION_IS_NOT_VALID, validationResult.error.registryVersion, validationResult.error.cliVersion); + let validationResult = validator.validateOcCliVersion( + req.headers['user-agent'] + ); + if (!validationResult.isValid) { + res.errorDetails = format( + strings.errors.registry.OC_CLI_VERSION_IS_NOT_VALID, + validationResult.error.registryVersion, + validationResult.error.cliVersion + ); return res.status(409).json({ code: 'cli_version_not_valid', error: res.errorDetails, @@ -30,9 +34,16 @@ module.exports = function(repository){ }); } - validationResult = validator.validateNodeVersion(req.headers['user-agent'], process.version); - if(!validationResult.isValid) { - res.errorDetails = format(strings.errors.registry.NODE_CLI_VERSION_IS_NOT_VALID, validationResult.error.registryNodeVersion, validationResult.error.cliNodeVersion); + validationResult = validator.validateNodeVersion( + req.headers['user-agent'], + process.version + ); + if (!validationResult.isValid) { + res.errorDetails = format( + strings.errors.registry.NODE_CLI_VERSION_IS_NOT_VALID, + validationResult.error.registryNodeVersion, + validationResult.error.cliNodeVersion + ); return res.status(409).json({ code: 'node_version_not_valid', error: res.errorDetails, @@ -41,35 +52,49 @@ module.exports = function(repository){ } extractPackage(req.files, (err, pkgDetails) => { - - if(err){ + if (err) { res.errorDetails = format('Package is not valid: {0}', err); - return res.status(500).json({ error: 'package is not valid', details: err }); + return res + .status(500) + .json({ error: 'package is not valid', details: err }); } - repository.publishComponent(pkgDetails, req.params.componentName, req.params.componentVersion, (err) => { - - if(err){ - if(err.code === 'not_allowed'){ - res.errorDetails = format('Publish not allowed: {0}', err.msg); - return res.status(403).json({ error: err.msg }); - } else if(err.code === 'already_exists'){ - res.errorDetails = format('Component already exists: {0}', err.msg); - return res.status(403).json({ error: err.msg }); - } else if(err.code === 'name_not_valid'){ - res.errorDetails = format('Component name not valid: {0}', err.msg); - return res.status(409).json({ error: err.msg }); - } else if(err.code === 'version_not_valid'){ - res.errorDetails = format('Component version not valid: {0}', err.msg); - return res.status(409).json({ error: err.msg }); - } else { - res.errorDetails = format('Publish failed: {0}', err.msg); - return res.status(500).json({ error: err.msg }); + repository.publishComponent( + pkgDetails, + req.params.componentName, + req.params.componentVersion, + err => { + if (err) { + if (err.code === 'not_allowed') { + res.errorDetails = format('Publish not allowed: {0}', err.msg); + return res.status(403).json({ error: err.msg }); + } else if (err.code === 'already_exists') { + res.errorDetails = format( + 'Component already exists: {0}', + err.msg + ); + return res.status(403).json({ error: err.msg }); + } else if (err.code === 'name_not_valid') { + res.errorDetails = format( + 'Component name not valid: {0}', + err.msg + ); + return res.status(409).json({ error: err.msg }); + } else if (err.code === 'version_not_valid') { + res.errorDetails = format( + 'Component version not valid: {0}', + err.msg + ); + return res.status(409).json({ error: err.msg }); + } else { + res.errorDetails = format('Publish failed: {0}', err.msg); + return res.status(500).json({ error: err.msg }); + } } - } - res.status(200).json({ ok: true }); - }); + res.status(200).json({ ok: true }); + } + ); }); }; }; diff --git a/src/registry/routes/static-redirector.js b/src/registry/routes/static-redirector.js index 4031fbec7..8186be428 100644 --- a/src/registry/routes/static-redirector.js +++ b/src/registry/routes/static-redirector.js @@ -6,32 +6,46 @@ const path = require('path'); const getFileInfo = require('../../utils/get-file-info'); -module.exports = function(repository){ - return function(req, res){ - +module.exports = function(repository) { + return function(req, res) { let filePath; - const clientPath = (res.conf.prefix ? res.conf.prefix : '/') + 'oc-client/client.js', - clientMapPath = (res.conf.prefix ? res.conf.prefix : '/') + 'oc-client/oc-client.min.map'; + const clientPath = + (res.conf.prefix ? res.conf.prefix : '/') + 'oc-client/client.js', + clientMapPath = + (res.conf.prefix ? res.conf.prefix : '/') + + 'oc-client/oc-client.min.map'; - if(req.route.path === clientPath){ - if(res.conf.local){ - filePath = path.join(__dirname, '../../components/oc-client/_package/src/oc-client.min.js'); + if (req.route.path === clientPath) { + if (res.conf.local) { + filePath = path.join( + __dirname, + '../../components/oc-client/_package/src/oc-client.min.js' + ); } else { return res.redirect(repository.getStaticClientPath()); } - } else if(req.route.path === clientMapPath){ - if(res.conf.local){ - filePath = path.join(__dirname, '../../components/oc-client/_package/src/oc-client.min.map'); + } else if (req.route.path === clientMapPath) { + if (res.conf.local) { + filePath = path.join( + __dirname, + '../../components/oc-client/_package/src/oc-client.min.map' + ); } else { return res.redirect(repository.getStaticClientMapPath()); } - } else if(req.params.componentName === 'oc-client'){ - filePath = path.join(__dirname, '../../components/oc-client/_package/' + req.params[0]); + } else if (req.params.componentName === 'oc-client') { + filePath = path.join( + __dirname, + '../../components/oc-client/_package/' + req.params[0] + ); } else { - filePath = path.join(res.conf.path, req.params.componentName) + '/_package/' + req.params[0]; + filePath = + path.join(res.conf.path, req.params.componentName) + + '/_package/' + + req.params[0]; } - if(!fs.existsSync(filePath)){ + if (!fs.existsSync(filePath)) { res.errorDetails = format('File {0} not found', filePath); return res.status(404).json({ err: res.errorDetails }); } @@ -39,11 +53,11 @@ module.exports = function(repository){ const fileStream = fs.createReadStream(filePath), fileInfo = getFileInfo(filePath); - if(fileInfo.mimeType){ + if (fileInfo.mimeType) { res.set('Content-Type', fileInfo.mimeType); } - if(fileInfo.gzip){ + if (fileInfo.gzip) { res.set('Content-Encoding', 'gzip'); } diff --git a/src/registry/views/static/component-info.js b/src/registry/views/static/component-info.js index 7466b6828..f1f18ba63 100644 --- a/src/registry/views/static/component-info.js +++ b/src/registry/views/static/component-info.js @@ -5,26 +5,24 @@ var oc = oc || {}; oc.cmd = oc.cmd || []; -oc.cmd.push(function(){ - - $('#versions').change(function(){ +oc.cmd.push(function() { + $('#versions').change(function() { window.location = thisComponentHref + $(this).val() + '/~info'; }); - $('.refresh-preview').click(function(){ - + $('.refresh-preview').click(function() { var splitted = $('#href').val().split('?'), url = splitted[0], lang = $('#lang').val(); - if(url.slice(-1) !== '/'){ + if (url.slice(-1) !== '/') { url += '/'; } - url = url.replace('http\:\/\/', '\/\/').replace('https\:\/\/', '\/\/'); + url = url.replace('http://', '//').replace('https://', '//'); url += '~preview/?__ocAcceptLanguage=' + lang + '&'; - if(splitted.length > 1){ + if (splitted.length > 1) { url += splitted[1]; } diff --git a/src/registry/views/static/index.js b/src/registry/views/static/index.js index abe66bc03..610ddc694 100644 --- a/src/registry/views/static/index.js +++ b/src/registry/views/static/index.js @@ -5,9 +5,8 @@ var oc = oc || {}; oc.cmd = oc.cmd || []; -oc.cmd.push(function(){ - - var componentsListChanged = function(){ +oc.cmd.push(function() { + var componentsListChanged = function() { $('.componentRow').removeClass('hide'); var s = $('.search').val(), r = new RegExp(s), @@ -16,24 +15,24 @@ oc.cmd.push(function(){ hidden = 0, i; - for(i = 0; i < selectedCheckboxes.length; i++){ + for (i = 0; i < selectedCheckboxes.length; i++) { hiddenStates.push($(selectedCheckboxes[i]).attr('name')); } - for(i = 0; i < componentsList.length; i++){ + for (i = 0; i < componentsList.length; i++) { var matches = !s || !!componentsList[i].name.match(r), selector = $('#component-' + componentsList[i].name), isHidden = false; - for(var j = 0; j < hiddenStates.length; j++){ - if(componentsList[i].state.toLowerCase() === hiddenStates[j]){ + for (var j = 0; j < hiddenStates.length; j++) { + if (componentsList[i].state.toLowerCase() === hiddenStates[j]) { isHidden = true; } } var show = matches && !isHidden; selector[show ? 'removeClass' : 'addClass']('hide'); - if(!show){ + if (!show) { hidden += 1; } } @@ -41,7 +40,7 @@ oc.cmd.push(function(){ var totalShowing = componentsList.length - hidden, result = 'Showing ' + totalShowing + ' components'; - if(s){ + if (s) { result += ' matching search query: ' + s; } @@ -50,9 +49,8 @@ oc.cmd.push(function(){ return false; }; - var initialiseTabs = function(){ - - var selectItem = function(target){ + var initialiseTabs = function() { + var selectItem = function(target) { var $target = $(target); $('.box').hide(); $target.show(); @@ -60,20 +58,22 @@ oc.cmd.push(function(){ $('#menuList a[href="' + target + '"]').addClass('selected'); }; - var hash = (location.href.split("#")[1] || ""); + var hash = location.href.split('#')[1] || ''; var isHashValid = hash && $('#' + hash); var target = isHashValid ? '#' + hash : $($('#menuList a')[0]).attr('href'); selectItem(target); - $('#menuList a').click(function(){ + $('#menuList a').click(function() { selectItem($(this).attr('href')); }); }; - $('#filter-components').submit(componentsListChanged).keyup(componentsListChanged); + $('#filter-components') + .submit(componentsListChanged) + .keyup(componentsListChanged); $('#filter-components input[type=checkbox]').change(componentsListChanged); - if(q){ + if (q) { $('.search').val(q); } diff --git a/src/resources/index.js b/src/resources/index.js index e52df03f4..ce9a2a119 100644 --- a/src/resources/index.js +++ b/src/resources/index.js @@ -13,46 +13,71 @@ module.exports = { BATCH_ROUTE_BODY_NOT_VALID_CODE: 'POST_BODY_NOT_VALID', BATCH_ROUTE_COMPONENTS_PROPERTY_MISSING: 'components property is missing', BATCH_ROUTE_COMPONENTS_NOT_ARRAY: 'components property is not an array', - BATCH_ROUTE_COMPONENT_NAME_MISSING: 'component {0} must have name property', + BATCH_ROUTE_COMPONENT_NAME_MISSING: + 'component {0} must have name property', COMPONENT_EXECUTION_ERROR: 'Component execution error: {0}', - COMPONENT_NAME_NOT_VALID: 'The component\'s name contains invalid characters. Allowed are alphanumeric, _, -', + COMPONENT_NAME_NOT_VALID: + "The component's name contains invalid characters. Allowed are alphanumeric, _, -", COMPONENT_NAME_NOT_VALID_CODE: 'name_not_valid', COMPONENT_NOT_FOUND: 'Component "{0}" not found on {1}', - COMPONENT_PUBLISHNAME_CONFLICT: 'Component name conflict. Ensure package.json and component\s folder name are equal.', + COMPONENT_PUBLISHNAME_CONFLICT: + 'Component name conflict. Ensure package.json and components folder name are equal.', COMPONENT_PUBLISHVALIDATION_FAIL: 'Component validation failed: {0}', COMPONENT_PUBLISHVALIDATION_FAIL_CODE: 'not_allowed', - COMPONENT_VERSION_NOT_FOUND: 'Component "{0}" with version "{1}" not found on {2}', - COMPONENT_VERSION_ALREADY_FOUND: 'Component "{0}" with version "{1}" can\'t be published to {2} because a component with the same name and version already exists', + COMPONENT_VERSION_NOT_FOUND: + 'Component "{0}" with version "{1}" not found on {2}', + COMPONENT_VERSION_ALREADY_FOUND: + 'Component "{0}" with version "{1}" can\'t be published to {2} because a component with the same name and version already exists', COMPONENT_VERSION_ALREADY_FOUND_CODE: 'already_exists', - COMPONENT_VERSION_NOT_VALID: 'Version "{0}" is not a valid semantic version.', + COMPONENT_VERSION_NOT_VALID: + 'Version "{0}" is not a valid semantic version.', COMPONENT_VERSION_NOT_VALID_CODE: 'version_not_valid', - COMPONENT_SET_HEADER_PARAMETERS_NOT_VALID: 'context.setHeader parameters must be strings', - CONFIGURATION_DEPENDENCIES_MUST_BE_ARRAY: 'Registry configuration is not valid: dependencies must be an array', + COMPONENT_SET_HEADER_PARAMETERS_NOT_VALID: + 'context.setHeader parameters must be strings', + CONFIGURATION_DEPENDENCIES_MUST_BE_ARRAY: + 'Registry configuration is not valid: dependencies must be an array', CONFIGURATION_EMPTY: 'Registry configuration is empty', - CONFIGURATION_ONREQUEST_MUST_BE_FUNCTION: 'Registry configuration is not valid: registry.on\'s callback must be a function', - CONFIGURATION_PUBLISH_BASIC_AUTH_CREDENTIALS_MISSING: 'Registry configuration is not valid: basic auth requires username and password', - CONFIGURATION_PUBLISH_AUTH_MODULE_NOT_FOUND: 'Registry configuration is not valid: module "{0}" not found', - CONFIGURATION_PREFIX_DOES_NOT_END_WITH_SLASH: 'Registry configuration is not valid: prefix should end with "/"', - CONFIGURATION_PREFIX_DOES_NOT_START_WITH_SLASH: 'Registry configuration is not valid: prefix should start with "/"', - CONFIGURATION_ROUTES_HANDLER_MUST_BE_FUNCTION: 'Registry configuration is not valid: handler should be a function', - CONFIGURATION_ROUTES_NOT_VALID: 'Registry configuration is not valid: each route should contain route, method and handler', - CONFIGURATION_ROUTES_MUST_BE_ARRAY: 'Registry configuration is not valid: routes must be an array', - CONFIGURATION_ROUTES_ROUTE_CONTAINS_PREFIX: 'Registry configuration is not valid: route url can\'t contain "{0}"', - CONFIGURATION_S3_NOT_VALID: 'Registry configuration is not valid: S3 configuration is not valid', - CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY: 'Registry configuration is not valid: customHeadersToSkipOnWeakVersion must be an array of strings', + CONFIGURATION_ONREQUEST_MUST_BE_FUNCTION: + "Registry configuration is not valid: registry.on's callback must be a function", + CONFIGURATION_PUBLISH_BASIC_AUTH_CREDENTIALS_MISSING: + 'Registry configuration is not valid: basic auth requires username and password', + CONFIGURATION_PUBLISH_AUTH_MODULE_NOT_FOUND: + 'Registry configuration is not valid: module "{0}" not found', + CONFIGURATION_PREFIX_DOES_NOT_END_WITH_SLASH: + 'Registry configuration is not valid: prefix should end with "/"', + CONFIGURATION_PREFIX_DOES_NOT_START_WITH_SLASH: + 'Registry configuration is not valid: prefix should start with "/"', + CONFIGURATION_ROUTES_HANDLER_MUST_BE_FUNCTION: + 'Registry configuration is not valid: handler should be a function', + CONFIGURATION_ROUTES_NOT_VALID: + 'Registry configuration is not valid: each route should contain route, method and handler', + CONFIGURATION_ROUTES_MUST_BE_ARRAY: + 'Registry configuration is not valid: routes must be an array', + CONFIGURATION_ROUTES_ROUTE_CONTAINS_PREFIX: + 'Registry configuration is not valid: route url can\'t contain "{0}"', + CONFIGURATION_S3_NOT_VALID: + 'Registry configuration is not valid: S3 configuration is not valid', + CONFIGURATION_HEADERS_TO_SKIP_MUST_BE_STRING_ARRAY: + 'Registry configuration is not valid: customHeadersToSkipOnWeakVersion must be an array of strings', DATA_OBJECT_IS_UNDEFINED: 'data object is undefined', - DEPENDENCY_NOT_FOUND: 'Component is trying to use unavailable dependencies: {0}', + DEPENDENCY_NOT_FOUND: + 'Component is trying to use unavailable dependencies: {0}', DEPENDENCY_NOT_FOUND_CODE: 'DEPENDENCY_MISSING_FROM_REGISTRY', - LOCAL_PUBLISH_NOT_ALLOWED: 'Components can\'t be published to local repository', + LOCAL_PUBLISH_NOT_ALLOWED: + "Components can't be published to local repository", LOCAL_PUBLISH_NOT_ALLOWED_CODE: 'not_allowed', GENERIC_ERROR: 'error!', - MANDATORY_PARAMETER_MISSING: 'Expected mandatory parameters are missing: {0}', + MANDATORY_PARAMETER_MISSING: + 'Expected mandatory parameters are missing: {0}', MANDATORY_PARAMETER_MISSING_CODE: 'missing', NESTED_RENDERER_CALLBACK_IS_NOT_VALID: 'callback is not valid', - NESTED_RENDERER_COMPONENT_NAME_IS_NOT_VALID: 'component\'s name is not valid', + NESTED_RENDERER_COMPONENT_NAME_IS_NOT_VALID: + "component's name is not valid", NESTED_RENDERER_COMPONENTS_IS_NOT_VALID: 'components is not valid', - NODE_CLI_VERSION_IS_NOT_VALID: 'Node CLI version is not valid: Registry {0}, CLI {1}', - OC_CLI_VERSION_IS_NOT_VALID: 'OC CLI version is not valid: Registry {0}, CLI {1}', + NODE_CLI_VERSION_IS_NOT_VALID: + 'Node CLI version is not valid: Registry {0}, CLI {1}', + OC_CLI_VERSION_IS_NOT_VALID: + 'OC CLI version is not valid: Registry {0}, CLI {1}', PARAMETER_WRONG_FORMAT: 'Parameters are not correctly formatted: {0}', PARAMETER_WRONG_FORMAT_CODE: 'wrong type', PLUGIN_NOT_FOUND: 'Component is trying to use un-registered plugins: {0}', @@ -63,29 +88,41 @@ module.exports = { TEMPLATE_NOT_VALID: '{0} is not a valid oc-template' }, cli: { - COMPONENT_HREF_NOT_FOUND: 'The specified path is not a valid component\'s url', + COMPONENT_HREF_NOT_FOUND: + "The specified path is not a valid component's url", COMPONENTS_NOT_FOUND: 'no components found in specified path', FOLDER_IS_NOT_A_FOLDER: '"{0}" must be a directory', FOLDER_NOT_FOUND: '"{0}" not found', DEV_FAIL: 'An error happened when initialising the dev runner: {0}', INIT_FAIL: 'An error happened when initialising the component: {0}', INVALID_CREDENTIALS: 'Invalid credentials', - MOCK_PLUGIN_IS_NOT_A_FUNCTION: 'Looks like you are trying to register a dynamic mock plugin but the file you specified is not a function', - NAME_NOT_VALID: 'the name is not valid. Allowed characters are alphanumeric, _, -', - NODE_CLI_VERSION_NEEDS_UPGRADE: 'the version of used node is invalid. Try to upgrade node to version matching \'{0}\'', - OC_CLI_VERSION_NEEDS_UPGRADE: 'the version of used OC CLI is invalid. Try to upgrade OC CLI running {0}', + MOCK_PLUGIN_IS_NOT_A_FUNCTION: + 'Looks like you are trying to register a dynamic mock plugin but the file you specified is not a function', + NAME_NOT_VALID: + 'the name is not valid. Allowed characters are alphanumeric, _, -', + NODE_CLI_VERSION_NEEDS_UPGRADE: + "the version of used node is invalid. Try to upgrade node to version matching '{0}'", + OC_CLI_VERSION_NEEDS_UPGRADE: + 'the version of used OC CLI is invalid. Try to upgrade OC CLI running {0}', PACKAGE_CREATION_FAIL: 'An error happened when creating the package: {0}', PACKAGING_FAIL: 'an error happened while packaging {0}: {1}', - PLUGIN_MISSING_FROM_REGISTRY: 'Looks like you are trying to use a plugin in the dev mode ({0}).\nYou need to mock it doing {1}', - PLUGIN_MISSING_FROM_COMPONENT: 'Looks like you are trying to use a plugin you haven\'t registered ({0}).' + - '\nYou need to register it editing your component\'s package.json', - PORT_IS_BUSY: 'The port {0} is already in use. Specify the optional port parameter to use another port.', + PLUGIN_MISSING_FROM_REGISTRY: + 'Looks like you are trying to use a plugin in the dev mode ({0}).\nYou need to mock it doing {1}', + PLUGIN_MISSING_FROM_COMPONENT: + "Looks like you are trying to use a plugin you haven't registered ({0})." + + "\nYou need to register it editing your component's package.json", + PORT_IS_BUSY: + 'The port {0} is already in use. Specify the optional port parameter to use another port.', PUBLISHING_FAIL: 'An error happened when publishing the component: {0}', - REGISTRY_NOT_FOUND: 'oc registries not found. Run "oc registry add "', - SERVERJS_DEPENDENCY_NOT_DECLARED: 'Missing dependencies from package.json => {0}', + REGISTRY_NOT_FOUND: + 'oc registries not found. Run "oc registry add "', + SERVERJS_DEPENDENCY_NOT_DECLARED: + 'Missing dependencies from package.json => {0}', TEMPLATE_NOT_FOUND: 'file {0} not found', - TEMPLATE_TYPE_NOT_VALID: 'the template is not valid. Allowed values are handlebars and jade', - TEMPLATE_DEP_MISSING: 'Template dependency missing. Run "$npm install --save {0}" to fix it.' + TEMPLATE_TYPE_NOT_VALID: + 'the template is not valid. Allowed values are handlebars and jade', + TEMPLATE_DEP_MISSING: + 'Template dependency missing. Run "$npm install --save {0}" to fix it.' }, generic: 'An error occurred: {0}', s3: { @@ -108,15 +145,18 @@ module.exports = { ENTER_USERNAME: 'Enter username:', USING_CREDS: 'Using specified credentials', HELP_HINT: 'Hint: Run -h with any command to show the help', - HOT_RELOADING_DISABLED: 'OC dev is running with hot reloading disabled so changes will be ignored', - INSTALLING_DEPS: 'Trying to install missing modules: {0}\nIf you aren\'t connected to the internet, or npm isn\'t configured then this step will fail', + HOT_RELOADING_DISABLED: + 'OC dev is running with hot reloading disabled so changes will be ignored', + INSTALLING_DEPS: + "Trying to install missing modules: {0}\nIf you aren't connected to the internet, or npm isn't configured then this step will fail", MOCKED_PLUGIN: 'Mock for plugin has been registered: {0} () => {1}', - NO_SUCH_COMMAND: 'No such command \'{0}\'', - NOT_VALID_REGISTRY_COMMAND: 'Not valid command: got {0}, allowed values: add, ls, remove', + NO_SUCH_COMMAND: "No such command '{0}'", + NOT_VALID_REGISTRY_COMMAND: + 'Not valid command: got {0}, allowed values: add, ls, remove', PACKAGING: 'Packaging -> {0}', PACKAGED: 'Packaged -> {0}', PACKAGING_COMPONENTS: 'Packaging components...', - PREVIEW_STARTED_AT_URL: 'Component\'s preview started at url: {0}', + PREVIEW_STARTED_AT_URL: "Component's preview started at url: {0}", PUBLISHED: 'Published -> {0}', PUBLISHING: 'Publishing -> {0}', REGISTERING_MOCKED_PLUGINS: 'Registering mocked plugins...', diff --git a/src/utils/date-stringify.js b/src/utils/date-stringify.js index 31d175203..991def5b7 100644 --- a/src/utils/date-stringify.js +++ b/src/utils/date-stringify.js @@ -2,10 +2,21 @@ const padZero = require('./pad-zero'); -module.exports = (date) => { - if(date instanceof Date) { - return date.getFullYear() + '/' + padZero(2, date.getMonth() + 1) + '/' + padZero(2, date.getDate()) + - ' ' + padZero(2, date.getHours()) + ':' + padZero(2, date.getMinutes()) + ':' + padZero(2, date.getSeconds()); +module.exports = date => { + if (date instanceof Date) { + return ( + date.getFullYear() + + '/' + + padZero(2, date.getMonth() + 1) + + '/' + + padZero(2, date.getDate()) + + ' ' + + padZero(2, date.getHours()) + + ':' + + padZero(2, date.getMinutes()) + + ':' + + padZero(2, date.getSeconds()) + ); } return ''; diff --git a/src/utils/get-file-info.js b/src/utils/get-file-info.js index 7e45519d2..f99208f8f 100644 --- a/src/utils/get-file-info.js +++ b/src/utils/get-file-info.js @@ -4,11 +4,11 @@ const path = require('path'); const getMimeType = require('./get-mime-type'); -module.exports = function(filePath){ +module.exports = function(filePath) { let ext = path.extname(filePath).toLowerCase(), isGzipped = false; - if(ext === '.gz'){ + if (ext === '.gz') { isGzipped = true; ext = path.extname(filePath.slice(0, -3)).toLowerCase(); } diff --git a/src/utils/get-mime-type.js b/src/utils/get-mime-type.js index aad47bd03..fe6498a59 100644 --- a/src/utils/get-mime-type.js +++ b/src/utils/get-mime-type.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = function(extension){ +module.exports = function(extension) { return { '.js': 'application/javascript', '.css': 'text/css', diff --git a/src/utils/get-next-year.js b/src/utils/get-next-year.js index b01dcc421..7377bc86f 100644 --- a/src/utils/get-next-year.js +++ b/src/utils/get-next-year.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = function(){ - return new Date((new Date()).setYear((new Date()).getFullYear() + 1)); +module.exports = function() { + return new Date(new Date().setYear(new Date().getFullYear() + 1)); }; diff --git a/src/utils/get-unix-utc-timestamp.js b/src/utils/get-unix-utc-timestamp.js index ad2ea46d6..339499ad6 100644 --- a/src/utils/get-unix-utc-timestamp.js +++ b/src/utils/get-unix-utc-timestamp.js @@ -1,8 +1,16 @@ 'use strict'; -module.exports = function(){ +module.exports = function() { const d1 = new Date(), - d2 = new Date(d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds(), d1.getUTCMilliseconds()); + d2 = new Date( + d1.getUTCFullYear(), + d1.getUTCMonth(), + d1.getUTCDate(), + d1.getUTCHours(), + d1.getUTCMinutes(), + d1.getUTCSeconds(), + d1.getUTCMilliseconds() + ); return Math.floor(d2.getTime()); }; diff --git a/src/utils/hash-builder.js b/src/utils/hash-builder.js index 7d4e363b1..3753a69c5 100644 --- a/src/utils/hash-builder.js +++ b/src/utils/hash-builder.js @@ -3,7 +3,7 @@ const crypto = require('crypto'); module.exports = { - fromString: function(content){ + fromString: function(content) { const shasum = crypto.createHash('sha1'); shasum.update(content); return shasum.digest('hex'); diff --git a/src/utils/pad-zero.js b/src/utils/pad-zero.js index aeb370540..b3c475049 100644 --- a/src/utils/pad-zero.js +++ b/src/utils/pad-zero.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = function(length, data){ +module.exports = function(length, data) { return Array(length - String(data).length + 1).join('0') + data; }; diff --git a/src/utils/put.js b/src/utils/put.js index 613000fb8..7b04074df 100644 --- a/src/utils/put.js +++ b/src/utils/put.js @@ -7,8 +7,7 @@ const url = require('url'); const _ = require('lodash'); module.exports = function(urlPath, files, headers, callback) { - - if(_.isFunction(headers)){ + if (_.isFunction(headers)) { callback = headers; headers = {}; } @@ -18,11 +17,11 @@ module.exports = function(urlPath, files, headers, callback) { let body = '', callbackDone = false; - if(!_.isArray(files)){ + if (!_.isArray(files)) { files = [files]; } - _.forEach(files, (file) => { + _.forEach(files, file => { const fileName = path.basename(file); form.append(fileName, fs.createReadStream(file)); }); @@ -30,21 +29,20 @@ module.exports = function(urlPath, files, headers, callback) { options.headers = _.extend(headers, form.getHeaders()); form.submit(options, (err, res) => { - - if(err){ + if (err) { callbackDone = true; return callback(err); } - res.on('data', (chunk) => { + res.on('data', chunk => { body += chunk; }); res.on('end', () => { - if(!callbackDone){ + if (!callbackDone) { callbackDone = true; - if(res.statusCode !== 200){ + if (res.statusCode !== 200) { callback(body); } else { callback(null, body); diff --git a/src/utils/require-template.js b/src/utils/require-template.js index 2cec862f6..2b608e7e0 100644 --- a/src/utils/require-template.js +++ b/src/utils/require-template.js @@ -4,25 +4,27 @@ const format = require('stringformat'); const path = require('path'); const templateNotFound = 'Error requiring oc-template: "{0}" not found'; -const templateNotValid = 'Error requiring oc-template: "{0}" is not a valid oc-template'; +const templateNotValid = + 'Error requiring oc-template: "{0}" is not a valid oc-template'; -function isValidTemplate(template){ +function isValidTemplate(template) { if (typeof template !== 'object') { return false; } - return [ - 'getInfo', - 'getCompiledTemplate', - 'compile', - 'render' - ].every((method) => template[method]); + return ['getInfo', 'getCompiledTemplate', 'compile', 'render'].every( + method => template[method] + ); } - module.exports = function(template) { let ocTemplate; - const localTemplate = path.join(__dirname, '../../', 'node_modules', template); + const localTemplate = path.join( + __dirname, + '../../', + 'node_modules', + template + ); const relativeTemplate = path.resolve('.', 'node_modules', template); try { @@ -30,7 +32,7 @@ module.exports = function(template) { delete require.cache[localTemplate]; } ocTemplate = require(localTemplate); - } catch(err) { + } catch (err) { try { if (require.cache && !!require.cache[relativeTemplate]) { delete require.cache[relativeTemplate]; From d8933155d3b95b97018274e3dca86515c3fec1dc Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 8 Jun 2017 11:54:08 +0100 Subject: [PATCH 2/3] removing eslint from test task as we run eslint-prettier now --- Gruntfile.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ca9de5799..031d82d1d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -2,16 +2,15 @@ const _ = require('lodash'); -module.exports = function(grunt){ - +module.exports = function(grunt) { const taskObject = { pkg: grunt.file.readJSON('package.json') }; - grunt.file.expand('tasks/*.js', '!tasks/_*.js').forEach((file) => { + grunt.file.expand('tasks/*.js', '!tasks/_*.js').forEach(file => { let name = file.split('/'); name = name[name.length - 1].replace('.js', ''); const task = require('./' + file); - if(_.isFunction(task)) { + if (_.isFunction(task)) { task(grunt); } else { taskObject[name] = task; @@ -22,10 +21,14 @@ module.exports = function(grunt){ require('load-grunt-tasks')(grunt); grunt.registerTask('default', ['test-local', 'build']); - grunt.registerTask('sauce', ['karma:sauce-linux', 'karma:sauce-osx', 'karma:sauce-windows']); - grunt.registerTask('test-local', ['eslint', 'mochaTest:all', 'karma:local']); - grunt.registerTask('test-local-silent', ['eslint', 'mochaTest:silent', 'karma:local']); - grunt.registerTask('test', ['eslint', 'mochaTest:all']); + grunt.registerTask('sauce', [ + 'karma:sauce-linux', + 'karma:sauce-osx', + 'karma:sauce-windows' + ]); + grunt.registerTask('test-local', ['mochaTest:all', 'karma:local']); + grunt.registerTask('test-local-silent', ['mochaTest:silent', 'karma:local']); + grunt.registerTask('test', ['mochaTest:all']); grunt.registerTask('git-stage', [ 'gitadd:versionFiles', 'gitcommit:version', From 8a1dd2a696b98cb183fc367901c1295bf9b83710 Mon Sep 17 00:00:00 2001 From: Nick Balestra Date: Thu, 8 Jun 2017 12:22:21 +0100 Subject: [PATCH 3/3] removed grunt-eslint dep --- package.json | 1 - tasks/eslint.js | 5 ----- 2 files changed, 6 deletions(-) delete mode 100644 tasks/eslint.js diff --git a/package.json b/package.json index f739ee54c..a0b800c39 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "chai": "3.5.0", "cheerio": "0.22.0", "grunt": "^1.0.1", - "grunt-eslint": "^19.0.0", "grunt-git": "^1.0.0", "grunt-karma": "^2.0.0", "grunt-mocha-test": "^0.12.7", diff --git a/tasks/eslint.js b/tasks/eslint.js deleted file mode 100644 index 4ddf3fad4..000000000 --- a/tasks/eslint.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - target: ['.'] -};