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

rokucommunity / roku-deploy / #804

pending completion
#804

push

web-flow
Bump jszip from 3.7.1 to 3.8.0

Bumps [jszip](https://github.com/Stuk/jszip) from 3.7.1 to 3.8.0.
- [Release notes](https://github.com/Stuk/jszip/releases)
- [Changelog](https://github.com/Stuk/jszip/blob/main/CHANGES.md)
- [Commits](https://github.com/Stuk/jszip/compare/v3.7.1...v3.8.0)

---
updated-dependencies:
- dependency-name: jszip
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

281 of 281 branches covered (100.0%)

Branch coverage included in aggregate %.

533 of 533 relevant lines covered (100.0%)

45.77 hits per line

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

100.0
/src/util.ts
1
/* eslint-disable */
2
import * as fsExtra from 'fs-extra';
1✔
3
import * as path from 'path';
1✔
4
import * as fs from 'fs';
1✔
5
import * as picomatch from 'picomatch';
1✔
6
import fastGlob = require("fast-glob")
1✔
7

8
export class Util {
1✔
9
    /**
10
     * Determine if `childPath` is contained within the `parentPath`
11
     * @param parentPath
12
     * @param childPath
13
     * @param standardizePaths if false, the paths are assumed to already be in the same format and are not re-standardized
14
     */
15
    public isParentOfPath(parentPath: string, childPath: string, standardizePaths = true) {
6✔
16
        if (standardizePaths) {
141✔
17
            parentPath = util.standardizePath(parentPath);
6✔
18
            childPath = util.standardizePath(childPath);
6✔
19
        }
20
        const relative = path.relative(parentPath, childPath);
141✔
21
        return relative && !relative.startsWith('..') && !path.isAbsolute(relative);
141✔
22
    }
23

24
    /**
25
     * Determines if the given path is a file
26
     * @param filePathAbsolute
27
     */
28
    public async isFile(filePathAbsolute: string) {
29
        try {
2✔
30
            //get the full path to the file. This should be the same path for files, and the actual path for any symlinks
31
            let realPathAbsolute = fs.realpathSync(filePathAbsolute);
2✔
32
            let stat = await fsExtra.lstat(realPathAbsolute);
1✔
33
            return stat.isFile();
1✔
34
        } catch (e) {
35
            // lstatSync throws an error if path doesn't exist
36
            return false;
1✔
37
        }
38
    }
39

40
    /**
41
     * Normalize path and replace all directory separators with current OS separators
42
     * @param thePath
43
     */
44
    public standardizePath(thePath: string) {
45
        if (!thePath) {
824✔
46
            return thePath;
14✔
47
        }
48
        return path.normalize(
810✔
49
            thePath.replace(/[\/\\]+/g, path.sep)
50
        );
51
    }
52

53
    /**
54
     * Convert all slashes to forward slashes
55
     */
56
    public toForwardSlashes(thePath: string) {
57
        if (typeof thePath === 'string') {
3✔
58
            return thePath.replace(/[\/\\]+/g, '/');
1✔
59
        } else {
60
            return thePath;
2✔
61
        }
62
    }
63

64
    /**
65
     * Do a case-insensitive string replacement
66
     * @param subject the string that will have its contents replaced
67
     * @param search the search text to find in `subject`
68
     * @param replace the text to replace `search` with in `subject`
69
     */
70
    public stringReplaceInsensitive(subject: string, search: string, replace: string) {
71
        let idx = subject.toLowerCase().indexOf(search.toLowerCase());
134✔
72
        if (idx > -1) {
134✔
73
            return subject.substring(0, idx) + replace + subject.substr(idx + search.length);
133✔
74
        } else {
75
            return subject;
1✔
76
        }
77
    }
78

79
    /**
80
     * Keep calling the callback until it does NOT throw an exception, or until the max number of tries has been reached.
81
     * @param callback
82
     * @param maxTries
83
     * @param sleepMilliseconds
84
     */
85
    /* istanbul ignore next */ //typescript generates some weird while statement that can't get fully covered for some reason
86
    public async tryRepeatAsync<T>(callback, maxTries = 10, sleepMilliseconds = 50): Promise<T> {
87
        let tryCount = 0;
88
        while (true) {
89
            try {
90
                return await Promise.resolve(callback());
91
            } catch (e) {
92
                tryCount++;
93
                if (tryCount > maxTries) {
94
                    throw e;
95
                } else {
96
                    await this.sleep(sleepMilliseconds);
97
                }
98
            }
99
        }
100
    }
101

102
    public async sleep(milliseconds: number) {
103
        await new Promise((resolve) => {
20✔
104
            setTimeout(resolve, milliseconds);
20✔
105
        });
106
    }
107

108
    /**
109
     * Determine if a file exists (case insensitive)
110
     */
111
    public async fileExistsCaseInsensitive(filePath: string) {
112
        filePath = this.standardizePath(filePath);
14✔
113
        const lowerFilePath = filePath.toLowerCase();
14✔
114

115
        const parentDirPath = path.dirname(filePath);
14✔
116

117
        //file can't exist if its parent dir doesn't exist
118
        if (await fsExtra.pathExists(parentDirPath) === false) {
14✔
119
            return false;
1✔
120
        }
121

122
        //get a list of every file in the parent directory for this file
123
        const filesInDir = await fsExtra.readdir(parentDirPath);
13✔
124
        //look at each file path until we find the one we're searching for
125
        for (let dirFile of filesInDir) {
13✔
126
            const dirFilePath = this.standardizePath(`${parentDirPath}/${dirFile}`);
14✔
127
            if (dirFilePath.toLowerCase() === lowerFilePath) {
14✔
128
                return true;
12✔
129
            }
130
        }
131
        return false;
1✔
132
    }
133

134
    /**
135
     * Run a series of glob patterns, returning the matches in buckets corresponding to their pattern index.
136
     */
137
    public async globAllByIndex(patterns: string[], cwd: string) {
138
        //force all path separators to unit style
139
        cwd = cwd.replace(/\\/g, '/');
88✔
140

141
        const globResults = patterns.map(async (pattern) => {
88✔
142
            //force all windows-style slashes to unix style
143
            pattern = pattern.replace(/\\/g, '/');
150✔
144
            //skip negated patterns (we will use them to filter later on)
145
            if (pattern.startsWith('!')) {
150✔
146
                return pattern;
12✔
147
            } else {
148
                //run glob matcher
149

150
                return fastGlob([pattern], {
138✔
151
                    cwd: cwd,
152
                    absolute: true,
153
                    followSymbolicLinks: true,
154
                    onlyFiles: true,
155
                });
156
            }
157
        });
158

159
        const matchesByIndex: Array<Array<string>> = [];
88✔
160

161
        for (let i = 0; i < globResults.length; i++) {
88✔
162
            const globResult = await globResults[i];
150✔
163
            //if the matches collection is missing, this is a filter
164
            if (typeof globResult === 'string') {
150✔
165
                this.filterPaths(globResult, matchesByIndex, cwd, i - 1);
12✔
166
                matchesByIndex.push(undefined);
12✔
167
            } else {
168
                matchesByIndex.push(globResult);
138✔
169
            }
170
        }
171
        return matchesByIndex;
88✔
172
    }
173

174
    /**
175
     * Filter all of the matches based on a minimatch pattern
176
     * @param stopIndex the max index of `matchesByIndex` to filter until
177
     * @param pattern - the pattern used to filter out entries from `matchesByIndex`. Usually preceeded by a `!`
178
     */
179
    private filterPaths(pattern: string, filesByIndex: string[][], cwd: string, stopIndex: number) {
180
        //move the ! to the start of the string to negate the absolute path, replace windows slashes with unix ones
181
        let negatedPatternAbsolute = '!' + path.posix.join(cwd, pattern.replace(/^!/, ''));
13✔
182
        let filter = picomatch(negatedPatternAbsolute);
13✔
183
        for (let i = 0; i <= stopIndex; i++) {
13✔
184
            if (filesByIndex[i]) {
20✔
185
                //filter all matches by the specified pattern
186
                filesByIndex[i] = filesByIndex[i].filter(x => {
17✔
187
                    return filter(x);
38✔
188
                });
189
            }
190
        }
191
    }
192
}
193

194
export let util = new Util();
1✔
195

196

197
/**
198
 * A tagged template literal function for standardizing the path.
199
 */
200
export function standardizePath(stringParts, ...expressions: any[]) {
1✔
201
    let result = [];
263✔
202
    for (let i = 0; i < stringParts.length; i++) {
263✔
203
        result.push(stringParts[i], expressions[i]);
1,037✔
204
    }
205
    return util.standardizePath(
263✔
206
        result.join('')
207
    );
208
}
209

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

© 2025 Coveralls, Inc