@cspell/url 8.16.1 → 8.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
1
  import Path from 'node:path';
2
- export declare const isWindows: boolean;
3
2
  export declare const percentRegEx: RegExp;
4
3
  export declare const backslashRegEx: RegExp;
5
4
  export declare const newlineRegEx: RegExp;
@@ -1,9 +1,8 @@
1
1
  import assert from 'node:assert';
2
2
  import Path from 'node:path';
3
3
  import { pathToFileURL } from 'node:url';
4
- import { pathWindowsDriveLetterToUpper, regExpWindowsPathDriveLetter, toFilePathOrHref } from './fileUrl.mjs';
4
+ import { isFileURL, isWindows, isWindowsFileUrl, isWindowsPathnameWithDriveLatter, pathWindowsDriveLetterToUpper, regExpWindowsPathDriveLetter, toFilePathOrHref, } from './fileUrl.mjs';
5
5
  import { addTrailingSlash, isUrlLike, normalizeWindowsUrl, regExpWindowsPath, urlParent, urlToUrlRelative, } from './url.mjs';
6
- export const isWindows = process.platform === 'win32';
7
6
  const isWindowsPathRegEx = regExpWindowsPathDriveLetter;
8
7
  const isWindowsPathname = regExpWindowsPath;
9
8
  export const percentRegEx = /%/g;
@@ -94,17 +93,25 @@ export class FileUrlBuilder {
94
93
  if (typeof filenameOrUrl !== 'string')
95
94
  return filenameOrUrl;
96
95
  if (isUrlLike(filenameOrUrl))
97
- return new URL(filenameOrUrl);
96
+ return normalizeWindowsUrl(new URL(filenameOrUrl));
98
97
  relativeTo ??= this.cwd;
99
98
  isWindows && (filenameOrUrl = filenameOrUrl.replaceAll('\\', '/'));
99
+ if (this.isAbsolute(filenameOrUrl) && isFileURL(relativeTo)) {
100
+ const pathname = this.normalizeFilePathForUrl(filenameOrUrl);
101
+ if (isWindowsFileUrl(relativeTo) && !isWindowsPathnameWithDriveLatter(pathname)) {
102
+ const relFilePrefix = relativeTo.toString().slice(0, 10);
103
+ return normalizeWindowsUrl(new URL(relFilePrefix + pathname));
104
+ }
105
+ return normalizeWindowsUrl(new URL('file://' + pathname));
106
+ }
100
107
  if (isUrlLike(relativeTo)) {
101
108
  const pathname = this.normalizeFilePathForUrl(filenameOrUrl);
102
- return new URL(pathname, relativeTo);
109
+ return normalizeWindowsUrl(new URL(pathname, relativeTo));
103
110
  }
104
111
  // Resolve removes the trailing slash, so we need to add it back.
105
112
  const appendSlash = filenameOrUrl.endsWith('/') ? '/' : '';
106
113
  const pathname = this.normalizeFilePathForUrl(this.path.resolve(relativeTo.toString(), filenameOrUrl)) + appendSlash;
107
- return this.pathToFileURL(pathname, this.cwd);
114
+ return normalizeWindowsUrl(new URL('file://' + pathname));
108
115
  }
109
116
  /**
110
117
  * Try to make a URL for a directory.
@@ -121,7 +128,7 @@ export class FileUrlBuilder {
121
128
  return this.#urlToFilePathOrHref(url);
122
129
  }
123
130
  #urlToFilePathOrHref(url) {
124
- if (url.protocol !== ProtocolFile)
131
+ if (url.protocol !== ProtocolFile || url.hostname)
125
132
  return url.href;
126
133
  const p = this.path === Path
127
134
  ? toFilePathOrHref(url)
@@ -1,3 +1,5 @@
1
+ export declare const isWindows: boolean;
2
+ export declare function isWindowsPathnameWithDriveLatter(pathname: string): boolean;
1
3
  /**
2
4
  * @param url - URL or string to check if it is a file URL.
3
5
  * @returns true if the URL is a file URL.
@@ -11,4 +13,10 @@ export declare function isFileURL(url: URL | string): boolean;
11
13
  export declare function toFilePathOrHref(url: URL | string): string;
12
14
  export declare const regExpWindowsPathDriveLetter: RegExp;
13
15
  export declare function pathWindowsDriveLetterToUpper(absoluteFilePath: string): string;
16
+ /**
17
+ * Test if a url is a file url with a windows path. It does check for UNC paths.
18
+ * @param url - the url
19
+ * @returns true if the url is a file url with a windows path with a drive letter.
20
+ */
21
+ export declare function isWindowsFileUrl(url: URL | string): boolean;
14
22
  //# sourceMappingURL=fileUrl.d.mts.map
package/dist/fileUrl.mjs CHANGED
@@ -1,5 +1,10 @@
1
- import { fileURLToPath } from 'node:url';
1
+ import { fileURLToPath, pathToFileURL } from 'node:url';
2
2
  import { hasProtocol } from './url.mjs';
3
+ export const isWindows = process.platform === 'win32';
4
+ const windowsUrlPathRegExp = /^\/[a-zA-Z]:\//;
5
+ export function isWindowsPathnameWithDriveLatter(pathname) {
6
+ return windowsUrlPathRegExp.test(pathname);
7
+ }
3
8
  /**
4
9
  * @param url - URL or string to check if it is a file URL.
5
10
  * @returns true if the URL is a file URL.
@@ -13,13 +18,41 @@ export function isFileURL(url) {
13
18
  * @returns path or href
14
19
  */
15
20
  export function toFilePathOrHref(url) {
16
- return isFileURL(url) ? toFilePath(url) : url.toString();
21
+ return isFileURL(url) && url.toString().startsWith('file:///') ? toFilePath(url) : url.toString();
17
22
  }
18
23
  function toFilePath(url) {
19
- return pathWindowsDriveLetterToUpper(fileURLToPath(url));
24
+ try {
25
+ // Fix drive letter if necessary.
26
+ if (isWindows) {
27
+ const u = new URL(url);
28
+ if (!isWindowsPathnameWithDriveLatter(u.pathname)) {
29
+ const cwdUrl = pathToFileURL(process.cwd());
30
+ if (cwdUrl.hostname) {
31
+ return fileURLToPath(new URL(u.pathname, cwdUrl));
32
+ }
33
+ const drive = cwdUrl.pathname.split('/')[1];
34
+ u.pathname = `/${drive}${u.pathname}`;
35
+ return fileURLToPath(u);
36
+ }
37
+ }
38
+ return pathWindowsDriveLetterToUpper(fileURLToPath(url));
39
+ }
40
+ catch {
41
+ // console.error('Failed to convert URL to path', url);
42
+ return url.toString();
43
+ }
20
44
  }
21
45
  export const regExpWindowsPathDriveLetter = /^([a-zA-Z]):[\\/]/;
22
46
  export function pathWindowsDriveLetterToUpper(absoluteFilePath) {
23
47
  return absoluteFilePath.replace(regExpWindowsPathDriveLetter, (s) => s.toUpperCase());
24
48
  }
49
+ const regExpWindowsFileUrl = /^file:\/\/\/[a-zA-Z]:\//;
50
+ /**
51
+ * Test if a url is a file url with a windows path. It does check for UNC paths.
52
+ * @param url - the url
53
+ * @returns true if the url is a file url with a windows path with a drive letter.
54
+ */
55
+ export function isWindowsFileUrl(url) {
56
+ return regExpWindowsFileUrl.test(url.toString());
57
+ }
25
58
  //# sourceMappingURL=fileUrl.mjs.map
package/dist/index.d.mts CHANGED
@@ -3,5 +3,5 @@ export { encodePathChars, normalizeFilePathForUrl, toFileDirURL, toFileURL } fro
3
3
  export { isFileURL, toFilePathOrHref } from './fileUrl.mjs';
4
4
  export type { BuilderOptions, PathInterface } from './FileUrlBuilder.mjs';
5
5
  export { FileUrlBuilder } from './FileUrlBuilder.mjs';
6
- export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isNotUrlLike, isURL, isUrlLike, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
6
+ export { addTrailingSlash, basenameOfUrlPathname, fixUncUrl, hasProtocol, isNotUrlLike, isURL, isUrlLike, normalizeWindowsUrl, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
7
7
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -2,5 +2,5 @@ export { isDataURL, urlBasename } from './dataUrl.mjs';
2
2
  export { encodePathChars, normalizeFilePathForUrl, toFileDirURL, toFileURL } from './defaultFileUrlBuilder.mjs';
3
3
  export { isFileURL, toFilePathOrHref } from './fileUrl.mjs';
4
4
  export { FileUrlBuilder } from './FileUrlBuilder.mjs';
5
- export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isNotUrlLike, isURL, isUrlLike, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
5
+ export { addTrailingSlash, basenameOfUrlPathname, fixUncUrl, hasProtocol, isNotUrlLike, isURL, isUrlLike, normalizeWindowsUrl, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
6
6
  //# sourceMappingURL=index.mjs.map
package/dist/url.d.mts CHANGED
@@ -105,4 +105,10 @@ export declare const regExpEncodedColon: RegExp;
105
105
  * @returns a new URL if modified or converted from a string.
106
106
  */
107
107
  export declare function normalizeWindowsUrl(url: URL | string): URL;
108
+ /**
109
+ * There is a bug is NodeJS that sometimes causes UNC paths converted to a URL to be prefixed with `file:////`.
110
+ * @param url - URL to check.
111
+ * @returns fixed URL if needed.
112
+ */
113
+ export declare function fixUncUrl(url: URL): URL;
108
114
  //# sourceMappingURL=url.d.mts.map
package/dist/url.mjs CHANGED
@@ -150,6 +150,7 @@ export function urlToUrlRelative(urlFrom, urlTo) {
150
150
  }
151
151
  export const regExpWindowsPath = /^[\\/]([a-zA-Z]:[\\/])/;
152
152
  export const regExpEncodedColon = /%3[aA]/g;
153
+ const badUncLocalhostUrl = /^(\/+[a-zA-Z])\$/;
153
154
  /**
154
155
  * Ensure that a windows file url is correctly formatted with a capitol letter for the drive.
155
156
  *
@@ -159,15 +160,28 @@ export const regExpEncodedColon = /%3[aA]/g;
159
160
  export function normalizeWindowsUrl(url) {
160
161
  url = typeof url === 'string' ? new URL(url) : url;
161
162
  if (url.protocol === 'file:') {
162
- const pathname = url.pathname
163
- .replaceAll(regExpEncodedColon, ':')
164
- .replace(regExpWindowsPath, (d) => d.toUpperCase());
163
+ let pathname = url.pathname.replaceAll('%3A', ':').replaceAll('%3a', ':').replaceAll('%24', '$');
164
+ if (!url.host) {
165
+ pathname = pathname.replace(badUncLocalhostUrl, '$1:');
166
+ }
167
+ pathname = pathname.replace(regExpWindowsPath, (d) => d.toUpperCase());
165
168
  if (pathname !== url.pathname) {
166
169
  url = new URL(url);
167
170
  url.pathname = pathname;
168
- return url;
171
+ return fixUncUrl(url);
169
172
  }
170
173
  }
174
+ return fixUncUrl(url);
175
+ }
176
+ /**
177
+ * There is a bug is NodeJS that sometimes causes UNC paths converted to a URL to be prefixed with `file:////`.
178
+ * @param url - URL to check.
179
+ * @returns fixed URL if needed.
180
+ */
181
+ export function fixUncUrl(url) {
182
+ if (url.href.startsWith('file:////')) {
183
+ return new URL(url.href.replace(/^file:\/{4}/, 'file://'));
184
+ }
171
185
  return url;
172
186
  }
173
187
  //# sourceMappingURL=url.mjs.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public",
5
5
  "provenance": true
6
6
  },
7
- "version": "8.16.1",
7
+ "version": "8.17.0",
8
8
  "description": "URL parsing and manipulation utilities for cspell",
9
9
  "keywords": [
10
10
  "cspell",
@@ -57,5 +57,5 @@
57
57
  "engines": {
58
58
  "node": ">=18.0"
59
59
  },
60
- "gitHead": "773bb6e701ff0b7fbeb30e4621119bb4315415ad"
60
+ "gitHead": "cac17fe7b993db5965aa441648b1c22cb5486929"
61
61
  }