From ca87d95bcbfec9241e5840267862bace8b0197fa Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 3 Dec 2021 09:52:03 +0100 Subject: Fix plugin upgrade Correctly decache all plugin paths --- server/helpers/decache.ts | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 server/helpers/decache.ts (limited to 'server/helpers') diff --git a/server/helpers/decache.ts b/server/helpers/decache.ts new file mode 100644 index 000000000..e31973b7a --- /dev/null +++ b/server/helpers/decache.ts @@ -0,0 +1,78 @@ +// Thanks: https://github.com/dwyl/decache +// We reuse this file to also uncache plugin base path + +import { extname } from 'path' + +function decachePlugin (pluginPath: string, libraryPath: string) { + const moduleName = find(libraryPath) + + if (!moduleName) return + + searchCache(moduleName, function (mod) { + delete require.cache[mod.id] + }) + + removeCachedPath(pluginPath) +} + +function decacheModule (name: string) { + const moduleName = find(name) + + if (!moduleName) return + + searchCache(moduleName, function (mod) { + delete require.cache[mod.id] + }) + + removeCachedPath(moduleName) +} + +// --------------------------------------------------------------------------- + +export { + decacheModule, + decachePlugin +} + +// --------------------------------------------------------------------------- + +function find (moduleName: string) { + try { + return require.resolve(moduleName) + } catch { + return '' + } +} + +function searchCache (moduleName: string, callback: (current: NodeModule) => void) { + const resolvedModule = require.resolve(moduleName) + let mod: NodeModule + const visited = {} + + if (resolvedModule && ((mod = require.cache[resolvedModule]) !== undefined)) { + // Recursively go over the results + (function run (current) { + visited[current.id] = true + + current.children.forEach(function (child) { + if (extname(child.filename) !== '.node' && !visited[child.id]) { + run(child) + } + }) + + // Call the specified callback providing the + // found module + callback(current) + })(mod) + } +}; + +function removeCachedPath (pluginPath: string) { + const pathCache = (module.constructor as any)._pathCache + + Object.keys(pathCache).forEach(function (cacheKey) { + if (cacheKey.includes(pluginPath)) { + delete pathCache[cacheKey] + } + }) +} -- cgit v1.2.3