linting: easy lints

This commit is contained in:
John McLear 2021-01-19 19:07:20 +00:00
parent f6661d41be
commit 43490df113
5 changed files with 82 additions and 72 deletions

View file

@ -1,4 +1,4 @@
/* global exports, require */ 'use strict';
const _ = require('underscore'); const _ = require('underscore');
const pluginDefs = require('./plugin_defs'); const pluginDefs = require('./plugin_defs');
@ -15,30 +15,28 @@ exports.deprecationNotices = {};
const deprecationWarned = {}; const deprecationWarned = {};
function checkDeprecation(hook) { const checkDeprecation = (hook) => {
const notice = exports.deprecationNotices[hook.hook_name]; const notice = exports.deprecationNotices[hook.hook_name];
if (notice == null) return; if (notice == null) return;
if (deprecationWarned[hook.hook_fn_name]) return; if (deprecationWarned[hook.hook_fn_name]) return;
console.warn(`${hook.hook_name} hook used by the ${hook.part.plugin} plugin ` + console.warn(`${hook.hook_name} hook used by the ${hook.part.plugin} plugin ` +
`(${hook.hook_fn_name}) is deprecated: ${notice}`); `(${hook.hook_fn_name}) is deprecated: ${notice}`);
deprecationWarned[hook.hook_fn_name] = true; deprecationWarned[hook.hook_fn_name] = true;
} };
exports.bubbleExceptions = true; exports.bubbleExceptions = true;
const hookCallWrapper = function (hook, hook_name, args, cb) { const hookCallWrapper = (hook, hook_name, args, cb) => {
if (cb === undefined) cb = function (x) { return x; }; if (cb === undefined) cb = (x) => x;
checkDeprecation(hook); checkDeprecation(hook);
// Normalize output to list for both sync and async cases // Normalize output to list for both sync and async cases
const normalize = function (x) { const normalize = (x) => {
if (x === undefined) return []; if (x === undefined) return [];
return x; return x;
}; };
const normalizedhook = function () { const normalizedhook = () => normalize(hook.hook_fn(hook_name, args, (x) => cb(normalize(x))));
return normalize(hook.hook_fn(hook_name, args, (x) => cb(normalize(x))));
};
if (exports.bubbleExceptions) { if (exports.bubbleExceptions) {
return normalizedhook(); 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 i;
let result; let result;
for (i = 0; i < lst.length; i++) { for (i = 0; i < lst.length; i++) {
@ -61,11 +59,11 @@ exports.syncMapFirst = function (lst, fn) {
return []; return [];
}; };
exports.mapFirst = function (lst, fn, cb, predicate) { exports.mapFirst = (lst, fn, cb, predicate) => {
if (predicate == null) predicate = (x) => (x != null && x.length > 0); if (predicate == null) predicate = (x) => (x != null && x.length > 0);
let i = 0; let i = 0;
var next = function () { const next = () => {
if (i >= lst.length) return cb(null, []); if (i >= lst.length) return cb(null, []);
fn(lst[i++], (err, result) => { fn(lst[i++], (err, result) => {
if (err) return cb(err); 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. // 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); checkDeprecation(hook);
// This var is used to keep track of whether the hook function already settled. // 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'); settle(null, val, 'returned value');
return outcome.val; return outcome.val;
} };
// Invokes all registered hook functions synchronously. // 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. // 1. Collect all values returned by the hook functions into an array.
// 2. Convert each `undefined` entry into `[]`. // 2. Convert each `undefined` entry into `[]`.
// 3. Flatten one level. // 3. Flatten one level.
exports.callAll = function (hookName, context) { exports.callAll = (hookName, context) => {
if (context == null) context = {}; if (context == null) context = {};
const hooks = pluginDefs.hooks[hookName] || []; const hooks = pluginDefs.hooks[hookName] || [];
return _.flatten(hooks.map((hook) => { 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. // 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); checkDeprecation(hook);
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
// This var is used to keep track of whether the hook function already settled. // 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'), (val) => settle(null, val, 'returned value'),
(err) => settle(err, null, 'Promise rejection')); (err) => settle(err, null, 'Promise rejection'));
}); });
} };
// Invokes all registered hook functions asynchronously. // Invokes all registered hook functions asynchronously.
// //
@ -350,20 +348,22 @@ exports.aCallAll = async (hookName, context, cb) => {
const hooks = pluginDefs.hooks[hookName] || []; const hooks = pluginDefs.hooks[hookName] || [];
let resultsPromise = Promise.all(hooks.map((hook) => callHookFnAsync(hook, context) let resultsPromise = Promise.all(hooks.map((hook) => callHookFnAsync(hook, context)
// `undefined` (but not `null`!) is treated the same as []. // `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); if (cb != null) resultsPromise = resultsPromise.then((val) => cb(null, val), cb);
return await resultsPromise; return await resultsPromise;
}; };
exports.callFirst = function (hook_name, args) { exports.callFirst = (hook_name, args) => {
if (!args) args = {}; if (!args) args = {};
if (pluginDefs.hooks[hook_name] === undefined) return []; 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 (!args) args = {};
if (!cb) cb = function () {}; if (!cb) cb = () => {};
if (pluginDefs.hooks[hook_name] === undefined) return cb(null, []); if (pluginDefs.hooks[hook_name] === undefined) return cb(null, []);
exports.mapFirst( exports.mapFirst(
pluginDefs.hooks[hook_name], pluginDefs.hooks[hook_name],
@ -373,10 +373,10 @@ function aCallFirst(hook_name, args, cb, predicate) {
cb, cb,
predicate predicate
); );
} };
/* return a Promise if cb is not supplied */ /* 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) { if (cb === undefined) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
aCallFirst(hook_name, args, (err, res) => err ? reject(err) : resolve(res), predicate); 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) { exports.callAllStr = (hook_name, args, sep, pre, post) => {
if (sep == undefined) sep = ''; if (sep === undefined) sep = '';
if (pre == undefined) pre = ''; if (pre === undefined) pre = '';
if (post == undefined) post = ''; if (post === undefined) post = '';
const newCallhooks = []; const newCallhooks = [];
const callhooks = exports.callAll(hook_name, args); const callhooks = exports.callAll(hook_name, args);
for (let i = 0, ii = callhooks.length; i < ii; i++) { for (let i = 0, ii = callhooks.length; i < ii; i++) {

View file

@ -1,3 +1,5 @@
'use strict';
const log4js = require('log4js'); const log4js = require('log4js');
const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); const plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins');
const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
@ -13,6 +15,10 @@ const loadNpm = async () => {
npm.on('log', log4js.getLogger('npm').log); npm.on('log', log4js.getLogger('npm').log);
}; };
const onAllTasksFinished = () => {
hooks.aCallAll('restartServer', {}, () => {});
};
let tasks = 0; let tasks = 0;
function wrapTaskCb(cb) { function wrapTaskCb(cb) {
@ -21,14 +27,10 @@ function wrapTaskCb(cb) {
return function () { return function () {
cb && cb.apply(this, arguments); cb && cb.apply(this, arguments);
tasks--; tasks--;
if (tasks == 0) onAllTasksFinished(); if (tasks === 0) onAllTasksFinished();
}; };
} }
function onAllTasksFinished() {
hooks.aCallAll('restartServer', {}, () => {});
}
exports.uninstall = async (pluginName, cb = null) => { exports.uninstall = async (pluginName, cb = null) => {
cb = wrapTaskCb(cb); cb = wrapTaskCb(cb);
try { try {
@ -60,7 +62,7 @@ exports.install = async (pluginName, cb = null) => {
exports.availablePlugins = null; exports.availablePlugins = null;
let cacheTimestamp = 0; let cacheTimestamp = 0;
exports.getAvailablePlugins = function (maxCacheAge) { exports.getAvailablePlugins = (maxCacheAge) => {
const nowTimestamp = Math.round(Date.now() / 1000); const nowTimestamp = Math.round(Date.now() / 1000);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -87,31 +89,33 @@ exports.getAvailablePlugins = function (maxCacheAge) {
}; };
exports.search = function (searchTerm, maxCacheAge) { exports.search = (searchTerm, maxCacheAge) => exports.getAvailablePlugins(maxCacheAge).then(
return exports.getAvailablePlugins(maxCacheAge).then((results) => { (results) => {
const res = {}; const res = {};
if (searchTerm) { if (searchTerm) {
searchTerm = searchTerm.toLowerCase(); 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;
} }
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;
}
);

View file

@ -1,3 +1,5 @@
'use strict';
// This module contains processed plugin definitions. The data structures in this file are set by // This module contains processed plugin definitions. The data structures in this file are set by
// plugins.js (server) or client_plugins.js (client). // plugins.js (server) or client_plugins.js (client).

View file

@ -1,3 +1,4 @@
'use strict';
const _ = require('underscore'); const _ = require('underscore');
const defs = require('./plugin_defs'); const defs = require('./plugin_defs');
@ -8,13 +9,13 @@ const disabledHookReasons = {
}, },
}; };
function loadFn(path, hookName) { const loadFn = (path, hookName) => {
let functionName; let functionName;
const parts = path.split(':'); const parts = path.split(':');
// on windows: C:\foo\bar:xyz // on windows: C:\foo\bar:xyz
if (parts[0].length == 1) { if (parts[0].length === 1) {
if (parts.length == 3) { if (parts.length === 3) {
functionName = parts.pop(); functionName = parts.pop();
} }
path = parts.join(':'); path = parts.join(':');
@ -30,9 +31,9 @@ function loadFn(path, hookName) {
fn = fn[name]; fn = fn[name];
}); });
return fn; return fn;
} };
function extractHooks(parts, hook_set_name, normalizer) { const extractHooks = (parts, hook_set_name, normalizer) => {
const hooks = {}; const hooks = {};
_.each(parts, (part) => { _.each(parts, (part) => {
_.chain(part[hook_set_name] || {}) _.chain(part[hook_set_name] || {})
@ -50,20 +51,23 @@ function extractHooks(parts, hook_set_name, normalizer) {
const disabledReason = (disabledHookReasons[hook_set_name] || {})[hook_name]; const disabledReason = (disabledHookReasons[hook_set_name] || {})[hook_name];
if (disabledReason) { 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} ` + console.error(`The hook function ${hook_fn_name} from plugin ${part.plugin} ` +
'will never be called, which may cause the plugin to fail'); '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`); console.error(`Please update the ${part.plugin} plugin to not
use the ${hook_name} hook`);
return; return;
} }
let hook_fn;
try { try {
var hook_fn = loadFn(hook_fn_name, hook_name); hook_fn = loadFn(hook_fn_name, hook_name);
if (!hook_fn) { if (!hook_fn) {
throw 'Not a function'; throw new Error('Not a function');
} }
} catch (exc) { } 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 (hook_fn) {
if (hooks[hook_name] == null) hooks[hook_name] = []; if (hooks[hook_name] == null) hooks[hook_name] = [];
@ -72,7 +76,7 @@ function extractHooks(parts, hook_set_name, normalizer) {
}); });
}); });
return hooks; return hooks;
} };
exports.extractHooks = extractHooks; exports.extractHooks = extractHooks;
@ -88,7 +92,7 @@ exports.extractHooks = extractHooks;
* No plugins: [] * No plugins: []
* Some plugins: [ 'ep_adminpads', 'ep_add_buttons', 'ep_activepads' ] * Some plugins: [ 'ep_adminpads', 'ep_add_buttons', 'ep_activepads' ]
*/ */
exports.clientPluginNames = function () { exports.clientPluginNames = () => {
const client_plugin_names = _.uniq( const client_plugin_names = _.uniq(
defs.parts defs.parts
.filter((part) => part.hasOwnProperty('client_hooks')) .filter((part) => part.hasOwnProperty('client_hooks'))

View file

@ -55,7 +55,7 @@ const tsort = (edges) => {
Object.keys(nodes).forEach(visit); Object.keys(nodes).forEach(visit);
return sorted; return sorted;
} };
/** /**
* TEST * TEST