From b3dda3b11c23f36942d283c0974a3664268f6242 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 19 Jan 2021 16:37:12 +0000 Subject: [PATCH] lint: src/static/js/pluginfw/*.js --- src/static/js/pluginfw/hooks.js | 56 ++++++++++----------- src/static/js/pluginfw/installer.js | 72 ++++++++++++++------------- src/static/js/pluginfw/plugin_defs.js | 2 + src/static/js/pluginfw/plugins.js | 51 ++++++++----------- src/static/js/pluginfw/shared.js | 34 +++++++------ 5 files changed, 109 insertions(+), 106 deletions(-) diff --git a/src/static/js/pluginfw/hooks.js b/src/static/js/pluginfw/hooks.js index 6243a930..e61079eb 100644 --- a/src/static/js/pluginfw/hooks.js +++ b/src/static/js/pluginfw/hooks.js @@ -1,4 +1,4 @@ -/* global exports, require */ +'use strict'; const _ = require('underscore'); const pluginDefs = require('./plugin_defs'); @@ -15,30 +15,28 @@ exports.deprecationNotices = {}; const deprecationWarned = {}; -function checkDeprecation(hook) { +const checkDeprecation = (hook) => { const notice = exports.deprecationNotices[hook.hook_name]; if (notice == null) return; if (deprecationWarned[hook.hook_fn_name]) return; console.warn(`${hook.hook_name} hook used by the ${hook.part.plugin} plugin ` + `(${hook.hook_fn_name}) is deprecated: ${notice}`); deprecationWarned[hook.hook_fn_name] = true; -} +}; exports.bubbleExceptions = true; -const hookCallWrapper = function (hook, hook_name, args, cb) { - if (cb === undefined) cb = function (x) { return x; }; +const hookCallWrapper = (hook, hook_name, args, cb) => { + if (cb === undefined) cb = (x) => x; checkDeprecation(hook); // Normalize output to list for both sync and async cases - const normalize = function (x) { + const normalize = (x) => { if (x === undefined) return []; return x; }; - const normalizedhook = function () { - return normalize(hook.hook_fn(hook_name, args, (x) => cb(normalize(x)))); - }; + const normalizedhook = () => normalize(hook.hook_fn(hook_name, args, (x) => cb(normalize(x)))); if (exports.bubbleExceptions) { return normalizedhook(); @@ -51,7 +49,7 @@ const hookCallWrapper = function (hook, hook_name, args, cb) { } }; -exports.syncMapFirst = function (lst, fn) { +exports.syncMapFirst = (lst, fn) => { let i; let result; for (i = 0; i < lst.length; i++) { @@ -61,11 +59,11 @@ exports.syncMapFirst = function (lst, fn) { return []; }; -exports.mapFirst = function (lst, fn, cb, predicate) { +exports.mapFirst = (lst, fn, cb, predicate) => { if (predicate == null) predicate = (x) => (x != null && x.length > 0); let i = 0; - var next = function () { + const next = () => { if (i >= lst.length) return cb(null, []); fn(lst[i++], (err, result) => { if (err) return cb(err); @@ -104,7 +102,7 @@ exports.mapFirst = function (lst, fn, cb, predicate) { // // See the tests in tests/backend/specs/hooks.js for examples of supported and prohibited behaviors. // -function callHookFnSync(hook, context) { +const callHookFnSync = (hook, context) => { checkDeprecation(hook); // This var is used to keep track of whether the hook function already settled. @@ -190,7 +188,7 @@ function callHookFnSync(hook, context) { settle(null, val, 'returned value'); return outcome.val; -} +}; // Invokes all registered hook functions synchronously. // @@ -203,7 +201,7 @@ function callHookFnSync(hook, context) { // 1. Collect all values returned by the hook functions into an array. // 2. Convert each `undefined` entry into `[]`. // 3. Flatten one level. -exports.callAll = function (hookName, context) { +exports.callAll = (hookName, context) => { if (context == null) context = {}; const hooks = pluginDefs.hooks[hookName] || []; return _.flatten(hooks.map((hook) => { @@ -248,7 +246,7 @@ exports.callAll = function (hookName, context) { // // See the tests in tests/backend/specs/hooks.js for examples of supported and prohibited behaviors. // -async function callHookFnAsync(hook, context) { +const callHookFnAsync = async (hook, context) => { checkDeprecation(hook); return await new Promise((resolve, reject) => { // This var is used to keep track of whether the hook function already settled. @@ -326,7 +324,7 @@ async function callHookFnAsync(hook, context) { (val) => settle(null, val, 'returned value'), (err) => settle(err, null, 'Promise rejection')); }); -} +}; // Invokes all registered hook functions asynchronously. // @@ -350,20 +348,22 @@ exports.aCallAll = async (hookName, context, cb) => { const hooks = pluginDefs.hooks[hookName] || []; let resultsPromise = Promise.all(hooks.map((hook) => callHookFnAsync(hook, context) // `undefined` (but not `null`!) is treated the same as []. - .then((result) => (result === undefined) ? [] : result))).then((results) => _.flatten(results, 1)); + .then((result) => (result === undefined) ? [] : result))) + .then((results) => _.flatten(results, 1)); if (cb != null) resultsPromise = resultsPromise.then((val) => cb(null, val), cb); return await resultsPromise; }; -exports.callFirst = function (hook_name, args) { +exports.callFirst = (hook_name, args) => { if (!args) args = {}; if (pluginDefs.hooks[hook_name] === undefined) return []; - return exports.syncMapFirst(pluginDefs.hooks[hook_name], (hook) => hookCallWrapper(hook, hook_name, args)); + return exports.syncMapFirst(pluginDefs.hooks[hook_name], + (hook) => hookCallWrapper(hook, hook_name, args)); }; -function aCallFirst(hook_name, args, cb, predicate) { +const aCallFirst = (hook_name, args, cb, predicate) => { if (!args) args = {}; - if (!cb) cb = function () {}; + if (!cb) cb = () => {}; if (pluginDefs.hooks[hook_name] === undefined) return cb(null, []); exports.mapFirst( pluginDefs.hooks[hook_name], @@ -373,10 +373,10 @@ function aCallFirst(hook_name, args, cb, predicate) { cb, predicate ); -} +}; /* return a Promise if cb is not supplied */ -exports.aCallFirst = function (hook_name, args, cb, predicate) { +exports.aCallFirst = (hook_name, args, cb, predicate) => { if (cb === undefined) { return new Promise((resolve, reject) => { aCallFirst(hook_name, args, (err, res) => err ? reject(err) : resolve(res), predicate); @@ -386,10 +386,10 @@ exports.aCallFirst = function (hook_name, args, cb, predicate) { } }; -exports.callAllStr = function (hook_name, args, sep, pre, post) { - if (sep == undefined) sep = ''; - if (pre == undefined) pre = ''; - if (post == undefined) post = ''; +exports.callAllStr = (hook_name, args, sep, pre, post) => { + if (sep === undefined) sep = ''; + if (pre === undefined) pre = ''; + if (post === undefined) post = ''; const newCallhooks = []; const callhooks = exports.callAll(hook_name, args); for (let i = 0, ii = callhooks.length; i < ii; i++) { diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js index 7d29b91b..ae5c06e1 100644 --- a/src/static/js/pluginfw/installer.js +++ b/src/static/js/pluginfw/installer.js @@ -1,6 +1,8 @@ +'use strict'; + const log4js = require('log4js'); -const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); -const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); +const plugins = require('./plugins'); +const hooks = require('./hooks'); const npm = require('npm'); const request = require('request'); const util = require('util'); @@ -13,22 +15,22 @@ const loadNpm = async () => { npm.on('log', log4js.getLogger('npm').log); }; +const onAllTasksFinished = () => { + hooks.aCallAll('restartServer', {}, () => {}); +}; + let tasks = 0; function wrapTaskCb(cb) { tasks++; - return function () { - cb && cb.apply(this, arguments); + return function (...args) { + cb && cb.apply(this, args); tasks--; - if (tasks == 0) onAllTasksFinished(); + if (tasks === 0) onAllTasksFinished(); }; } -function onAllTasksFinished() { - hooks.aCallAll('restartServer', {}, () => {}); -} - exports.uninstall = async (pluginName, cb = null) => { cb = wrapTaskCb(cb); try { @@ -60,7 +62,7 @@ exports.install = async (pluginName, cb = null) => { exports.availablePlugins = null; let cacheTimestamp = 0; -exports.getAvailablePlugins = function (maxCacheAge) { +exports.getAvailablePlugins = (maxCacheAge) => { const nowTimestamp = Math.round(Date.now() / 1000); return new Promise((resolve, reject) => { @@ -87,31 +89,33 @@ exports.getAvailablePlugins = function (maxCacheAge) { }; -exports.search = function (searchTerm, maxCacheAge) { - return exports.getAvailablePlugins(maxCacheAge).then((results) => { - const res = {}; +exports.search = (searchTerm, maxCacheAge) => exports.getAvailablePlugins(maxCacheAge).then( + (results) => { + const res = {}; - if (searchTerm) { - searchTerm = searchTerm.toLowerCase(); - } - - for (const pluginName in results) { - // for every available plugin - if (pluginName.indexOf(plugins.prefix) != 0) continue; // TODO: Also search in keywords here! - - if (searchTerm && !~results[pluginName].name.toLowerCase().indexOf(searchTerm) && - (typeof results[pluginName].description !== 'undefined' && !~results[pluginName].description.toLowerCase().indexOf(searchTerm)) - ) { - if (typeof results[pluginName].description === 'undefined') { - console.debug('plugin without Description: %s', results[pluginName].name); - } - - continue; + if (searchTerm) { + searchTerm = searchTerm.toLowerCase(); } - res[pluginName] = results[pluginName]; - } + for (const pluginName in results) { + // for every available plugin + // TODO: Also search in keywords here! + if (pluginName.indexOf(plugins.prefix) !== 0) continue; - return res; - }); -}; + if (searchTerm && !~results[pluginName].name.toLowerCase().indexOf(searchTerm) && + (typeof results[pluginName].description !== 'undefined' && + !~results[pluginName].description.toLowerCase().indexOf(searchTerm)) + ) { + if (typeof results[pluginName].description === 'undefined') { + console.debug('plugin without Description: %s', results[pluginName].name); + } + + continue; + } + + res[pluginName] = results[pluginName]; + } + + return res; + } +); diff --git a/src/static/js/pluginfw/plugin_defs.js b/src/static/js/pluginfw/plugin_defs.js index 95bbcb95..768d99c3 100644 --- a/src/static/js/pluginfw/plugin_defs.js +++ b/src/static/js/pluginfw/plugin_defs.js @@ -1,3 +1,5 @@ +'use strict'; + // This module contains processed plugin definitions. The data structures in this file are set by // plugins.js (server) or client_plugins.js (client). diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js index 52fbdd27..4acdee7b 100644 --- a/src/static/js/pluginfw/plugins.js +++ b/src/static/js/pluginfw/plugins.js @@ -1,6 +1,7 @@ +'use strict'; + const fs = require('fs').promises; const hooks = require('./hooks'); -const npm = require('npm/lib/npm.js'); const readInstalled = require('./read-installed.js'); const path = require('path'); const tsort = require('./tsort'); @@ -13,11 +14,9 @@ const defs = require('./plugin_defs'); exports.prefix = 'ep_'; -exports.formatPlugins = function () { - return _.keys(defs.plugins).join(', '); -}; +exports.formatPlugins = () => Object.keys(defs.plugins).join(', '); -exports.formatPluginsWithVersion = function () { +exports.formatPluginsWithVersion = () => { const plugins = []; _.forEach(defs.plugins, (plugin) => { if (plugin.package.name !== 'ep_etherpad-lite') { @@ -28,17 +27,16 @@ exports.formatPluginsWithVersion = function () { return plugins.join(', '); }; -exports.formatParts = function () { - return _.map(defs.parts, (part) => part.full_name).join('\n'); -}; +exports.formatParts = () => _.map(defs.parts, (part) => part.full_name).join('\n'); -exports.formatHooks = function (hook_set_name) { +exports.formatHooks = (hook_set_name) => { const res = []; const hooks = pluginUtils.extractHooks(defs.parts, hook_set_name || 'hooks'); _.chain(hooks).keys().forEach((hook_name) => { _.forEach(hooks[hook_name], (hook) => { - res.push(`
${hook.hook_name}
${hook.hook_fn_name} from ${hook.part.full_name}
`); + res.push(`
${hook.hook_name}
${hook.hook_fn_name} ` + + `from ${hook.part.full_name}
`); }); }); return `
${res.join('\n')}
`; @@ -57,7 +55,7 @@ const callInit = async () => { })); }; -exports.pathNormalization = function (part, hook_fn_name, hook_name) { +exports.pathNormalization = (part, hook_fn_name, hook_name) => { const tmp = hook_fn_name.split(':'); // hook_fn_name might be something like 'C:\\foo.js:myFunc'. // If there is a single colon assume it's 'filename:funcname' not 'C:\\filename'. const functionName = (tmp.length > 1 ? tmp.pop() : null) || hook_name; @@ -67,7 +65,7 @@ exports.pathNormalization = function (part, hook_fn_name, hook_name) { return `${fileName}:${functionName}`; }; -exports.update = async function () { +exports.update = async () => { const packages = await exports.getPackages(); const parts = {}; // Key is full name. sortParts converts this into a topologically sorted array. const plugins = {}; @@ -83,13 +81,14 @@ exports.update = async function () { await callInit(); }; -exports.getPackages = async function () { - // Load list of installed NPM packages, flatten it to a list, and filter out only packages with names that +exports.getPackages = async () => { + // Load list of installed NPM packages, flatten it to a list, + // and filter out only packages with names that const dir = settings.root; const data = await util.promisify(readInstalled)(dir); const packages = {}; - function flatten(deps) { + const flatten = (deps) => { _.chain(deps).keys().each((name) => { if (name.indexOf(exports.prefix) === 0) { packages[name] = _.clone(deps[name]); @@ -102,7 +101,7 @@ exports.getPackages = async function () { // I don't think we need recursion // if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies); }); - } + }; const tmp = {}; tmp[data.name] = data; @@ -110,7 +109,7 @@ exports.getPackages = async function () { return packages; }; -async function loadPlugin(packages, plugin_name, plugins, parts) { +const loadPlugin = async (packages, plugin_name, plugins, parts) => { const plugin_path = path.resolve(packages[plugin_name].path, 'ep.json'); try { const data = await fs.readFile(plugin_path); @@ -129,9 +128,9 @@ async function loadPlugin(packages, plugin_name, plugins, parts) { } catch (er) { console.error(`Unable to load plugin definition file ${plugin_path}`); } -} +}; -function partsToParentChildList(parts) { +const partsToParentChildList = (parts) => { const res = []; _.chain(parts).keys().forEach((name) => { _.each(parts[name].post || [], (child_name) => { @@ -145,15 +144,9 @@ function partsToParentChildList(parts) { } }); return res; -} +}; // Used only in Node, so no need for _ -function sortParts(parts) { - return tsort( - partsToParentChildList(parts) - ).filter( - (name) => parts[name] !== undefined - ).map( - (name) => parts[name] - ); -} +const sortParts = (parts) => tsort(partsToParentChildList(parts)) + .filter((name) => parts[name] !== undefined) + .map((name) => parts[name]); diff --git a/src/static/js/pluginfw/shared.js b/src/static/js/pluginfw/shared.js index 74970681..981cd255 100644 --- a/src/static/js/pluginfw/shared.js +++ b/src/static/js/pluginfw/shared.js @@ -1,3 +1,4 @@ +'use strict'; const _ = require('underscore'); const defs = require('./plugin_defs'); @@ -8,13 +9,13 @@ const disabledHookReasons = { }, }; -function loadFn(path, hookName) { +const loadFn = (path, hookName) => { let functionName; const parts = path.split(':'); // on windows: C:\foo\bar:xyz - if (parts[0].length == 1) { - if (parts.length == 3) { + if (parts[0].length === 1) { + if (parts.length === 3) { functionName = parts.pop(); } path = parts.join(':'); @@ -30,9 +31,9 @@ function loadFn(path, hookName) { fn = fn[name]; }); return fn; -} +}; -function extractHooks(parts, hook_set_name, normalizer) { +const extractHooks = (parts, hook_set_name, normalizer) => { const hooks = {}; _.each(parts, (part) => { _.chain(part[hook_set_name] || {}) @@ -50,20 +51,23 @@ function extractHooks(parts, hook_set_name, normalizer) { const disabledReason = (disabledHookReasons[hook_set_name] || {})[hook_name]; if (disabledReason) { - console.error(`Hook ${hook_set_name}/${hook_name} is disabled. Reason: ${disabledReason}`); + console.error( + `Hook ${hook_set_name}/${hook_name} is disabled. Reason: ${disabledReason}`); console.error(`The hook function ${hook_fn_name} from plugin ${part.plugin} ` + - 'will never be called, which may cause the plugin to fail'); - console.error(`Please update the ${part.plugin} plugin to not use the ${hook_name} hook`); + 'will never be called, which may cause the plugin to fail'); + console.error( + `Please update the ${part.plugin} plugin to not use the ${hook_name} hook`); return; } - + let hook_fn; try { - var hook_fn = loadFn(hook_fn_name, hook_name); + hook_fn = loadFn(hook_fn_name, hook_name); if (!hook_fn) { - throw 'Not a function'; + throw new Error('Not a function'); } } catch (exc) { - console.error(`Failed to load '${hook_fn_name}' for '${part.full_name}/${hook_set_name}/${hook_name}': ${exc.toString()}`); + console.error(`Failed to load '${hook_fn_name}' for ` + + `'${part.full_name}/${hook_set_name}/${hook_name}': ${exc.toString()}`); } if (hook_fn) { if (hooks[hook_name] == null) hooks[hook_name] = []; @@ -72,7 +76,7 @@ function extractHooks(parts, hook_set_name, normalizer) { }); }); return hooks; -} +}; exports.extractHooks = extractHooks; @@ -88,10 +92,10 @@ exports.extractHooks = extractHooks; * No plugins: [] * Some plugins: [ 'ep_adminpads', 'ep_add_buttons', 'ep_activepads' ] */ -exports.clientPluginNames = function () { +exports.clientPluginNames = () => { const client_plugin_names = _.uniq( defs.parts - .filter((part) => part.hasOwnProperty('client_hooks')) + .filter((part) => Object.prototype.hasOwnProperty.call(part, 'client_hooks')) .map((part) => `plugin-${part.plugin}`) );