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

hexojs / hexo-util / 16650079534

31 Jul 2025 01:17PM UTC coverage: 72.979% (-23.9%) from 96.875%
16650079534

Pull #426

github

web-flow
Merge f1b03a4f5 into d497bc760
Pull Request #426: build: restructure for dual ESM/CJS output, update tooling, and enhance utilities

811 of 1128 branches covered (71.9%)

1576 of 2010 new or added lines in 40 files covered. (78.41%)

6 existing lines in 1 file now uncovered.

5272 of 7224 relevant lines covered (72.98%)

69.31 hits per line

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

94.12
/lib/encode_url.ts
1
import { punycode } from './_punycode.js';
2✔
2

2✔
3
function safeDecodeURIComponent(str: string) {
103✔
4
  try {
103✔
5
    return decodeURI(str);
103✔
6
  } catch {
103✔
7
    return str;
1✔
8
  }
1✔
9
}
103✔
10

2✔
11
export const encodeURL = (str: string) => {
2✔
12
  // Handle data URLs
100✔
13
  if (/^data:/i.test(str)) return str;
100✔
14

99✔
15
  // Try absolute URL
99✔
16
  try {
99✔
17
    const url = new URL(str);
99✔
18
    // Convert punycode host to Unicode if needed
99✔
19
    const unicodeHost = punycode.toUnicode(url.hostname);
99✔
20
    // Encode pathname only if not already encoded
99✔
21
    const pathname = encodeURI(safeDecodeURIComponent(url.pathname));
99✔
22
    // Encode search params, preserving existing encodings
99✔
23
    const search = new URLSearchParams(url.search).toString() ? '?' + new URLSearchParams(url.search).toString() : '';
100✔
24
    // Encode hash
100✔
25
    const hash = url.hash ? '#' + encodeURI(safeDecodeURIComponent(url.hash.slice(1))) : '';
100✔
26
    // Rebuild URL string manually to preserve Unicode hostname
100✔
27
    let result = url.protocol + '//';
100✔
28
    if (url.username || url.password) {
100✔
29
      result += url.username;
1✔
30
      if (url.password) result += ':' + url.password;
1✔
31
      result += '@';
1✔
32
    }
1✔
33
    result += unicodeHost;
40✔
34
    if (url.port) result += ':' + url.port;
100✔
35
    result += pathname + search + hash;
40✔
36
    // Remove trailing slash for file URLs if not present in input
40✔
37
    if (/^file:/i.test(str) && !/\/$/.test(str)) {
100!
NEW
38
      result = result.replace(/\/$/, '');
×
NEW
39
    }
×
40
    return result;
40✔
41
  } catch {
100✔
42
    // Not an absolute URL, try relative path or fragment
59✔
43
    // Handle hash only
59✔
44
    if (str.startsWith('#')) {
59✔
45
      return '#' + encodeURI(safeDecodeURIComponent(str.slice(1)));
1✔
46
    }
1✔
47
    // Handle relative path with query/hash
58✔
48
    const [path, search = ''] = str.split('?');
58✔
49
    const [pathname, hash = ''] = search.split('#');
58✔
50
    let encoded = encodeURI(safeDecodeURIComponent(path));
58✔
51
    if (pathname) {
59✔
52
      encoded += '?' + encodeURI(safeDecodeURIComponent(pathname));
1✔
53
    }
1✔
54
    if (hash) {
59!
NEW
55
      encoded += '#' + encodeURI(safeDecodeURIComponent(hash));
×
NEW
56
    }
×
57
    return encoded;
58✔
58
  }
58✔
59
};
100✔
60

2✔
61
// For ESM compatibility
2✔
62
export default encodeURL;
2✔
63
// For CommonJS compatibility
2✔
64
if (typeof module !== 'undefined' && typeof module.exports === 'object' && module.exports !== null) {
2!
65
  module.exports = encodeURL;
1✔
66
  // For ESM compatibility
1✔
67
  module.exports.default = encodeURL;
1✔
68
}
1✔
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