• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

electrode-io / electrode-native / 7592

29 Apr 2026 07:06PM UTC coverage: 56.607% (-11.2%) from 67.836%
7592

push

Azure Pipelines

web-flow
Merge pull request #1925 from electrode-io/npm-packages-security-audit-fixes

Fixed critical CVE for npm packages

3601 of 7766 branches covered (46.37%)

Branch coverage included in aggregate %.

9 of 10 new or added lines in 5 files covered. (90.0%)

1659 existing lines in 113 files now uncovered.

9426 of 15247 relevant lines covered (61.82%)

523.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.85
/ern-core/src/ModuleFactory.ts
1
import fs from 'fs-extra';
11✔
2
import path from 'path';
11✔
3
import shell from './shell';
11✔
4
import { yarn } from './clients';
11✔
5
import { PackagePath } from './PackagePath';
11✔
6
import { readPackageJson } from './packageJsonFileUtils';
11✔
7

8
export class ModuleFactory<T> {
11✔
9
  private readonly packagePrefix?: string;
10

11
  public constructor(
12
    readonly packageCachePath: string,
14✔
13
    {
14
      packagePrefix,
15
    }: {
16
      packagePrefix?: string;
17
    } = {},
4✔
18
  ) {
19
    this.packagePrefix = packagePrefix;
14✔
20
  }
21

22
  public async getModuleInstance(p: PackagePath): Promise<T> {
23
    if (!p.isFilePath && !p.isRegistryPath) {
9✔
24
      throw new Error(`Not a supported package path : ${p.toString()}`);
1✔
25
    }
26
    const pathToModule = await this.getLocalPathToPackage(p);
8✔
27
    return this.instantiateModule(pathToModule);
7✔
28
  }
29

30
  private instantiateModule(pathToModule: string): T {
UNCOV
31
    const Module = require(pathToModule).default;
×
UNCOV
32
    return new Module();
×
33
  }
34

35
  private async getLocalPathToPackage(p: PackagePath): Promise<string> {
36
    return p.isFilePath
8✔
37
      ? this.getPathToLocalPackage(p)
8✔
38
      : await this.getPathToRegistryPackage(p);
39
  }
40

41
  private getPathToLocalPackage(p: PackagePath): string {
42
    const pathWithSrc = path.join(p.basePath, 'src');
2✔
43
    return fs.pathExistsSync(pathWithSrc) ? pathWithSrc : p.basePath;
2✔
44
  }
45

46
  private async getPathToRegistryPackage(p: PackagePath): Promise<string> {
47
    if (!this.doesPackageCacheExist()) {
6!
48
      await this.createPackageCache();
6✔
49
    }
50

51
    const modulePackagePath = this.packagePrefix
6✔
52
      ? this.processPackageRegistryPath(p)
6!
53
      : p;
54
    await this.refreshCacheFor(modulePackagePath);
6✔
55

56
    return path.join(
5✔
57
      this.packageCachePath,
58
      'node_modules',
59
      modulePackagePath.basePath,
60
    );
61
  }
62

63
  private doesPackageCacheExist(): boolean {
64
    return fs.pathExistsSync(this.packageCachePath);
6✔
65
  }
66

67
  private async createPackageCache() {
68
    shell.mkdir('-p', this.packageCachePath);
6✔
69
    try {
6✔
70
      shell.pushd(this.packageCachePath);
6✔
71
      await yarn.init();
6✔
72
    } finally {
73
      shell.popd();
6✔
74
    }
75
  }
76

77
  private async refreshCacheFor(p: PackagePath) {
78
    const packageJson = await readPackageJson(this.packageCachePath);
6✔
79
    return packageJson.dependencies?.[p.basePath]
5✔
80
      ? this.upgradeCachedPackage(p)
5✔
81
      : this.addPackageToCache(p);
82
  }
83

84
  private async addPackageToCache(p: PackagePath) {
85
    shell.pushd(this.packageCachePath);
4✔
86
    try {
4✔
87
      await yarn.add(p);
4✔
88
    } finally {
89
      shell.popd();
4✔
90
    }
91
  }
92

93
  private async upgradeCachedPackage(p: PackagePath) {
94
    shell.pushd(this.packageCachePath);
1✔
95
    try {
1✔
96
      await yarn.upgrade(p);
1✔
97
    } finally {
98
      shell.popd();
1✔
99
    }
100
  }
101

102
  private processPackageRegistryPath(p: PackagePath): PackagePath {
103
    if (
6✔
104
      !p.fullPath.startsWith('@') &&
12✔
105
      !p.fullPath.startsWith(this.packagePrefix!)
106
    ) {
107
      return PackagePath.fromString(`${this.packagePrefix}${p.fullPath}`);
3✔
108
    }
109
    return p;
3✔
110
  }
111
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc