aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers/decache.ts
blob: 08ab545e42aab664d479bdf87163467f98cbc74d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 as { [ id: string ]: string[] }

  Object.keys(pathCache).forEach(function (cacheKey) {
    if (cacheKey.includes(pluginPath)) {
      delete pathCache[cacheKey]
    }
  })
}