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

visgl / loaders.gl / 25798238260

13 May 2026 12:10PM UTC coverage: 60.607% (+0.3%) from 60.27%
25798238260

push

github

web-flow
feat(json) GeoJSON -> geoarrow, schema, logging  (#3399)

13466 of 24516 branches covered (54.93%)

Branch coverage included in aggregate %.

448 of 541 new or added lines in 12 files covered. (82.81%)

1264 existing lines in 117 files now uncovered.

27516 of 43103 relevant lines covered (63.84%)

15056.99 hits per line

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

80.41
/modules/loader-utils/src/lib/path-utils/path.ts
1
// Beginning of a minimal implementation of the Node.js path API, that doesn't pull in big polyfills.
2

3
import {getCWD} from './get-cwd';
4

5
/**
6
 * Replacement for Node.js path.filename
7
 * @param url
8
 */
9
export function filename(url: string): string {
10
  const slashIndex = url ? url.lastIndexOf('/') : -1;
161,753!
11
  return slashIndex >= 0 ? url.substr(slashIndex + 1) : url;
161,753✔
12
}
13

14
/**
15
 * Replacement for Node.js path.dirname
16
 * @param url
17
 */
18
export function dirname(url: string): string {
19
  const slashIndex = url ? url.lastIndexOf('/') : -1;
162,465✔
20
  return slashIndex >= 0 ? url.substr(0, slashIndex) : '';
162,465✔
21
}
22

23
/**
24
 * Replacement for Node.js path.join
25
 * @param parts
26
 */
27
export function join(...parts: string[]): string {
UNCOV
28
  const separator = '/';
8✔
UNCOV
29
  parts = parts.map((part, index) => {
8✔
UNCOV
30
    if (index) {
12✔
UNCOV
31
      part = part.replace(new RegExp(`^${separator}`), '');
4✔
32
    }
UNCOV
33
    if (index !== parts.length - 1) {
12✔
UNCOV
34
      part = part.replace(new RegExp(`${separator}$`), '');
4✔
35
    }
UNCOV
36
    return part;
12✔
37
  });
UNCOV
38
  return parts.join(separator);
8✔
39
}
40

41
/* eslint-disable no-continue */
42

43
/**
44
 * https://nodejs.org/api/path.html#path_path_resolve_paths
45
 * @param paths A sequence of paths or path segments.
46
 * @return resolved path
47
 * Forked from BTOdell/path-resolve under MIT license
48
 * @see https://github.com/BTOdell/path-resolve/blob/master/LICENSE
49
 */
50
export function resolve(...components: string[]): string {
51
  const paths: string[] = [];
18,601✔
52
  for (let _i = 0; _i < components.length; _i++) {
18,601✔
53
    paths[_i] = components[_i];
19,010✔
54
  }
55
  let resolvedPath = '';
18,601✔
56
  let resolvedAbsolute = false;
18,601✔
57
  let cwd: string | undefined;
58
  for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) {
18,601✔
59
    let path: string | undefined;
60
    if (i >= 0) {
37,207✔
61
      path = paths[i];
19,010✔
62
    } else {
63
      if (cwd === undefined) {
18,197!
64
        cwd = getCWD();
18,197✔
65
      }
66
      path = cwd;
18,197✔
67
    }
68
    // Skip empty entries
69
    if (path.length === 0) {
37,207!
70
      continue;
×
71
    }
72
    resolvedPath = `${path}/${resolvedPath}`;
37,207✔
73
    resolvedAbsolute = path.charCodeAt(0) === SLASH;
37,207✔
74
  }
75
  // At this point the path should be resolved to a full absolute path, but
76
  // handle relative paths to be safe (might happen when process.cwd() fails)
77
  // Normalize the path (removes leading slash)
78
  resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
18,601✔
79
  if (resolvedAbsolute) {
18,601!
80
    return `/${resolvedPath}`;
18,601✔
81
  } else if (resolvedPath.length > 0) {
×
82
    return resolvedPath;
×
83
  }
84
  return '.';
×
85
}
86

87
const SLASH = 47;
764✔
88
const DOT = 46;
764✔
89

90
/**
91
 * Resolves . and .. elements in a path with directory names
92
 * Forked from BTOdell/path-resolve under MIT license
93
 * @see https://github.com/BTOdell/path-resolve/blob/master/LICENSE
94
 */
95
/* eslint-disable max-depth */
96
// eslint-disable-next-line complexity, max-statements
97
function normalizeStringPosix(path: string, allowAboveRoot: boolean): string {
98
  let res = '';
18,601✔
99
  let lastSlash = -1;
18,601✔
100
  let dots = 0;
18,601✔
101
  let code: number | undefined;
102
  let isAboveRoot = false;
18,601✔
103

104
  for (let i = 0; i <= path.length; ++i) {
18,601✔
105
    if (i < path.length) {
1,172,576✔
106
      code = path.charCodeAt(i);
1,153,975✔
107
    } else if (code === SLASH) {
18,601!
108
      break;
18,601✔
109
    } else {
110
      code = SLASH;
×
111
    }
112
    if (code === SLASH) {
1,153,975✔
113
      if (lastSlash === i - 1 || dots === 1) {
185,859✔
114
        // NOOP
115
      } else if (lastSlash !== i - 1 && dots === 2) {
298,122✔
116
        if (
220!
117
          res.length < 2 ||
392!
118
          !isAboveRoot ||
119
          res.charCodeAt(res.length - 1) !== DOT ||
120
          res.charCodeAt(res.length - 2) !== DOT
121
        ) {
122
          if (res.length > 2) {
220✔
123
            const start = res.length - 1;
172✔
124
            let j = start;
172✔
125
            for (; j >= 0; --j) {
172✔
126
              if (res.charCodeAt(j) === SLASH) {
2,459✔
127
                break;
146✔
128
              }
129
            }
130
            if (j !== start) {
172!
131
              res = j === -1 ? '' : res.slice(0, j);
172✔
132
              lastSlash = i;
172✔
133
              dots = 0;
172✔
134
              isAboveRoot = false;
172✔
135
              continue;
172✔
136
            }
137
          } else if (res.length === 2 || res.length === 1) {
48!
138
            res = '';
×
139
            lastSlash = i;
×
140
            dots = 0;
×
141
            isAboveRoot = false;
×
142
            continue;
×
143
          }
144
        }
145
        if (allowAboveRoot) {
48!
146
          if (res.length > 0) {
×
147
            res += '/..';
×
148
          } else {
149
            res = '..';
×
150
          }
151
          isAboveRoot = true;
×
152
        }
153
      } else {
154
        const slice = path.slice(lastSlash + 1, i);
148,841✔
155
        if (res.length > 0) {
148,841✔
156
          res += `/${slice}`;
130,214✔
157
        } else {
158
          res = slice;
18,627✔
159
        }
160
        isAboveRoot = false;
148,841✔
161
      }
162
      lastSlash = i;
185,687✔
163
      dots = 0;
185,687✔
164
    } else if (code === DOT && dots !== -1) {
968,116✔
165
      ++dots;
18,632✔
166
    } else {
167
      dots = -1;
949,484✔
168
    }
169
  }
170
  return res;
18,601✔
171
}
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