@cspell/url 8.9.1 → 8.10.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.
@@ -0,0 +1,88 @@
1
+ import Path from 'node:path';
2
+ export declare const isWindows: boolean;
3
+ export declare const isWindowsPathRegEx: RegExp;
4
+ export declare const percentRegEx: RegExp;
5
+ export declare const backslashRegEx: RegExp;
6
+ export declare const newlineRegEx: RegExp;
7
+ export declare const carriageReturnRegEx: RegExp;
8
+ export declare const tabRegEx: RegExp;
9
+ export declare const questionRegex: RegExp;
10
+ export declare const hashRegex: RegExp;
11
+ export interface PathInterface {
12
+ sep: string;
13
+ resolve(...paths: string[]): string;
14
+ parse(path: string): Path.ParsedPath;
15
+ normalize(path: string): string;
16
+ relative(from: string, to: string): string;
17
+ isAbsolute(path: string): boolean;
18
+ }
19
+ export interface BuilderOptions {
20
+ windows?: boolean | undefined;
21
+ path?: PathInterface | undefined;
22
+ cwd?: URL | undefined;
23
+ }
24
+ export declare class FileUrlBuilder {
25
+ #private;
26
+ private windows;
27
+ readonly path: PathInterface;
28
+ readonly cwd: URL;
29
+ constructor(options?: BuilderOptions);
30
+ /**
31
+ * Encode special characters in a file path to use in a URL.
32
+ * @param filepath
33
+ * @returns
34
+ */
35
+ encodePathChars(filepath: string): string;
36
+ /**
37
+ * Normalize a file path for use in a URL.
38
+ * ```js
39
+ * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
40
+ * // Result: file:///Users/user/path/to/file.txt
41
+ * ```
42
+ * @param filePath
43
+ * @returns a normalized file path for use as a relative path in a URL.
44
+ */
45
+ normalizeFilePathForUrl(filePath: string): string;
46
+ /**
47
+ * Try to make a file URL.
48
+ * - if filenameOrUrl is already a URL, it is returned as is.
49
+ * @param filenameOrUrl
50
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
51
+ * @returns a URL
52
+ */
53
+ toFileURL(filenameOrUrl: string | URL, relativeTo?: string | URL): URL;
54
+ /**
55
+ * Try to make a URL for a directory.
56
+ * - if dirOrUrl is already a URL, a slash is appended to the pathname.
57
+ * @param dirOrUrl - directory path to convert to a file URL.
58
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
59
+ * @returns a URL
60
+ */
61
+ toFileDirURL(dirOrUrl: string | URL, relativeTo?: string | URL): URL;
62
+ urlToFilePathOrHref(url: URL | string): string;
63
+ /**
64
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
65
+ * The protocol is not evaluated. Only the `url.pathname` is used.
66
+ * The result: `new URL(relative(urlFrom, urlTo), urlFrom).pathname === urlTo.pathname`
67
+ * @param urlFrom
68
+ * @param urlTo
69
+ * @returns the relative path
70
+ */
71
+ relative(urlFrom: URL, urlTo: URL): string;
72
+ /**
73
+ * Get the parent directory of a URL.
74
+ * @param url
75
+ */
76
+ urlDirname(url: URL | string): URL;
77
+ pathToFileURL(pathname: string, relativeToURL?: URL | string): URL;
78
+ rootFileURL(filePath?: string): URL;
79
+ /**
80
+ * Determine if a filePath is absolute.
81
+ *
82
+ * @param filePath
83
+ * @returns true if `URL` or `path.isAbsolute(filePath)`
84
+ */
85
+ isAbsolute(filePath: string): boolean;
86
+ isUrlLike(url: string | URL): boolean;
87
+ }
88
+ //# sourceMappingURL=FileUrlBuilder.d.mts.map
@@ -0,0 +1,176 @@
1
+ import assert from 'node:assert';
2
+ import Path from 'node:path';
3
+ import { toFilePathOrHref } from './fileUrl.mjs';
4
+ import { addTrailingSlash, isUrlLike, urlParent, urlToUrlRelative } from './url.mjs';
5
+ export const isWindows = process.platform === 'win32';
6
+ export const isWindowsPathRegEx = /^[a-z]:[\\/]/i;
7
+ const isWindowsPathname = /^[\\/]([a-z]:[\\/])/i;
8
+ export const percentRegEx = /%/g;
9
+ export const backslashRegEx = /\\/g;
10
+ export const newlineRegEx = /\n/g;
11
+ export const carriageReturnRegEx = /\r/g;
12
+ export const tabRegEx = /\t/g;
13
+ export const questionRegex = /\?/g;
14
+ export const hashRegex = /#/g;
15
+ const ProtocolFile = 'file:';
16
+ const RootFileURL = 'file:///';
17
+ export class FileUrlBuilder {
18
+ windows;
19
+ path;
20
+ cwd;
21
+ constructor(options = {}) {
22
+ const sep = options.path?.sep;
23
+ this.windows = options.windows ?? (sep ? sep === '\\' : undefined) ?? isWindows;
24
+ this.path = options.path ?? (this.windows ? Path.win32 : Path.posix);
25
+ // note: `this.path.resolve() + '/'` is used on purpose instead of `'./'`
26
+ this.cwd = options.cwd ?? this.pathToFileURL(this.path.resolve() + '/', this.rootFileURL());
27
+ assert(this.path.sep === (this.windows ? '\\' : '/'), `Path separator should match OS type Windows: ${this.windows === true ? 'true' : (this.windows ?? 'undefined') || 'false'}, ` +
28
+ `sep: ${this.path.sep}, ` +
29
+ `options: ` +
30
+ JSON.stringify({
31
+ isWindows,
32
+ sep: `${sep}`,
33
+ windows: options.windows,
34
+ pathSep: options.path?.sep,
35
+ n: options.path?.normalize('path/file.txt'),
36
+ cwd: options.cwd?.href,
37
+ win32: this.path === Path.win32,
38
+ posix: this.path === Path.posix,
39
+ 'win32.normalize': this.path.normalize === Path.win32.normalize,
40
+ 'posix.normalize': this.path.normalize === Path.posix.normalize,
41
+ }) +
42
+ ``);
43
+ }
44
+ /**
45
+ * Encode special characters in a file path to use in a URL.
46
+ * @param filepath
47
+ * @returns
48
+ */
49
+ encodePathChars(filepath) {
50
+ filepath = filepath.replaceAll(percentRegEx, '%25');
51
+ // In posix, backslash is a valid character in paths:
52
+ if (!this.windows && !isWindows && filepath.includes('\\')) {
53
+ filepath = filepath.replaceAll(backslashRegEx, '%5C');
54
+ }
55
+ filepath = filepath.replaceAll(newlineRegEx, '%0A');
56
+ filepath = filepath.replaceAll(carriageReturnRegEx, '%0D');
57
+ filepath = filepath.replaceAll(tabRegEx, '%09');
58
+ return filepath;
59
+ }
60
+ /**
61
+ * Normalize a file path for use in a URL.
62
+ * ```js
63
+ * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
64
+ * // Result: file:///Users/user/path/to/file.txt
65
+ * ```
66
+ * @param filePath
67
+ * @returns a normalized file path for use as a relative path in a URL.
68
+ */
69
+ normalizeFilePathForUrl(filePath) {
70
+ filePath = this.encodePathChars(filePath);
71
+ filePath = filePath.replaceAll(questionRegex, '%3F');
72
+ filePath = filePath.replaceAll(hashRegex, '%23');
73
+ const pathname = filePath.replaceAll('\\', '/');
74
+ return pathname.replace(isWindowsPathRegEx, (drive) => `/${drive}`.toUpperCase());
75
+ }
76
+ /**
77
+ * Try to make a file URL.
78
+ * - if filenameOrUrl is already a URL, it is returned as is.
79
+ * @param filenameOrUrl
80
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
81
+ * @returns a URL
82
+ */
83
+ toFileURL(filenameOrUrl, relativeTo) {
84
+ if (typeof filenameOrUrl !== 'string')
85
+ return filenameOrUrl;
86
+ if (isUrlLike(filenameOrUrl))
87
+ return new URL(filenameOrUrl);
88
+ relativeTo ??= this.cwd;
89
+ isWindows && (filenameOrUrl = filenameOrUrl.replaceAll('\\', '/'));
90
+ if (isUrlLike(relativeTo)) {
91
+ const pathname = this.normalizeFilePathForUrl(filenameOrUrl);
92
+ return new URL(pathname, relativeTo);
93
+ }
94
+ // Resolve removes the trailing slash, so we need to add it back.
95
+ const appendSlash = filenameOrUrl.endsWith('/') ? '/' : '';
96
+ const pathname = this.normalizeFilePathForUrl(this.path.resolve(relativeTo.toString(), filenameOrUrl)) + appendSlash;
97
+ return this.pathToFileURL(pathname, this.cwd);
98
+ }
99
+ /**
100
+ * Try to make a URL for a directory.
101
+ * - if dirOrUrl is already a URL, a slash is appended to the pathname.
102
+ * @param dirOrUrl - directory path to convert to a file URL.
103
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
104
+ * @returns a URL
105
+ */
106
+ toFileDirURL(dirOrUrl, relativeTo) {
107
+ return addTrailingSlash(this.toFileURL(dirOrUrl, relativeTo));
108
+ }
109
+ urlToFilePathOrHref(url) {
110
+ url = this.toFileURL(url);
111
+ return this.#urlToFilePathOrHref(url);
112
+ }
113
+ #urlToFilePathOrHref(url) {
114
+ if (url.protocol !== ProtocolFile)
115
+ return url.href;
116
+ const p = this.path === Path
117
+ ? toFilePathOrHref(url)
118
+ : decodeURIComponent(url.pathname.split('/').join(this.path.sep));
119
+ return p.replace(isWindowsPathRegEx, (drive) => drive.toUpperCase()).replace(isWindowsPathname, '$1');
120
+ }
121
+ /**
122
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
123
+ * The protocol is not evaluated. Only the `url.pathname` is used.
124
+ * The result: `new URL(relative(urlFrom, urlTo), urlFrom).pathname === urlTo.pathname`
125
+ * @param urlFrom
126
+ * @param urlTo
127
+ * @returns the relative path
128
+ */
129
+ relative(urlFrom, urlTo) {
130
+ if (urlFrom.protocol === urlTo.protocol && urlFrom.protocol === ProtocolFile) {
131
+ if (urlFrom.href === urlTo.href)
132
+ return '';
133
+ urlFrom = urlFrom.pathname.endsWith('/') ? urlFrom : new URL('./', urlFrom);
134
+ const fromPath = urlFrom.pathname;
135
+ const toPath = urlTo.pathname;
136
+ if (toPath.startsWith(fromPath))
137
+ return decodeURIComponent(toPath.slice(fromPath.length));
138
+ const pFrom = this.#urlToFilePathOrHref(urlFrom);
139
+ const pTo = this.#urlToFilePathOrHref(urlTo);
140
+ const toIsDir = urlTo.pathname.endsWith('/');
141
+ let pathname = this.normalizeFilePathForUrl(this.path.relative(pFrom, pTo));
142
+ if (toIsDir && !pathname.endsWith('/'))
143
+ pathname += '/';
144
+ return decodeURIComponent(pathname);
145
+ }
146
+ return decodeURIComponent(urlToUrlRelative(urlFrom, urlTo));
147
+ }
148
+ /**
149
+ * Get the parent directory of a URL.
150
+ * @param url
151
+ */
152
+ urlDirname(url) {
153
+ return urlParent(this.toFileURL(url));
154
+ }
155
+ pathToFileURL(pathname, relativeToURL) {
156
+ return new URL(this.normalizeFilePathForUrl(pathname), relativeToURL || this.cwd);
157
+ }
158
+ rootFileURL(filePath) {
159
+ const path = this.path;
160
+ const p = path.parse(path.normalize(path.resolve(filePath ?? '.')));
161
+ return new URL(this.normalizeFilePathForUrl(p.root), RootFileURL);
162
+ }
163
+ /**
164
+ * Determine if a filePath is absolute.
165
+ *
166
+ * @param filePath
167
+ * @returns true if `URL` or `path.isAbsolute(filePath)`
168
+ */
169
+ isAbsolute(filePath) {
170
+ return isUrlLike(filePath) || this.path.isAbsolute(filePath);
171
+ }
172
+ isUrlLike(url) {
173
+ return isUrlLike(url);
174
+ }
175
+ }
176
+ //# sourceMappingURL=FileUrlBuilder.mjs.map
@@ -0,0 +1,27 @@
1
+ export declare function encodePathChars(filepath: string): string;
2
+ /**
3
+ * Normalize a file path for use in a URL.
4
+ * ```js
5
+ * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
6
+ * // Result: file:///Users/user/path/to/file.txt
7
+ * ```
8
+ * @param filePath
9
+ * @returns a normalized file path for use as a relative path in a URL.
10
+ */
11
+ export declare function normalizeFilePathForUrl(filePath: string): string;
12
+ /**
13
+ * Try to make a file URL.
14
+ * - if filenameOrUrl is already a URL, it is returned as is.
15
+ * -
16
+ * @param filenameOrUrl
17
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
18
+ * @returns a URL
19
+ */
20
+ export declare function toFileURL(filenameOrUrl: string | URL, relativeTo?: string | URL): URL;
21
+ /**
22
+ * Converts a file path to a URL and adds a trailing slash.
23
+ * @param dir - url to a directory
24
+ * @returns a URL
25
+ */
26
+ export declare function toFileDirURL(dir: string | URL): URL;
27
+ //# sourceMappingURL=defaultFileUrlBuilder.d.mts.map
@@ -0,0 +1,37 @@
1
+ import { FileUrlBuilder } from './FileUrlBuilder.mjs';
2
+ const fileUrlBuilder = new FileUrlBuilder();
3
+ export function encodePathChars(filepath) {
4
+ return fileUrlBuilder.encodePathChars(filepath);
5
+ }
6
+ /**
7
+ * Normalize a file path for use in a URL.
8
+ * ```js
9
+ * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
10
+ * // Result: file:///Users/user/path/to/file.txt
11
+ * ```
12
+ * @param filePath
13
+ * @returns a normalized file path for use as a relative path in a URL.
14
+ */
15
+ export function normalizeFilePathForUrl(filePath) {
16
+ return fileUrlBuilder.normalizeFilePathForUrl(filePath);
17
+ }
18
+ /**
19
+ * Try to make a file URL.
20
+ * - if filenameOrUrl is already a URL, it is returned as is.
21
+ * -
22
+ * @param filenameOrUrl
23
+ * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
24
+ * @returns a URL
25
+ */
26
+ export function toFileURL(filenameOrUrl, relativeTo) {
27
+ return fileUrlBuilder.toFileURL(filenameOrUrl, relativeTo);
28
+ }
29
+ /**
30
+ * Converts a file path to a URL and adds a trailing slash.
31
+ * @param dir - url to a directory
32
+ * @returns a URL
33
+ */
34
+ export function toFileDirURL(dir) {
35
+ return fileUrlBuilder.toFileDirURL(dir);
36
+ }
37
+ //# sourceMappingURL=defaultFileUrlBuilder.mjs.map
@@ -3,75 +3,10 @@
3
3
  * @returns true if the URL is a file URL.
4
4
  */
5
5
  export declare function isFileURL(url: URL | string): boolean;
6
- export interface PathInterface {
7
- sep: string;
8
- resolve(...paths: string[]): string;
9
- }
10
- export interface BuilderOptions {
11
- windows?: boolean | undefined;
12
- path?: PathInterface | undefined;
13
- cwd?: URL | undefined;
14
- }
15
- export declare class FileUrlBuilder {
16
- private windows;
17
- private path;
18
- private cwd;
19
- constructor(options?: BuilderOptions);
20
- /**
21
- * Encode special characters in a file path to use in a URL.
22
- * @param filepath
23
- * @returns
24
- */
25
- encodePathChars(filepath: string): string;
26
- /**
27
- * Normalize a file path for use in a URL.
28
- * ```js
29
- * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
30
- * // Result: file:///Users/user/path/to/file.txt
31
- * ```
32
- * @param filePath
33
- * @returns a normalized file path for use as a relative path in a URL.
34
- */
35
- normalizeFilePathForUrl(filePath: string): string;
36
- /**
37
- * Try to make a file URL.
38
- * - if filenameOrUrl is already a URL, it is returned as is.
39
- * @param filenameOrUrl
40
- * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
41
- * @returns a URL
42
- */
43
- toFileURL(filenameOrUrl: string | URL, relativeTo?: string | URL): URL;
44
- }
45
- export declare function encodePathChars(filepath: string): string;
46
- /**
47
- * Normalize a file path for use in a URL.
48
- * ```js
49
- * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
50
- * // Result: file:///Users/user/path/to/file.txt
51
- * ```
52
- * @param filePath
53
- * @returns a normalized file path for use as a relative path in a URL.
54
- */
55
- export declare function normalizeFilePathForUrl(filePath: string): string;
56
- /**
57
- * Try to make a file URL.
58
- * - if filenameOrUrl is already a URL, it is returned as is.
59
- * -
60
- * @param filenameOrUrl
61
- * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
62
- * @returns a URL
63
- */
64
- export declare function toFileURL(filenameOrUrl: string | URL, relativeTo?: string | URL): URL;
65
6
  /**
66
7
  * Convert a URL into a string. If it is a file URL, convert it to a path.
67
8
  * @param url - URL
68
9
  * @returns path or href
69
10
  */
70
11
  export declare function toFilePathOrHref(url: URL | string): string;
71
- /**
72
- * Converts a file path to a URL and adds a trailing slash.
73
- * @param dir - url to a directory
74
- * @returns a URL
75
- */
76
- export declare function toFileDirURL(dir: string | URL): URL;
77
12
  //# sourceMappingURL=fileUrl.d.mts.map
package/dist/fileUrl.mjs CHANGED
@@ -1,16 +1,5 @@
1
- import assert from 'node:assert';
2
- import path from 'node:path';
3
- import { fileURLToPath, pathToFileURL } from 'node:url';
4
- import { addTrailingSlash, hasProtocol, isUrlLike } from './url.mjs';
5
- const isWindows = process.platform === 'win32';
6
- const isWindowsPathRegEx = /^[a-z]:[\\/]/i;
7
- const percentRegEx = /%/g;
8
- const backslashRegEx = /\\/g;
9
- const newlineRegEx = /\n/g;
10
- const carriageReturnRegEx = /\r/g;
11
- const tabRegEx = /\t/g;
12
- const questionRegex = /\?/g;
13
- const hashRegex = /#/g;
1
+ import { fileURLToPath } from 'node:url';
2
+ import { hasProtocol } from './url.mjs';
14
3
  /**
15
4
  * @param url - URL or string to check if it is a file URL.
16
5
  * @returns true if the URL is a file URL.
@@ -18,100 +7,6 @@ const hashRegex = /#/g;
18
7
  export function isFileURL(url) {
19
8
  return hasProtocol(url, 'file:');
20
9
  }
21
- export class FileUrlBuilder {
22
- windows;
23
- path;
24
- cwd;
25
- constructor(options = {}) {
26
- const sep = options.path?.sep;
27
- this.windows = options.windows ?? (sep ? sep === '\\' : undefined) ?? isWindows;
28
- this.path = options.path ?? this.windows ? path.win32 : path.posix;
29
- this.cwd = options.cwd ?? pathToFileURL(this.path.resolve() + '/');
30
- assert(this.path.sep === (this.windows ? '\\' : '/'));
31
- }
32
- /**
33
- * Encode special characters in a file path to use in a URL.
34
- * @param filepath
35
- * @returns
36
- */
37
- encodePathChars(filepath) {
38
- filepath = filepath.replaceAll(percentRegEx, '%25');
39
- // In posix, backslash is a valid character in paths:
40
- if (!this.windows && filepath.includes('\\'))
41
- filepath = filepath.replaceAll(backslashRegEx, '%5C');
42
- filepath = filepath.replaceAll(newlineRegEx, '%0A');
43
- filepath = filepath.replaceAll(carriageReturnRegEx, '%0D');
44
- filepath = filepath.replaceAll(tabRegEx, '%09');
45
- return filepath;
46
- }
47
- /**
48
- * Normalize a file path for use in a URL.
49
- * ```js
50
- * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
51
- * // Result: file:///Users/user/path/to/file.txt
52
- * ```
53
- * @param filePath
54
- * @returns a normalized file path for use as a relative path in a URL.
55
- */
56
- normalizeFilePathForUrl(filePath) {
57
- filePath = this.encodePathChars(filePath);
58
- filePath = filePath.replaceAll(questionRegex, '%3F');
59
- filePath = filePath.replaceAll(hashRegex, '%23');
60
- const pathname = filePath.replaceAll('\\', '/');
61
- return pathname.replace(isWindowsPathRegEx, (drive) => `/${drive}`.toUpperCase());
62
- }
63
- /**
64
- * Try to make a file URL.
65
- * - if filenameOrUrl is already a URL, it is returned as is.
66
- * @param filenameOrUrl
67
- * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
68
- * @returns a URL
69
- */
70
- toFileURL(filenameOrUrl, relativeTo) {
71
- if (typeof filenameOrUrl !== 'string')
72
- return filenameOrUrl;
73
- if (isUrlLike(filenameOrUrl))
74
- return new URL(filenameOrUrl);
75
- relativeTo ??= this.cwd;
76
- if (isUrlLike(relativeTo)) {
77
- return new URL(this.normalizeFilePathForUrl(filenameOrUrl), relativeTo);
78
- }
79
- // Resolve removes the trailing slash, so we need to add it back.
80
- const appendSlash = filenameOrUrl.endsWith('/')
81
- ? '/'
82
- : this.windows && filenameOrUrl.endsWith('\\')
83
- ? '\\'
84
- : '';
85
- return pathToFileURL(this.path.resolve(relativeTo.toString(), filenameOrUrl) + appendSlash);
86
- }
87
- }
88
- const fileUrlBuilder = new FileUrlBuilder();
89
- export function encodePathChars(filepath) {
90
- return fileUrlBuilder.encodePathChars(filepath);
91
- }
92
- /**
93
- * Normalize a file path for use in a URL.
94
- * ```js
95
- * const url = new URL(normalizeFilePathForUrl('path\\to\\file.txt'), 'file:///Users/user/');
96
- * // Result: file:///Users/user/path/to/file.txt
97
- * ```
98
- * @param filePath
99
- * @returns a normalized file path for use as a relative path in a URL.
100
- */
101
- export function normalizeFilePathForUrl(filePath) {
102
- return fileUrlBuilder.normalizeFilePathForUrl(filePath);
103
- }
104
- /**
105
- * Try to make a file URL.
106
- * - if filenameOrUrl is already a URL, it is returned as is.
107
- * -
108
- * @param filenameOrUrl
109
- * @param relativeTo - optional URL, if given, filenameOrUrl will be parsed as relative.
110
- * @returns a URL
111
- */
112
- export function toFileURL(filenameOrUrl, relativeTo) {
113
- return fileUrlBuilder.toFileURL(filenameOrUrl, relativeTo);
114
- }
115
10
  /**
116
11
  * Convert a URL into a string. If it is a file URL, convert it to a path.
117
12
  * @param url - URL
@@ -126,13 +21,4 @@ function toFilePath(url) {
126
21
  function windowsDriveLetterToUpper(absoluteFilePath) {
127
22
  return absoluteFilePath.replace(/^([a-z]):\\/, (s) => s.toUpperCase());
128
23
  }
129
- /**
130
- * Converts a file path to a URL and adds a trailing slash.
131
- * @param dir - url to a directory
132
- * @returns a URL
133
- */
134
- export function toFileDirURL(dir) {
135
- const url = toFileURL(dir);
136
- return addTrailingSlash(url);
137
- }
138
24
  //# sourceMappingURL=fileUrl.mjs.map
package/dist/index.d.mts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { isDataURL, urlBasename } from './dataUrl.mjs';
2
- export type { BuilderOptions, PathInterface } from './fileUrl.mjs';
3
- export { encodePathChars, FileUrlBuilder, isFileURL, normalizeFilePathForUrl, toFileDirURL, toFilePathOrHref, toFileURL, } from './fileUrl.mjs';
4
- export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isURL, isUrlLike, toURL, urlParent } from './url.mjs';
2
+ export { encodePathChars, normalizeFilePathForUrl, toFileDirURL, toFileURL } from './defaultFileUrlBuilder.mjs';
3
+ export { isFileURL, toFilePathOrHref } from './fileUrl.mjs';
4
+ export type { BuilderOptions, PathInterface } from './FileUrlBuilder.mjs';
5
+ export { FileUrlBuilder } from './FileUrlBuilder.mjs';
6
+ export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isNotUrlLike, isURL, isUrlLike, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
5
7
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  export { isDataURL, urlBasename } from './dataUrl.mjs';
2
- export { encodePathChars, FileUrlBuilder, isFileURL, normalizeFilePathForUrl, toFileDirURL, toFilePathOrHref, toFileURL, } from './fileUrl.mjs';
3
- export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isURL, isUrlLike, toURL, urlParent } from './url.mjs';
2
+ export { encodePathChars, normalizeFilePathForUrl, toFileDirURL, toFileURL } from './defaultFileUrlBuilder.mjs';
3
+ export { isFileURL, toFilePathOrHref } from './fileUrl.mjs';
4
+ export { FileUrlBuilder } from './FileUrlBuilder.mjs';
5
+ export { addTrailingSlash, basenameOfUrlPathname, hasProtocol, isNotUrlLike, isURL, isUrlLike, toURL, urlDirname, urlParent, urlRelative, } from './url.mjs';
4
6
  //# sourceMappingURL=index.mjs.map
package/dist/url.d.mts CHANGED
@@ -12,6 +12,14 @@ export declare function toURL(url: string | URL, relativeTo?: string | URL): URL
12
12
  * @returns a URL
13
13
  */
14
14
  export declare function urlParent(url: string | URL): URL;
15
+ /**
16
+ * Alias of {@link urlParent}
17
+ * Try to determine the parent directory URL of the uri.
18
+ * If it is not a hierarchical URL, then it will return the URL.
19
+ * @param url - url to extract the dirname from.
20
+ * @returns a URL
21
+ */
22
+ export declare const urlDirname: typeof urlParent;
15
23
  /**
16
24
  * return the basename (last portion of the URL pathname) of a path. It does NOT remove the trailing slash.
17
25
  * @param path - URL pathname to extract the basename from.
@@ -26,6 +34,15 @@ export declare function isUrlLike(filename: URL): true;
26
34
  * @param filename - filename to check if it is a string containing a URL or a URL object.
27
35
  */
28
36
  export declare function isUrlLike(filename: string | URL): boolean;
37
+ /**
38
+ * @param filename - filename to check if it is a string containing a URL.
39
+ */
40
+ export declare function isNotUrlLike(filename: string): boolean;
41
+ export declare function isNotUrlLike(filename: URL): false;
42
+ /**
43
+ * @param filename - filename to check if it is a string containing a URL or a URL object.
44
+ */
45
+ export declare function isNotUrlLike(filename: string | URL): filename is string;
29
46
  /**
30
47
  * Check if `url` is a URL instance.
31
48
  * @returns
@@ -45,4 +62,38 @@ export declare function hasProtocol(url: string | URL, protocol: string): boolea
45
62
  * @returns
46
63
  */
47
64
  export declare function addTrailingSlash(url: URL): URL;
65
+ /**
66
+ * Remove the filename at the end of the URL pathname.
67
+ * If the URL pathname ends with a `/`, it is considered a directory and the URL is returned as is.
68
+ * If the URL pathname does not start with a `/`, it is considered an non-regular URL and the URL is returned as is.
69
+ * @param url
70
+ * @returns
71
+ */
72
+ export declare function urlRemoveFilename(url: URL): URL;
73
+ /**
74
+ * Extract the filename from the URL pathname.
75
+ *
76
+ * ```ts
77
+ * url.href === new URL(urlFilename(url), urlRemoveFilename(url)).href
78
+ * ```
79
+ * @param url - URL to extract the filename from.
80
+ * @returns the filename or empty string if the URL pathname ends with a `/`.
81
+ */
82
+ export declare function urlFilename(url: URL): string;
83
+ /**
84
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
85
+ * The protocol is not evaluated. Only the `url.pathname` is used.
86
+ * @param urlFrom
87
+ * @param urlTo
88
+ * @returns the relative path
89
+ */
90
+ export declare function urlRelative(urlFrom: string | URL, urlTo: string | URL): string;
91
+ /**
92
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
93
+ * The protocol is not evaluated. Only the `url.pathname` is used.
94
+ * @param urlFrom
95
+ * @param urlTo
96
+ * @returns the relative path
97
+ */
98
+ export declare function urlToUrlRelative(urlFrom: URL, urlTo: URL): string;
48
99
  //# sourceMappingURL=url.d.mts.map
package/dist/url.mjs CHANGED
@@ -28,6 +28,14 @@ export function urlParent(url) {
28
28
  }
29
29
  return new URL(hasTrailingSlash ? '..' : '.', url);
30
30
  }
31
+ /**
32
+ * Alias of {@link urlParent}
33
+ * Try to determine the parent directory URL of the uri.
34
+ * If it is not a hierarchical URL, then it will return the URL.
35
+ * @param url - url to extract the dirname from.
36
+ * @returns a URL
37
+ */
38
+ export const urlDirname = urlParent;
31
39
  /**
32
40
  * return the basename (last portion of the URL pathname) of a path. It does NOT remove the trailing slash.
33
41
  * @param path - URL pathname to extract the basename from.
@@ -40,6 +48,9 @@ export function basenameOfUrlPathname(path) {
40
48
  export function isUrlLike(filename) {
41
49
  return filename instanceof URL || isURLRegEx.test(filename);
42
50
  }
51
+ export function isNotUrlLike(filename) {
52
+ return !isUrlLike(filename);
53
+ }
43
54
  /**
44
55
  * Check if `url` is a URL instance.
45
56
  * @returns
@@ -70,4 +81,71 @@ export function addTrailingSlash(url) {
70
81
  urlWithSlash.pathname += '/';
71
82
  return urlWithSlash;
72
83
  }
84
+ /**
85
+ * Remove the filename at the end of the URL pathname.
86
+ * If the URL pathname ends with a `/`, it is considered a directory and the URL is returned as is.
87
+ * If the URL pathname does not start with a `/`, it is considered an non-regular URL and the URL is returned as is.
88
+ * @param url
89
+ * @returns
90
+ */
91
+ export function urlRemoveFilename(url) {
92
+ // Test if it is already a directory or it is not possible to remove the filename.
93
+ if (url.pathname.endsWith('/') || !url.pathname.startsWith('/'))
94
+ return url;
95
+ return new URL('./', url);
96
+ }
97
+ /**
98
+ * Extract the filename from the URL pathname.
99
+ *
100
+ * ```ts
101
+ * url.href === new URL(urlFilename(url), urlRemoveFilename(url)).href
102
+ * ```
103
+ * @param url - URL to extract the filename from.
104
+ * @returns the filename or empty string if the URL pathname ends with a `/`.
105
+ */
106
+ export function urlFilename(url) {
107
+ if (!url.pathname.startsWith('/'))
108
+ return '';
109
+ const lastSlash = url.pathname.lastIndexOf('/');
110
+ return url.pathname.slice(lastSlash + 1);
111
+ }
112
+ /**
113
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
114
+ * The protocol is not evaluated. Only the `url.pathname` is used.
115
+ * @param urlFrom
116
+ * @param urlTo
117
+ * @returns the relative path
118
+ */
119
+ export function urlRelative(urlFrom, urlTo) {
120
+ return urlToUrlRelative(toURL(urlFrom), toURL(urlTo));
121
+ }
122
+ /**
123
+ * Calculate the relative path to go from `urlFrom` to `urlTo`.
124
+ * The protocol is not evaluated. Only the `url.pathname` is used.
125
+ * @param urlFrom
126
+ * @param urlTo
127
+ * @returns the relative path
128
+ */
129
+ export function urlToUrlRelative(urlFrom, urlTo) {
130
+ let pFrom = urlFrom.pathname;
131
+ const pTo = urlTo.pathname;
132
+ if (pFrom === pTo)
133
+ return '';
134
+ pFrom = pFrom.endsWith('/') ? pFrom : new URL('./', urlFrom).pathname;
135
+ if (pTo.startsWith(pFrom))
136
+ return decodeURIComponent(pTo.slice(pFrom.length));
137
+ const p0 = pFrom;
138
+ const p1 = pTo;
139
+ if (p1.startsWith(p0)) {
140
+ return decodeURIComponent(p0 === p1 ? '' : p1.slice(p0.lastIndexOf('/') + 1));
141
+ }
142
+ const p0Parts = p0.split('/').slice(0, -1); // drop the last segment.
143
+ const p1Parts = p1.split('/');
144
+ let i = 0;
145
+ for (i = 0; i < p0Parts.length && i < p1Parts.length - 1 && p0Parts[i] === p1Parts[i]; ++i) {
146
+ // empty
147
+ }
148
+ const rel = '../'.repeat(p0Parts.length - i) + p1Parts.slice(i).join('/');
149
+ return decodeURIComponent(rel.length < p1.length ? rel : p1);
150
+ }
73
151
  //# sourceMappingURL=url.mjs.map
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "8.9.1",
6
+ "version": "8.10.0",
7
7
  "description": "URL parsing and manipulation utilities for cspell",
8
8
  "keywords": [
9
9
  "cspell",
@@ -28,6 +28,8 @@
28
28
  "!**/*.spec.*",
29
29
  "!**/*.test.*",
30
30
  "!**/test/**",
31
+ "!**/*.perf.*",
32
+ "!**/perf/**",
31
33
  "!**/*.map"
32
34
  ],
33
35
  "scripts": {
@@ -38,6 +40,9 @@
38
40
  "coverage": "vitest run --coverage",
39
41
  "test-watch": "vitest",
40
42
  "test": "vitest run",
43
+ "test:perf": "insight --file \"dist/perf/**/*.perf.{mjs,js}\" -t 1000",
44
+ "test:perf:ts": "insight --register ts-node/esm --file \"src/perf/**/*.perf.{mts,ts}\" -t 1000",
45
+ "test:perf:prof": "NODE_ENV=production node --cpu-prof ../../node_modules/perf-insight/bin.mjs --file \"dist/perf/**/*.perf.{mjs,js}\" -t 1000",
41
46
  "watch": "tsc -p . --watch"
42
47
  },
43
48
  "repository": {
@@ -51,5 +56,5 @@
51
56
  "engines": {
52
57
  "node": ">=18.0"
53
58
  },
54
- "gitHead": "f532c77cca4bfae380293c586f02f377354c850b"
59
+ "gitHead": "a5dde6ae7e2ac86ac956220d4b8c39a0e58e1bc6"
55
60
  }