@jsenv/urls 2.0.0 → 2.1.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.
- package/package.json +3 -3
- package/src/caller_position.js +11 -11
- package/src/common_pathname.js +20 -20
- package/src/data_url.js +18 -18
- package/src/ensure_url_trailing_slash.js +2 -2
- package/src/filesystem_path_to_url.js +5 -5
- package/src/inline_content_url_generator.js +18 -7
- package/src/is_filesystem_path.js +10 -10
- package/src/main.js +25 -22
- package/src/move_url.js +7 -7
- package/src/resolve_directory_url.js +5 -5
- package/src/resolve_url.js +3 -3
- package/src/url_is_inside_of.js +9 -9
- package/src/url_to_basename.js +6 -6
- package/src/url_to_extension.js +11 -11
- package/src/url_to_filename.js +7 -7
- package/src/url_to_filesystem_path.js +6 -6
- package/src/url_to_origin.js +4 -4
- package/src/url_to_parent_url.js +20 -17
- package/src/url_to_pathname.js +11 -11
- package/src/url_to_relative_url.js +27 -27
- package/src/url_to_resource.js +11 -11
- package/src/url_to_scheme.js +6 -6
- package/src/url_trace.js +77 -77
- package/src/url_utils.js +133 -59
- package/src/windows_file_path_utils.js +9 -9
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/urls",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
|
-
"url": "https://github.com/jsenv/
|
|
8
|
-
"directory": "packages/urls"
|
|
7
|
+
"url": "https://github.com/jsenv/core",
|
|
8
|
+
"directory": "packages/independent/urls"
|
|
9
9
|
},
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
package/src/caller_position.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { isFileSystemPath } from "./is_filesystem_path.js"
|
|
2
|
-
import { fileSystemPathToUrl } from "./filesystem_path_to_url.js"
|
|
1
|
+
import { isFileSystemPath } from "./is_filesystem_path.js";
|
|
2
|
+
import { fileSystemPathToUrl } from "./filesystem_path_to_url.js";
|
|
3
3
|
|
|
4
4
|
export const getCallerPosition = () => {
|
|
5
|
-
const { prepareStackTrace } = Error
|
|
5
|
+
const { prepareStackTrace } = Error;
|
|
6
6
|
Error.prepareStackTrace = (error, stack) => {
|
|
7
|
-
Error.prepareStackTrace = prepareStackTrace
|
|
8
|
-
return stack
|
|
9
|
-
}
|
|
10
|
-
const { stack } = new Error()
|
|
11
|
-
const callerCallsite = stack[2]
|
|
12
|
-
const fileName = callerCallsite.getFileName()
|
|
7
|
+
Error.prepareStackTrace = prepareStackTrace;
|
|
8
|
+
return stack;
|
|
9
|
+
};
|
|
10
|
+
const { stack } = new Error();
|
|
11
|
+
const callerCallsite = stack[2];
|
|
12
|
+
const fileName = callerCallsite.getFileName();
|
|
13
13
|
return {
|
|
14
14
|
url:
|
|
15
15
|
fileName && isFileSystemPath(fileName)
|
|
@@ -17,5 +17,5 @@ export const getCallerPosition = () => {
|
|
|
17
17
|
: fileName,
|
|
18
18
|
line: callerCallsite.getLineNumber(),
|
|
19
19
|
column: callerCallsite.getColumnNumber(),
|
|
20
|
-
}
|
|
21
|
-
}
|
|
20
|
+
};
|
|
21
|
+
};
|
package/src/common_pathname.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
export const getCommonPathname = (pathname, otherPathname) => {
|
|
2
2
|
if (pathname === otherPathname) {
|
|
3
|
-
return pathname
|
|
3
|
+
return pathname;
|
|
4
4
|
}
|
|
5
|
-
let commonPart = ""
|
|
6
|
-
let commonPathname = ""
|
|
7
|
-
let i = 0
|
|
8
|
-
const length = pathname.length
|
|
9
|
-
const otherLength = otherPathname.length
|
|
5
|
+
let commonPart = "";
|
|
6
|
+
let commonPathname = "";
|
|
7
|
+
let i = 0;
|
|
8
|
+
const length = pathname.length;
|
|
9
|
+
const otherLength = otherPathname.length;
|
|
10
10
|
while (i < length) {
|
|
11
|
-
const char = pathname.charAt(i)
|
|
12
|
-
const otherChar = otherPathname.charAt(i)
|
|
13
|
-
i
|
|
11
|
+
const char = pathname.charAt(i);
|
|
12
|
+
const otherChar = otherPathname.charAt(i);
|
|
13
|
+
i++;
|
|
14
14
|
if (char === otherChar) {
|
|
15
15
|
if (char === "/") {
|
|
16
|
-
commonPart += "/"
|
|
17
|
-
commonPathname += commonPart
|
|
18
|
-
commonPart = ""
|
|
16
|
+
commonPart += "/";
|
|
17
|
+
commonPathname += commonPart;
|
|
18
|
+
commonPart = "";
|
|
19
19
|
} else {
|
|
20
|
-
commonPart += char
|
|
20
|
+
commonPart += char;
|
|
21
21
|
}
|
|
22
22
|
} else {
|
|
23
23
|
if (char === "/" && i - 1 === otherLength) {
|
|
24
|
-
commonPart += "/"
|
|
25
|
-
commonPathname += commonPart
|
|
24
|
+
commonPart += "/";
|
|
25
|
+
commonPathname += commonPart;
|
|
26
26
|
}
|
|
27
|
-
return commonPathname
|
|
27
|
+
return commonPathname;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
if (length === otherLength) {
|
|
31
|
-
commonPathname += commonPart
|
|
31
|
+
commonPathname += commonPart;
|
|
32
32
|
} else if (otherPathname.charAt(i) === "/") {
|
|
33
|
-
commonPathname += commonPart
|
|
33
|
+
commonPathname += commonPart;
|
|
34
34
|
}
|
|
35
|
-
return commonPathname
|
|
36
|
-
}
|
|
35
|
+
return commonPathname;
|
|
36
|
+
};
|
package/src/data_url.js
CHANGED
|
@@ -7,44 +7,44 @@
|
|
|
7
7
|
|
|
8
8
|
export const DATA_URL = {
|
|
9
9
|
parse: (string) => {
|
|
10
|
-
const afterDataProtocol = string.slice("data:".length)
|
|
11
|
-
const commaIndex = afterDataProtocol.indexOf(",")
|
|
12
|
-
const beforeComma = afterDataProtocol.slice(0, commaIndex)
|
|
10
|
+
const afterDataProtocol = string.slice("data:".length);
|
|
11
|
+
const commaIndex = afterDataProtocol.indexOf(",");
|
|
12
|
+
const beforeComma = afterDataProtocol.slice(0, commaIndex);
|
|
13
13
|
|
|
14
|
-
let contentType
|
|
15
|
-
let base64Flag
|
|
14
|
+
let contentType;
|
|
15
|
+
let base64Flag;
|
|
16
16
|
if (beforeComma.endsWith(`;base64`)) {
|
|
17
|
-
contentType = beforeComma.slice(0, -`;base64`.length)
|
|
18
|
-
base64Flag = true
|
|
17
|
+
contentType = beforeComma.slice(0, -`;base64`.length);
|
|
18
|
+
base64Flag = true;
|
|
19
19
|
} else {
|
|
20
|
-
contentType = beforeComma
|
|
21
|
-
base64Flag = false
|
|
20
|
+
contentType = beforeComma;
|
|
21
|
+
base64Flag = false;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
contentType =
|
|
25
|
-
contentType === "" ? "text/plain;charset=US-ASCII" : contentType
|
|
26
|
-
const afterComma = afterDataProtocol.slice(commaIndex + 1)
|
|
25
|
+
contentType === "" ? "text/plain;charset=US-ASCII" : contentType;
|
|
26
|
+
const afterComma = afterDataProtocol.slice(commaIndex + 1);
|
|
27
27
|
return {
|
|
28
28
|
contentType,
|
|
29
29
|
base64Flag,
|
|
30
30
|
data: afterComma,
|
|
31
|
-
}
|
|
31
|
+
};
|
|
32
32
|
},
|
|
33
33
|
|
|
34
34
|
stringify: ({ contentType, base64Flag = true, data }) => {
|
|
35
35
|
if (!contentType || contentType === "text/plain;charset=US-ASCII") {
|
|
36
36
|
// can be a buffer or a string, hence check on data.length instead of !data or data === ''
|
|
37
37
|
if (data.length === 0) {
|
|
38
|
-
return `data
|
|
38
|
+
return `data:,`;
|
|
39
39
|
}
|
|
40
40
|
if (base64Flag) {
|
|
41
|
-
return `data:;base64,${data}
|
|
41
|
+
return `data:;base64,${data}`;
|
|
42
42
|
}
|
|
43
|
-
return `data:,${data}
|
|
43
|
+
return `data:,${data}`;
|
|
44
44
|
}
|
|
45
45
|
if (base64Flag) {
|
|
46
|
-
return `data:${contentType};base64,${data}
|
|
46
|
+
return `data:${contentType};base64,${data}`;
|
|
47
47
|
}
|
|
48
|
-
return `data:${contentType},${data}
|
|
48
|
+
return `data:${contentType},${data}`;
|
|
49
49
|
},
|
|
50
|
-
}
|
|
50
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export const ensureUrlTrailingSlash = (url) => {
|
|
2
|
-
return url.endsWith("/") ? url : `${url}
|
|
3
|
-
}
|
|
2
|
+
return url.endsWith("/") ? url : `${url}/`;
|
|
3
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { pathToFileURL } from "node:url"
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
2
|
|
|
3
|
-
import { isFileSystemPath } from "./is_filesystem_path.js"
|
|
3
|
+
import { isFileSystemPath } from "./is_filesystem_path.js";
|
|
4
4
|
|
|
5
5
|
export const fileSystemPathToUrl = (value) => {
|
|
6
6
|
if (!isFileSystemPath(value)) {
|
|
7
|
-
throw new Error(`value must be a filesystem path, got ${value}`)
|
|
7
|
+
throw new Error(`value must be a filesystem path, got ${value}`);
|
|
8
8
|
}
|
|
9
|
-
return String(pathToFileURL(value))
|
|
10
|
-
}
|
|
9
|
+
return String(pathToFileURL(value));
|
|
10
|
+
};
|
|
@@ -1,18 +1,29 @@
|
|
|
1
|
-
import { urlToFilename } from "./url_to_filename.js"
|
|
1
|
+
import { urlToFilename } from "./url_to_filename.js";
|
|
2
2
|
|
|
3
3
|
export const generateInlineContentUrl = ({
|
|
4
4
|
url,
|
|
5
5
|
extension,
|
|
6
|
+
basename,
|
|
6
7
|
line,
|
|
7
8
|
column,
|
|
8
9
|
lineEnd,
|
|
9
10
|
columnEnd,
|
|
10
11
|
}) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
let generatedName = "";
|
|
13
|
+
if (basename !== undefined) {
|
|
14
|
+
generatedName += basename;
|
|
15
|
+
}
|
|
16
|
+
if (line !== undefined && column !== undefined) {
|
|
17
|
+
generatedName = `L${line}C${column}`;
|
|
18
|
+
if (lineEnd !== undefined && columnEnd !== undefined) {
|
|
19
|
+
generatedName += `-L${lineEnd}C${columnEnd}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const filenameRaw = urlToFilename(url);
|
|
24
|
+
const filename = `${filenameRaw}@${generatedName}${extension}`;
|
|
14
25
|
// ideally we should keep query params from url
|
|
15
26
|
// maybe we could use a custom scheme like "inline:"
|
|
16
|
-
const inlineContentUrl = new URL(filename, url).href
|
|
17
|
-
return inlineContentUrl
|
|
18
|
-
}
|
|
27
|
+
const inlineContentUrl = new URL(filename, url).href;
|
|
28
|
+
return inlineContentUrl;
|
|
29
|
+
};
|
|
@@ -2,20 +2,20 @@ export const isFileSystemPath = (value) => {
|
|
|
2
2
|
if (typeof value !== "string") {
|
|
3
3
|
throw new TypeError(
|
|
4
4
|
`isFileSystemPath first arg must be a string, got ${value}`,
|
|
5
|
-
)
|
|
5
|
+
);
|
|
6
6
|
}
|
|
7
7
|
if (value[0] === "/") {
|
|
8
|
-
return true
|
|
8
|
+
return true;
|
|
9
9
|
}
|
|
10
|
-
return startsWithWindowsDriveLetter(value)
|
|
11
|
-
}
|
|
10
|
+
return startsWithWindowsDriveLetter(value);
|
|
11
|
+
};
|
|
12
12
|
|
|
13
13
|
const startsWithWindowsDriveLetter = (string) => {
|
|
14
|
-
const firstChar = string[0]
|
|
15
|
-
if (!/[a-zA-Z]/.test(firstChar)) return false
|
|
14
|
+
const firstChar = string[0];
|
|
15
|
+
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
16
16
|
|
|
17
|
-
const secondChar = string[1]
|
|
18
|
-
if (secondChar !== ":") return false
|
|
17
|
+
const secondChar = string[1];
|
|
18
|
+
if (secondChar !== ":") return false;
|
|
19
19
|
|
|
20
|
-
return true
|
|
21
|
-
}
|
|
20
|
+
return true;
|
|
21
|
+
};
|
package/src/main.js
CHANGED
|
@@ -1,41 +1,44 @@
|
|
|
1
|
-
export { DATA_URL } from "./data_url.js"
|
|
2
|
-
export { generateInlineContentUrl } from "./inline_content_url_generator.js"
|
|
1
|
+
export { DATA_URL } from "./data_url.js";
|
|
2
|
+
export { generateInlineContentUrl } from "./inline_content_url_generator.js";
|
|
3
3
|
export {
|
|
4
4
|
stringifyUrlTrace,
|
|
5
5
|
stringifyUrlSite,
|
|
6
6
|
showSourceLocation,
|
|
7
|
-
} from "./url_trace.js"
|
|
7
|
+
} from "./url_trace.js";
|
|
8
8
|
export {
|
|
9
9
|
asUrlWithoutSearch,
|
|
10
10
|
isValidUrl,
|
|
11
11
|
normalizeUrl,
|
|
12
12
|
injectQueryParamsIntoSpecifier,
|
|
13
13
|
injectQueryParams,
|
|
14
|
+
injectQueryParamWithoutEncoding,
|
|
15
|
+
injectQueryParamIntoSpecifierWithoutEncoding,
|
|
16
|
+
renderUrlOrRelativeUrlFilename,
|
|
14
17
|
setUrlExtension,
|
|
15
18
|
setUrlFilename,
|
|
16
19
|
ensurePathnameTrailingSlash,
|
|
17
20
|
asUrlUntilPathname,
|
|
18
|
-
} from "./url_utils.js"
|
|
21
|
+
} from "./url_utils.js";
|
|
19
22
|
export {
|
|
20
23
|
startsWithWindowsDriveLetter,
|
|
21
24
|
windowsFilePathToUrl,
|
|
22
25
|
replaceBackSlashesWithSlashes,
|
|
23
|
-
} from "./windows_file_path_utils.js"
|
|
24
|
-
export { getCallerPosition } from "./caller_position.js"
|
|
26
|
+
} from "./windows_file_path_utils.js";
|
|
27
|
+
export { getCallerPosition } from "./caller_position.js";
|
|
25
28
|
|
|
26
|
-
export { fileSystemPathToUrl } from "./filesystem_path_to_url.js"
|
|
27
|
-
export { isFileSystemPath } from "./is_filesystem_path.js"
|
|
28
|
-
export { resolveDirectoryUrl } from "./resolve_directory_url.js"
|
|
29
|
-
export { moveUrl } from "./move_url.js"
|
|
30
|
-
export { resolveUrl } from "./resolve_url.js"
|
|
31
|
-
export { urlIsInsideOf } from "./url_is_inside_of.js"
|
|
32
|
-
export { urlToBasename } from "./url_to_basename.js"
|
|
33
|
-
export { urlToExtension } from "./url_to_extension.js"
|
|
34
|
-
export { urlToFilename } from "./url_to_filename.js"
|
|
35
|
-
export { urlToFileSystemPath } from "./url_to_filesystem_path.js"
|
|
36
|
-
export { urlToOrigin } from "./url_to_origin.js"
|
|
37
|
-
export { urlToParentUrl } from "./url_to_parent_url.js"
|
|
38
|
-
export { urlToPathname } from "./url_to_pathname.js"
|
|
39
|
-
export { urlToRelativeUrl } from "./url_to_relative_url.js"
|
|
40
|
-
export { urlToResource } from "./url_to_resource.js"
|
|
41
|
-
export { urlToScheme } from "./url_to_scheme.js"
|
|
29
|
+
export { fileSystemPathToUrl } from "./filesystem_path_to_url.js";
|
|
30
|
+
export { isFileSystemPath } from "./is_filesystem_path.js";
|
|
31
|
+
export { resolveDirectoryUrl } from "./resolve_directory_url.js";
|
|
32
|
+
export { moveUrl } from "./move_url.js";
|
|
33
|
+
export { resolveUrl } from "./resolve_url.js";
|
|
34
|
+
export { urlIsInsideOf } from "./url_is_inside_of.js";
|
|
35
|
+
export { urlToBasename } from "./url_to_basename.js";
|
|
36
|
+
export { urlToExtension } from "./url_to_extension.js";
|
|
37
|
+
export { urlToFilename } from "./url_to_filename.js";
|
|
38
|
+
export { urlToFileSystemPath } from "./url_to_filesystem_path.js";
|
|
39
|
+
export { urlToOrigin } from "./url_to_origin.js";
|
|
40
|
+
export { urlToParentUrl } from "./url_to_parent_url.js";
|
|
41
|
+
export { urlToPathname } from "./url_to_pathname.js";
|
|
42
|
+
export { urlToRelativeUrl } from "./url_to_relative_url.js";
|
|
43
|
+
export { urlToResource } from "./url_to_resource.js";
|
|
44
|
+
export { urlToScheme } from "./url_to_scheme.js";
|
package/src/move_url.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { urlToRelativeUrl } from "./url_to_relative_url.js"
|
|
1
|
+
import { urlToRelativeUrl } from "./url_to_relative_url.js";
|
|
2
2
|
|
|
3
3
|
export const moveUrl = ({ url, from, to, preferRelative }) => {
|
|
4
|
-
let relativeUrl = urlToRelativeUrl(url, from)
|
|
4
|
+
let relativeUrl = urlToRelativeUrl(url, from);
|
|
5
5
|
if (relativeUrl.slice(0, 2) === "//") {
|
|
6
6
|
// restore the protocol
|
|
7
|
-
relativeUrl = new URL(relativeUrl, url).href
|
|
7
|
+
relativeUrl = new URL(relativeUrl, url).href;
|
|
8
8
|
}
|
|
9
|
-
const absoluteUrl = new URL(relativeUrl, to).href
|
|
9
|
+
const absoluteUrl = new URL(relativeUrl, to).href;
|
|
10
10
|
if (preferRelative) {
|
|
11
|
-
return urlToRelativeUrl(absoluteUrl, to)
|
|
11
|
+
return urlToRelativeUrl(absoluteUrl, to);
|
|
12
12
|
}
|
|
13
|
-
return absoluteUrl
|
|
14
|
-
}
|
|
13
|
+
return absoluteUrl;
|
|
14
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ensurePathnameTrailingSlash } from "./url_utils.js"
|
|
2
|
-
import { resolveUrl } from "./resolve_url.js"
|
|
1
|
+
import { ensurePathnameTrailingSlash } from "./url_utils.js";
|
|
2
|
+
import { resolveUrl } from "./resolve_url.js";
|
|
3
3
|
|
|
4
4
|
export const resolveDirectoryUrl = (specifier, baseUrl) => {
|
|
5
|
-
const url = resolveUrl(specifier, baseUrl)
|
|
6
|
-
return ensurePathnameTrailingSlash(url)
|
|
7
|
-
}
|
|
5
|
+
const url = resolveUrl(specifier, baseUrl);
|
|
6
|
+
return ensurePathnameTrailingSlash(url);
|
|
7
|
+
};
|
package/src/resolve_url.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const resolveUrl = (specifier, baseUrl) => {
|
|
2
2
|
if (typeof baseUrl === "undefined") {
|
|
3
|
-
throw new TypeError(`baseUrl missing to resolve ${specifier}`)
|
|
3
|
+
throw new TypeError(`baseUrl missing to resolve ${specifier}`);
|
|
4
4
|
}
|
|
5
|
-
return String(new URL(specifier, baseUrl))
|
|
6
|
-
}
|
|
5
|
+
return String(new URL(specifier, baseUrl));
|
|
6
|
+
};
|
package/src/url_is_inside_of.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export const urlIsInsideOf = (url, otherUrl) => {
|
|
2
|
-
const urlObject = new URL(url)
|
|
3
|
-
const otherUrlObject = new URL(otherUrl)
|
|
2
|
+
const urlObject = new URL(url);
|
|
3
|
+
const otherUrlObject = new URL(otherUrl);
|
|
4
4
|
|
|
5
5
|
if (urlObject.origin !== otherUrlObject.origin) {
|
|
6
|
-
return false
|
|
6
|
+
return false;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const urlPathname = urlObject.pathname
|
|
10
|
-
const otherUrlPathname = otherUrlObject.pathname
|
|
9
|
+
const urlPathname = urlObject.pathname;
|
|
10
|
+
const otherUrlPathname = otherUrlObject.pathname;
|
|
11
11
|
if (urlPathname === otherUrlPathname) {
|
|
12
|
-
return false
|
|
12
|
+
return false;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const isInside = urlPathname.startsWith(otherUrlPathname)
|
|
16
|
-
return isInside
|
|
17
|
-
}
|
|
15
|
+
const isInside = urlPathname.startsWith(otherUrlPathname);
|
|
16
|
+
return isInside;
|
|
17
|
+
};
|
package/src/url_to_basename.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { urlToFilename } from "./url_to_filename.js"
|
|
1
|
+
import { urlToFilename } from "./url_to_filename.js";
|
|
2
2
|
|
|
3
3
|
export const urlToBasename = (url) => {
|
|
4
|
-
const filename = urlToFilename(url)
|
|
5
|
-
const dotLastIndex = filename.lastIndexOf(".")
|
|
4
|
+
const filename = urlToFilename(url);
|
|
5
|
+
const dotLastIndex = filename.lastIndexOf(".");
|
|
6
6
|
const basename =
|
|
7
|
-
dotLastIndex === -1 ? filename : filename.slice(0, dotLastIndex)
|
|
8
|
-
return basename
|
|
9
|
-
}
|
|
7
|
+
dotLastIndex === -1 ? filename : filename.slice(0, dotLastIndex);
|
|
8
|
+
return basename;
|
|
9
|
+
};
|
package/src/url_to_extension.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { urlToPathname } from "./url_to_pathname.js"
|
|
1
|
+
import { urlToPathname } from "./url_to_pathname.js";
|
|
2
2
|
|
|
3
3
|
export const urlToExtension = (url) => {
|
|
4
|
-
const pathname = urlToPathname(url)
|
|
5
|
-
return pathnameToExtension(pathname)
|
|
6
|
-
}
|
|
4
|
+
const pathname = urlToPathname(url);
|
|
5
|
+
return pathnameToExtension(pathname);
|
|
6
|
+
};
|
|
7
7
|
|
|
8
8
|
const pathnameToExtension = (pathname) => {
|
|
9
|
-
const slashLastIndex = pathname.lastIndexOf("/")
|
|
9
|
+
const slashLastIndex = pathname.lastIndexOf("/");
|
|
10
10
|
if (slashLastIndex !== -1) {
|
|
11
|
-
pathname = pathname.slice(slashLastIndex + 1)
|
|
11
|
+
pathname = pathname.slice(slashLastIndex + 1);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const dotLastIndex = pathname.lastIndexOf(".")
|
|
15
|
-
if (dotLastIndex === -1) return ""
|
|
14
|
+
const dotLastIndex = pathname.lastIndexOf(".");
|
|
15
|
+
if (dotLastIndex === -1) return "";
|
|
16
16
|
// if (dotLastIndex === pathname.length - 1) return ""
|
|
17
|
-
const extension = pathname.slice(dotLastIndex)
|
|
18
|
-
return extension
|
|
19
|
-
}
|
|
17
|
+
const extension = pathname.slice(dotLastIndex);
|
|
18
|
+
return extension;
|
|
19
|
+
};
|
package/src/url_to_filename.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { urlToPathname } from "./url_to_pathname.js"
|
|
1
|
+
import { urlToPathname } from "./url_to_pathname.js";
|
|
2
2
|
|
|
3
3
|
export const urlToFilename = (url) => {
|
|
4
|
-
const pathname = urlToPathname(url)
|
|
4
|
+
const pathname = urlToPathname(url);
|
|
5
5
|
const pathnameBeforeLastSlash = pathname.endsWith("/")
|
|
6
6
|
? pathname.slice(0, -1)
|
|
7
|
-
: pathname
|
|
8
|
-
const slashLastIndex = pathnameBeforeLastSlash.lastIndexOf("/")
|
|
7
|
+
: pathname;
|
|
8
|
+
const slashLastIndex = pathnameBeforeLastSlash.lastIndexOf("/");
|
|
9
9
|
const filename =
|
|
10
10
|
slashLastIndex === -1
|
|
11
11
|
? pathnameBeforeLastSlash
|
|
12
|
-
: pathnameBeforeLastSlash.slice(slashLastIndex + 1)
|
|
13
|
-
return filename
|
|
14
|
-
}
|
|
12
|
+
: pathnameBeforeLastSlash.slice(slashLastIndex + 1);
|
|
13
|
+
return filename;
|
|
14
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { fileURLToPath } from "node:url"
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
2
|
|
|
3
3
|
export const urlToFileSystemPath = (url) => {
|
|
4
|
-
let urlString = String(url)
|
|
4
|
+
let urlString = String(url);
|
|
5
5
|
if (urlString[urlString.length - 1] === "/") {
|
|
6
6
|
// remove trailing / so that nodejs path becomes predictable otherwise it logs
|
|
7
7
|
// the trailing slash on linux but does not on windows
|
|
8
|
-
urlString = urlString.slice(0, -1)
|
|
8
|
+
urlString = urlString.slice(0, -1);
|
|
9
9
|
}
|
|
10
|
-
const fileSystemPath = fileURLToPath(urlString)
|
|
11
|
-
return fileSystemPath
|
|
12
|
-
}
|
|
10
|
+
const fileSystemPath = fileURLToPath(urlString);
|
|
11
|
+
return fileSystemPath;
|
|
12
|
+
};
|
package/src/url_to_origin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const urlToOrigin = (url) => {
|
|
2
|
-
const urlString = String(url)
|
|
2
|
+
const urlString = String(url);
|
|
3
3
|
if (urlString.startsWith("file://")) {
|
|
4
|
-
return `file
|
|
4
|
+
return `file://`;
|
|
5
5
|
}
|
|
6
|
-
return new URL(urlString).origin
|
|
7
|
-
}
|
|
6
|
+
return new URL(urlString).origin;
|
|
7
|
+
};
|
package/src/url_to_parent_url.js
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
|
-
import { urlToOrigin } from "./url_to_origin.js"
|
|
2
|
-
import { urlToResource } from "./url_to_resource.js"
|
|
1
|
+
import { urlToOrigin } from "./url_to_origin.js";
|
|
2
|
+
import { urlToResource } from "./url_to_resource.js";
|
|
3
3
|
|
|
4
4
|
export const urlToParentUrl = (url) => {
|
|
5
|
-
const resource = urlToResource(url)
|
|
6
|
-
const slashLastIndex = resource.lastIndexOf("/")
|
|
5
|
+
const resource = urlToResource(url);
|
|
6
|
+
const slashLastIndex = resource.lastIndexOf("/");
|
|
7
7
|
if (slashLastIndex === -1) {
|
|
8
|
-
const urlAsString = String(url)
|
|
9
|
-
return urlAsString
|
|
8
|
+
const urlAsString = String(url);
|
|
9
|
+
return urlAsString;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const lastCharacterIndex = resource.length - 1
|
|
12
|
+
const lastCharacterIndex = resource.length - 1;
|
|
13
13
|
if (slashLastIndex === lastCharacterIndex) {
|
|
14
|
-
const slashPreviousIndex = resource.lastIndexOf(
|
|
14
|
+
const slashPreviousIndex = resource.lastIndexOf(
|
|
15
|
+
"/",
|
|
16
|
+
lastCharacterIndex - 1,
|
|
17
|
+
);
|
|
15
18
|
if (slashPreviousIndex === -1) {
|
|
16
|
-
const urlAsString = String(url)
|
|
17
|
-
return urlAsString
|
|
19
|
+
const urlAsString = String(url);
|
|
20
|
+
return urlAsString;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
const origin = urlToOrigin(url)
|
|
21
|
-
const parentUrl = `${origin}${resource.slice(0, slashPreviousIndex + 1)}
|
|
22
|
-
return parentUrl
|
|
23
|
+
const origin = urlToOrigin(url);
|
|
24
|
+
const parentUrl = `${origin}${resource.slice(0, slashPreviousIndex + 1)}`;
|
|
25
|
+
return parentUrl;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
const origin = urlToOrigin(url)
|
|
26
|
-
const parentUrl = `${origin}${resource.slice(0, slashLastIndex + 1)}
|
|
27
|
-
return parentUrl
|
|
28
|
-
}
|
|
28
|
+
const origin = urlToOrigin(url);
|
|
29
|
+
const parentUrl = `${origin}${resource.slice(0, slashLastIndex + 1)}`;
|
|
30
|
+
return parentUrl;
|
|
31
|
+
};
|
package/src/url_to_pathname.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { urlToResource } from "./url_to_resource.js"
|
|
1
|
+
import { urlToResource } from "./url_to_resource.js";
|
|
2
2
|
|
|
3
3
|
export const urlToPathname = (url) => {
|
|
4
|
-
const resource = urlToResource(url)
|
|
5
|
-
const pathname = resourceToPathname(resource)
|
|
6
|
-
return pathname
|
|
7
|
-
}
|
|
4
|
+
const resource = urlToResource(url);
|
|
5
|
+
const pathname = resourceToPathname(resource);
|
|
6
|
+
return pathname;
|
|
7
|
+
};
|
|
8
8
|
|
|
9
9
|
const resourceToPathname = (resource) => {
|
|
10
|
-
const searchSeparatorIndex = resource.indexOf("?")
|
|
10
|
+
const searchSeparatorIndex = resource.indexOf("?");
|
|
11
11
|
if (searchSeparatorIndex > -1) {
|
|
12
|
-
return resource.slice(0, searchSeparatorIndex)
|
|
12
|
+
return resource.slice(0, searchSeparatorIndex);
|
|
13
13
|
}
|
|
14
|
-
const hashIndex = resource.indexOf("#")
|
|
14
|
+
const hashIndex = resource.indexOf("#");
|
|
15
15
|
if (hashIndex > -1) {
|
|
16
|
-
return resource.slice(0, hashIndex)
|
|
16
|
+
return resource.slice(0, hashIndex);
|
|
17
17
|
}
|
|
18
|
-
return resource
|
|
19
|
-
}
|
|
18
|
+
return resource;
|
|
19
|
+
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { getCommonPathname } from "./common_pathname.js"
|
|
1
|
+
import { getCommonPathname } from "./common_pathname.js";
|
|
2
2
|
|
|
3
3
|
export const urlToRelativeUrl = (url, baseUrl) => {
|
|
4
|
-
const urlObject = new URL(url)
|
|
5
|
-
const baseUrlObject = new URL(baseUrl)
|
|
4
|
+
const urlObject = new URL(url);
|
|
5
|
+
const baseUrlObject = new URL(baseUrl);
|
|
6
6
|
|
|
7
7
|
if (urlObject.protocol !== baseUrlObject.protocol) {
|
|
8
|
-
const urlAsString = String(url)
|
|
9
|
-
return urlAsString
|
|
8
|
+
const urlAsString = String(url);
|
|
9
|
+
return urlAsString;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
if (
|
|
@@ -14,43 +14,43 @@ export const urlToRelativeUrl = (url, baseUrl) => {
|
|
|
14
14
|
urlObject.password !== baseUrlObject.password ||
|
|
15
15
|
urlObject.host !== baseUrlObject.host
|
|
16
16
|
) {
|
|
17
|
-
const afterUrlScheme = String(url).slice(urlObject.protocol.length)
|
|
18
|
-
return afterUrlScheme
|
|
17
|
+
const afterUrlScheme = String(url).slice(urlObject.protocol.length);
|
|
18
|
+
return afterUrlScheme;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const { pathname, hash, search } = urlObject
|
|
21
|
+
const { pathname, hash, search } = urlObject;
|
|
22
22
|
if (pathname === "/") {
|
|
23
|
-
const baseUrlResourceWithoutLeadingSlash = baseUrlObject.pathname.slice(1)
|
|
24
|
-
return baseUrlResourceWithoutLeadingSlash
|
|
23
|
+
const baseUrlResourceWithoutLeadingSlash = baseUrlObject.pathname.slice(1);
|
|
24
|
+
return baseUrlResourceWithoutLeadingSlash;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const basePathname = baseUrlObject.pathname
|
|
28
|
-
const commonPathname = getCommonPathname(pathname, basePathname)
|
|
27
|
+
const basePathname = baseUrlObject.pathname;
|
|
28
|
+
const commonPathname = getCommonPathname(pathname, basePathname);
|
|
29
29
|
if (!commonPathname) {
|
|
30
|
-
const urlAsString = String(url)
|
|
31
|
-
return urlAsString
|
|
30
|
+
const urlAsString = String(url);
|
|
31
|
+
return urlAsString;
|
|
32
32
|
}
|
|
33
|
-
const specificPathname = pathname.slice(commonPathname.length)
|
|
34
|
-
const baseSpecificPathname = basePathname.slice(commonPathname.length)
|
|
33
|
+
const specificPathname = pathname.slice(commonPathname.length);
|
|
34
|
+
const baseSpecificPathname = basePathname.slice(commonPathname.length);
|
|
35
35
|
if (baseSpecificPathname.includes("/")) {
|
|
36
36
|
const baseSpecificParentPathname =
|
|
37
|
-
pathnameToParentPathname(baseSpecificPathname)
|
|
37
|
+
pathnameToParentPathname(baseSpecificPathname);
|
|
38
38
|
const relativeDirectoriesNotation = baseSpecificParentPathname.replace(
|
|
39
39
|
/.*?\//g,
|
|
40
40
|
"../",
|
|
41
|
-
)
|
|
42
|
-
const relativeUrl = `${relativeDirectoriesNotation}${specificPathname}${search}${hash}
|
|
43
|
-
return relativeUrl
|
|
41
|
+
);
|
|
42
|
+
const relativeUrl = `${relativeDirectoriesNotation}${specificPathname}${search}${hash}`;
|
|
43
|
+
return relativeUrl;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const relativeUrl = `${specificPathname}${search}${hash}
|
|
47
|
-
return relativeUrl
|
|
48
|
-
}
|
|
46
|
+
const relativeUrl = `${specificPathname}${search}${hash}`;
|
|
47
|
+
return relativeUrl;
|
|
48
|
+
};
|
|
49
49
|
|
|
50
50
|
const pathnameToParentPathname = (pathname) => {
|
|
51
|
-
const slashLastIndex = pathname.lastIndexOf("/")
|
|
51
|
+
const slashLastIndex = pathname.lastIndexOf("/");
|
|
52
52
|
if (slashLastIndex === -1) {
|
|
53
|
-
return "/"
|
|
53
|
+
return "/";
|
|
54
54
|
}
|
|
55
|
-
return pathname.slice(0, slashLastIndex + 1)
|
|
56
|
-
}
|
|
55
|
+
return pathname.slice(0, slashLastIndex + 1);
|
|
56
|
+
};
|
package/src/url_to_resource.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { urlToScheme } from "./url_to_scheme.js"
|
|
1
|
+
import { urlToScheme } from "./url_to_scheme.js";
|
|
2
2
|
|
|
3
3
|
export const urlToResource = (url) => {
|
|
4
|
-
const scheme = urlToScheme(url)
|
|
4
|
+
const scheme = urlToScheme(url);
|
|
5
5
|
|
|
6
6
|
if (scheme === "file") {
|
|
7
|
-
const urlAsStringWithoutFileProtocol = String(url).slice("file://".length)
|
|
8
|
-
return urlAsStringWithoutFileProtocol
|
|
7
|
+
const urlAsStringWithoutFileProtocol = String(url).slice("file://".length);
|
|
8
|
+
return urlAsStringWithoutFileProtocol;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
if (scheme === "https" || scheme === "http") {
|
|
12
12
|
// remove origin
|
|
13
|
-
const afterProtocol = String(url).slice(scheme.length + "://".length)
|
|
14
|
-
const pathnameSlashIndex = afterProtocol.indexOf("/", "://".length)
|
|
15
|
-
const urlAsStringWithoutOrigin = afterProtocol.slice(pathnameSlashIndex)
|
|
16
|
-
return urlAsStringWithoutOrigin
|
|
13
|
+
const afterProtocol = String(url).slice(scheme.length + "://".length);
|
|
14
|
+
const pathnameSlashIndex = afterProtocol.indexOf("/", "://".length);
|
|
15
|
+
const urlAsStringWithoutOrigin = afterProtocol.slice(pathnameSlashIndex);
|
|
16
|
+
return urlAsStringWithoutOrigin;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const urlAsStringWithoutProtocol = String(url).slice(scheme.length + 1)
|
|
20
|
-
return urlAsStringWithoutProtocol
|
|
21
|
-
}
|
|
19
|
+
const urlAsStringWithoutProtocol = String(url).slice(scheme.length + 1);
|
|
20
|
+
return urlAsStringWithoutProtocol;
|
|
21
|
+
};
|
package/src/url_to_scheme.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export const urlToScheme = (url) => {
|
|
2
|
-
const urlString = String(url)
|
|
3
|
-
const colonIndex = urlString.indexOf(":")
|
|
2
|
+
const urlString = String(url);
|
|
3
|
+
const colonIndex = urlString.indexOf(":");
|
|
4
4
|
if (colonIndex === -1) {
|
|
5
|
-
return ""
|
|
5
|
+
return "";
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const scheme = urlString.slice(0, colonIndex)
|
|
9
|
-
return scheme
|
|
10
|
-
}
|
|
8
|
+
const scheme = urlString.slice(0, colonIndex);
|
|
9
|
+
return scheme;
|
|
10
|
+
};
|
package/src/url_trace.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// https://github.com/babel/babel/blob/eea156b2cb8deecfcf82d52aa1b71ba4995c7d68/packages/babel-code-frame/src/index.js#L1
|
|
5
5
|
|
|
6
6
|
export const stringifyUrlTrace = (trace) => {
|
|
7
|
-
let string = ""
|
|
7
|
+
let string = "";
|
|
8
8
|
trace.forEach(({ type, url, line, column, source }, index) => {
|
|
9
9
|
if (index === 0) {
|
|
10
|
-
string += stringifyUrlSite({ url, line, column, source })
|
|
11
|
-
return
|
|
10
|
+
string += stringifyUrlSite({ url, line, column, source });
|
|
11
|
+
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
if (type === "import") {
|
|
@@ -16,19 +16,19 @@ export const stringifyUrlTrace = (trace) => {
|
|
|
16
16
|
url,
|
|
17
17
|
line,
|
|
18
18
|
column,
|
|
19
|
-
})}
|
|
20
|
-
return
|
|
19
|
+
})}`;
|
|
20
|
+
return;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
string += `\n referenced by ${stringifyUrlSite({
|
|
24
24
|
url,
|
|
25
25
|
line,
|
|
26
26
|
column,
|
|
27
|
-
})}
|
|
28
|
-
}, "")
|
|
27
|
+
})}`;
|
|
28
|
+
}, "");
|
|
29
29
|
|
|
30
|
-
return string
|
|
31
|
-
}
|
|
30
|
+
return string;
|
|
31
|
+
};
|
|
32
32
|
|
|
33
33
|
export const stringifyUrlSite = (
|
|
34
34
|
{ url, line, column, content },
|
|
@@ -39,17 +39,17 @@ export const stringifyUrlSite = (
|
|
|
39
39
|
color,
|
|
40
40
|
} = {},
|
|
41
41
|
) => {
|
|
42
|
-
let string = url
|
|
42
|
+
let string = url;
|
|
43
43
|
|
|
44
44
|
if (typeof line === "number") {
|
|
45
|
-
string += `:${line}
|
|
45
|
+
string += `:${line}`;
|
|
46
46
|
if (typeof column === "number") {
|
|
47
|
-
string += `:${column}
|
|
47
|
+
string += `:${column}`;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (!showCodeFrame || typeof line !== "number" || !content) {
|
|
52
|
-
return string
|
|
52
|
+
return string;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const sourceLoc = showSourceLocation({
|
|
@@ -59,11 +59,11 @@ export const stringifyUrlSite = (
|
|
|
59
59
|
numberOfSurroundingLinesToShow,
|
|
60
60
|
lineMaxLength,
|
|
61
61
|
color,
|
|
62
|
-
})
|
|
62
|
+
});
|
|
63
63
|
|
|
64
64
|
return `${string}
|
|
65
|
-
${sourceLoc}
|
|
66
|
-
}
|
|
65
|
+
${sourceLoc}`;
|
|
66
|
+
};
|
|
67
67
|
|
|
68
68
|
export const showSourceLocation = ({
|
|
69
69
|
content,
|
|
@@ -72,125 +72,125 @@ export const showSourceLocation = ({
|
|
|
72
72
|
numberOfSurroundingLinesToShow = 1,
|
|
73
73
|
lineMaxLength = 120,
|
|
74
74
|
} = {}) => {
|
|
75
|
-
let mark = (string) => string
|
|
76
|
-
let aside = (string) => string
|
|
75
|
+
let mark = (string) => string;
|
|
76
|
+
let aside = (string) => string;
|
|
77
77
|
// if (color) {
|
|
78
78
|
// mark = (string) => ANSI.color(string, ANSI.RED)
|
|
79
79
|
// aside = (string) => ANSI.color(string, ANSI.GREY)
|
|
80
80
|
// }
|
|
81
81
|
|
|
82
|
-
const lines = content.split(/\r?\n/)
|
|
83
|
-
if (line === 0) line = 1
|
|
82
|
+
const lines = content.split(/\r?\n/);
|
|
83
|
+
if (line === 0) line = 1;
|
|
84
84
|
let lineRange = {
|
|
85
85
|
start: line - 1,
|
|
86
86
|
end: line,
|
|
87
|
-
}
|
|
88
|
-
lineRange = moveLineRangeUp(lineRange, numberOfSurroundingLinesToShow)
|
|
89
|
-
lineRange = moveLineRangeDown(lineRange, numberOfSurroundingLinesToShow)
|
|
90
|
-
lineRange = lineRangeWithinLines(lineRange, lines)
|
|
91
|
-
const linesToShow = lines.slice(lineRange.start, lineRange.end)
|
|
92
|
-
const endLineNumber = lineRange.end
|
|
93
|
-
const lineNumberMaxWidth = String(endLineNumber).length
|
|
87
|
+
};
|
|
88
|
+
lineRange = moveLineRangeUp(lineRange, numberOfSurroundingLinesToShow);
|
|
89
|
+
lineRange = moveLineRangeDown(lineRange, numberOfSurroundingLinesToShow);
|
|
90
|
+
lineRange = lineRangeWithinLines(lineRange, lines);
|
|
91
|
+
const linesToShow = lines.slice(lineRange.start, lineRange.end);
|
|
92
|
+
const endLineNumber = lineRange.end;
|
|
93
|
+
const lineNumberMaxWidth = String(endLineNumber).length;
|
|
94
94
|
|
|
95
|
-
if (column === 0) column = 1
|
|
95
|
+
if (column === 0) column = 1;
|
|
96
96
|
|
|
97
|
-
const columnRange = {}
|
|
97
|
+
const columnRange = {};
|
|
98
98
|
if (column === undefined) {
|
|
99
|
-
columnRange.start = 0
|
|
100
|
-
columnRange.end = lineMaxLength
|
|
99
|
+
columnRange.start = 0;
|
|
100
|
+
columnRange.end = lineMaxLength;
|
|
101
101
|
} else if (column > lineMaxLength) {
|
|
102
|
-
columnRange.start = column - Math.floor(lineMaxLength / 2)
|
|
103
|
-
columnRange.end = column + Math.ceil(lineMaxLength / 2)
|
|
102
|
+
columnRange.start = column - Math.floor(lineMaxLength / 2);
|
|
103
|
+
columnRange.end = column + Math.ceil(lineMaxLength / 2);
|
|
104
104
|
} else {
|
|
105
|
-
columnRange.start = 0
|
|
106
|
-
columnRange.end = lineMaxLength
|
|
105
|
+
columnRange.start = 0;
|
|
106
|
+
columnRange.end = lineMaxLength;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
return linesToShow.map((lineSource, index) => {
|
|
110
|
-
const lineNumber = lineRange.start + index + 1
|
|
111
|
-
const isMainLine = lineNumber === line
|
|
112
|
-
const lineSourceTruncated = applyColumnRange(columnRange, lineSource)
|
|
113
|
-
const lineNumberWidth = String(lineNumber).length
|
|
110
|
+
const lineNumber = lineRange.start + index + 1;
|
|
111
|
+
const isMainLine = lineNumber === line;
|
|
112
|
+
const lineSourceTruncated = applyColumnRange(columnRange, lineSource);
|
|
113
|
+
const lineNumberWidth = String(lineNumber).length;
|
|
114
114
|
// ensure if line moves from 7,8,9 to 10 the display is still great
|
|
115
115
|
const lineNumberRightSpacing = " ".repeat(
|
|
116
116
|
lineNumberMaxWidth - lineNumberWidth,
|
|
117
|
-
)
|
|
118
|
-
const asideSource = `${lineNumber}${lineNumberRightSpacing}
|
|
119
|
-
const lineFormatted = `${aside(asideSource)} ${lineSourceTruncated}
|
|
117
|
+
);
|
|
118
|
+
const asideSource = `${lineNumber}${lineNumberRightSpacing} |`;
|
|
119
|
+
const lineFormatted = `${aside(asideSource)} ${lineSourceTruncated}`;
|
|
120
120
|
if (isMainLine) {
|
|
121
121
|
if (column === undefined) {
|
|
122
|
-
return `${mark(">")} ${lineFormatted}
|
|
122
|
+
return `${mark(">")} ${lineFormatted}`;
|
|
123
123
|
}
|
|
124
124
|
const spacing = stringToSpaces(
|
|
125
125
|
`${asideSource} ${lineSourceTruncated.slice(
|
|
126
126
|
0,
|
|
127
127
|
column - columnRange.start - 1,
|
|
128
128
|
)}`,
|
|
129
|
-
)
|
|
129
|
+
);
|
|
130
130
|
return `${mark(">")} ${lineFormatted}
|
|
131
|
-
${spacing}${mark("^")}
|
|
131
|
+
${spacing}${mark("^")}`;
|
|
132
132
|
}
|
|
133
|
-
return ` ${lineFormatted}
|
|
133
|
+
return ` ${lineFormatted}`;
|
|
134
134
|
}).join(`
|
|
135
|
-
`)
|
|
136
|
-
}
|
|
135
|
+
`);
|
|
136
|
+
};
|
|
137
137
|
|
|
138
138
|
const applyColumnRange = ({ start, end }, line) => {
|
|
139
139
|
if (typeof start !== "number") {
|
|
140
|
-
throw new TypeError(`start must be a number, received ${start}`)
|
|
140
|
+
throw new TypeError(`start must be a number, received ${start}`);
|
|
141
141
|
}
|
|
142
142
|
if (typeof end !== "number") {
|
|
143
|
-
throw new TypeError(`end must be a number, received ${end}`)
|
|
143
|
+
throw new TypeError(`end must be a number, received ${end}`);
|
|
144
144
|
}
|
|
145
145
|
if (end < start) {
|
|
146
146
|
throw new Error(
|
|
147
147
|
`end must be greater than start, but ${end} is smaller than ${start}`,
|
|
148
|
-
)
|
|
148
|
+
);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
const prefix = "…"
|
|
152
|
-
const suffix = "…"
|
|
153
|
-
const lastIndex = line.length
|
|
151
|
+
const prefix = "…";
|
|
152
|
+
const suffix = "…";
|
|
153
|
+
const lastIndex = line.length;
|
|
154
154
|
|
|
155
155
|
if (line.length === 0) {
|
|
156
156
|
// don't show any ellipsis if the line is empty
|
|
157
157
|
// because it's not truncated in that case
|
|
158
|
-
return ""
|
|
158
|
+
return "";
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
const startTruncated = start > 0
|
|
162
|
-
const endTruncated = lastIndex > end
|
|
161
|
+
const startTruncated = start > 0;
|
|
162
|
+
const endTruncated = lastIndex > end;
|
|
163
163
|
|
|
164
|
-
let from = startTruncated ? start + prefix.length : start
|
|
165
|
-
let to = endTruncated ? end - suffix.length : end
|
|
166
|
-
if (to > lastIndex) to = lastIndex
|
|
164
|
+
let from = startTruncated ? start + prefix.length : start;
|
|
165
|
+
let to = endTruncated ? end - suffix.length : end;
|
|
166
|
+
if (to > lastIndex) to = lastIndex;
|
|
167
167
|
|
|
168
168
|
if (start >= lastIndex || from === to) {
|
|
169
|
-
return ""
|
|
169
|
+
return "";
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
let result = ""
|
|
172
|
+
let result = "";
|
|
173
173
|
while (from < to) {
|
|
174
|
-
result += line[from]
|
|
175
|
-
from
|
|
174
|
+
result += line[from];
|
|
175
|
+
from++;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
if (result.length === 0) {
|
|
179
|
-
return ""
|
|
179
|
+
return "";
|
|
180
180
|
}
|
|
181
181
|
if (startTruncated && endTruncated) {
|
|
182
|
-
return `${prefix}${result}${suffix}
|
|
182
|
+
return `${prefix}${result}${suffix}`;
|
|
183
183
|
}
|
|
184
184
|
if (startTruncated) {
|
|
185
|
-
return `${prefix}${result}
|
|
185
|
+
return `${prefix}${result}`;
|
|
186
186
|
}
|
|
187
187
|
if (endTruncated) {
|
|
188
|
-
return `${result}${suffix}
|
|
188
|
+
return `${result}${suffix}`;
|
|
189
189
|
}
|
|
190
|
-
return result
|
|
191
|
-
}
|
|
190
|
+
return result;
|
|
191
|
+
};
|
|
192
192
|
|
|
193
|
-
const stringToSpaces = (string) => string.replace(/[^\t]/g, " ")
|
|
193
|
+
const stringToSpaces = (string) => string.replace(/[^\t]/g, " ");
|
|
194
194
|
|
|
195
195
|
// const getLineRangeLength = ({ start, end }) => end - start
|
|
196
196
|
|
|
@@ -198,19 +198,19 @@ const moveLineRangeUp = ({ start, end }, number) => {
|
|
|
198
198
|
return {
|
|
199
199
|
start: start - number,
|
|
200
200
|
end,
|
|
201
|
-
}
|
|
202
|
-
}
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
203
|
|
|
204
204
|
const moveLineRangeDown = ({ start, end }, number) => {
|
|
205
205
|
return {
|
|
206
206
|
start,
|
|
207
207
|
end: end + number,
|
|
208
|
-
}
|
|
209
|
-
}
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
210
|
|
|
211
211
|
const lineRangeWithinLines = ({ start, end }, lines) => {
|
|
212
212
|
return {
|
|
213
213
|
start: start < 0 ? 0 : start,
|
|
214
214
|
end: end > lines.length ? lines.length : end,
|
|
215
|
-
}
|
|
216
|
-
}
|
|
215
|
+
};
|
|
216
|
+
};
|
package/src/url_utils.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { urlToOrigin } from "./url_to_origin.js"
|
|
2
|
-
import { urlToExtension } from "./url_to_extension.js"
|
|
3
|
-
import { urlToResource } from "./url_to_resource.js"
|
|
1
|
+
import { urlToOrigin } from "./url_to_origin.js";
|
|
2
|
+
import { urlToExtension } from "./url_to_extension.js";
|
|
3
|
+
import { urlToResource } from "./url_to_resource.js";
|
|
4
4
|
|
|
5
5
|
export const asUrlWithoutSearch = (url) => {
|
|
6
6
|
if (url.includes("?")) {
|
|
7
|
-
const urlObject = new URL(url)
|
|
8
|
-
urlObject.search = ""
|
|
9
|
-
return urlObject.href
|
|
7
|
+
const urlObject = new URL(url);
|
|
8
|
+
urlObject.search = "";
|
|
9
|
+
return urlObject.href;
|
|
10
10
|
}
|
|
11
|
-
return url
|
|
12
|
-
}
|
|
11
|
+
return url;
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
export const isValidUrl = (url) => {
|
|
15
15
|
try {
|
|
16
16
|
// eslint-disable-next-line no-new
|
|
17
|
-
new URL(url)
|
|
18
|
-
return true
|
|
17
|
+
new URL(url);
|
|
18
|
+
return true;
|
|
19
19
|
} catch (e) {
|
|
20
|
-
return false
|
|
20
|
+
return false;
|
|
21
21
|
}
|
|
22
|
-
}
|
|
22
|
+
};
|
|
23
23
|
|
|
24
24
|
// normalize url search params:
|
|
25
25
|
// Using URLSearchParams to alter the url search params
|
|
@@ -30,83 +30,157 @@ export const normalizeUrl = (url) => {
|
|
|
30
30
|
if (url.includes("?")) {
|
|
31
31
|
// disable on data urls (would mess up base64 encoding)
|
|
32
32
|
if (url.startsWith("data:")) {
|
|
33
|
-
return url
|
|
33
|
+
return url;
|
|
34
34
|
}
|
|
35
|
-
return url.replace(/[=](?=&|$)/g, "")
|
|
35
|
+
return url.replace(/[=](?=&|$)/g, "");
|
|
36
36
|
}
|
|
37
|
-
return url
|
|
38
|
-
}
|
|
37
|
+
return url;
|
|
38
|
+
};
|
|
39
39
|
|
|
40
40
|
export const injectQueryParamsIntoSpecifier = (specifier, params) => {
|
|
41
41
|
if (isValidUrl(specifier)) {
|
|
42
|
-
return injectQueryParams(specifier, params)
|
|
42
|
+
return injectQueryParams(specifier, params);
|
|
43
43
|
}
|
|
44
|
-
const [beforeQuestion, afterQuestion = ""] = specifier.split("?")
|
|
45
|
-
const searchParams = new URLSearchParams(afterQuestion)
|
|
44
|
+
const [beforeQuestion, afterQuestion = ""] = specifier.split("?");
|
|
45
|
+
const searchParams = new URLSearchParams(afterQuestion);
|
|
46
46
|
Object.keys(params).forEach((key) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const value = params[key];
|
|
48
|
+
if (value === undefined) {
|
|
49
|
+
searchParams.delete(key);
|
|
50
|
+
} else {
|
|
51
|
+
searchParams.set(key, value);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
let paramsString = searchParams.toString();
|
|
50
55
|
if (paramsString) {
|
|
51
|
-
|
|
56
|
+
paramsString = paramsString.replace(/[=](?=&|$)/g, "");
|
|
57
|
+
return `${beforeQuestion}?${paramsString}`;
|
|
52
58
|
}
|
|
53
|
-
return
|
|
54
|
-
}
|
|
59
|
+
return beforeQuestion;
|
|
60
|
+
};
|
|
55
61
|
|
|
56
62
|
export const injectQueryParams = (url, params) => {
|
|
57
|
-
const urlObject = new URL(url)
|
|
63
|
+
const urlObject = new URL(url);
|
|
64
|
+
const { searchParams } = urlObject;
|
|
58
65
|
Object.keys(params).forEach((key) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
const value = params[key];
|
|
67
|
+
if (value === undefined) {
|
|
68
|
+
searchParams.delete(key);
|
|
69
|
+
} else {
|
|
70
|
+
searchParams.set(key, value);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
const urlWithParams = urlObject.href;
|
|
74
|
+
return normalizeUrl(urlWithParams);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const injectQueryParamWithoutEncoding = (url, key, value) => {
|
|
78
|
+
const urlObject = new URL(url);
|
|
79
|
+
let { origin, pathname, search, hash } = urlObject;
|
|
80
|
+
// origin is "null" for "file://" urls with Node.js
|
|
81
|
+
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
82
|
+
origin = "file://";
|
|
83
|
+
}
|
|
84
|
+
if (search === "") {
|
|
85
|
+
search = `?${key}=${value}`;
|
|
86
|
+
} else {
|
|
87
|
+
search += `${key}=${value}`;
|
|
88
|
+
}
|
|
89
|
+
return `${origin}${pathname}${search}${hash}`;
|
|
90
|
+
};
|
|
91
|
+
export const injectQueryParamIntoSpecifierWithoutEncoding = (
|
|
92
|
+
specifier,
|
|
93
|
+
key,
|
|
94
|
+
value,
|
|
95
|
+
) => {
|
|
96
|
+
if (isValidUrl(specifier)) {
|
|
97
|
+
return injectQueryParams(specifier, key, value);
|
|
98
|
+
}
|
|
99
|
+
const [beforeQuestion, afterQuestion = ""] = specifier.split("?");
|
|
100
|
+
const searchParams = new URLSearchParams(afterQuestion);
|
|
101
|
+
let search = searchParams.toString();
|
|
102
|
+
if (search === "") {
|
|
103
|
+
search = `?${key}=${value}`;
|
|
104
|
+
} else {
|
|
105
|
+
search = `?${search}&${key}=${value}`;
|
|
106
|
+
}
|
|
107
|
+
return `${beforeQuestion}${search}`;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export const renderUrlOrRelativeUrlFilename = (urlOrRelativeUrl, renderer) => {
|
|
111
|
+
const questionIndex = urlOrRelativeUrl.indexOf("?");
|
|
112
|
+
const beforeQuestion =
|
|
113
|
+
questionIndex === -1
|
|
114
|
+
? urlOrRelativeUrl
|
|
115
|
+
: urlOrRelativeUrl.slice(0, questionIndex);
|
|
116
|
+
const afterQuestion =
|
|
117
|
+
questionIndex === -1 ? "" : urlOrRelativeUrl.slice(questionIndex);
|
|
118
|
+
const beforeLastSlash = beforeQuestion.endsWith("/")
|
|
119
|
+
? beforeQuestion.slice(0, -1)
|
|
120
|
+
: beforeQuestion;
|
|
121
|
+
const slashLastIndex = beforeLastSlash.lastIndexOf("/");
|
|
122
|
+
const beforeFilename =
|
|
123
|
+
slashLastIndex === -1 ? "" : beforeQuestion.slice(0, slashLastIndex + 1);
|
|
124
|
+
const filename =
|
|
125
|
+
slashLastIndex === -1
|
|
126
|
+
? beforeQuestion
|
|
127
|
+
: beforeQuestion.slice(slashLastIndex + 1);
|
|
128
|
+
const dotLastIndex = filename.lastIndexOf(".");
|
|
129
|
+
const basename =
|
|
130
|
+
dotLastIndex === -1 ? filename : filename.slice(0, dotLastIndex);
|
|
131
|
+
const extension = dotLastIndex === -1 ? "" : filename.slice(dotLastIndex);
|
|
132
|
+
const newFilename = renderer({
|
|
133
|
+
basename,
|
|
134
|
+
extension,
|
|
135
|
+
});
|
|
136
|
+
return `${beforeFilename}${newFilename}${afterQuestion}`;
|
|
137
|
+
};
|
|
64
138
|
|
|
65
139
|
export const setUrlExtension = (url, extension) => {
|
|
66
|
-
const origin = urlToOrigin(url)
|
|
67
|
-
const currentExtension = urlToExtension(url)
|
|
68
|
-
const resource = urlToResource(url)
|
|
69
|
-
const [pathname, search] = resource.split("?")
|
|
140
|
+
const origin = urlToOrigin(url);
|
|
141
|
+
const currentExtension = urlToExtension(url);
|
|
142
|
+
const resource = urlToResource(url);
|
|
143
|
+
const [pathname, search] = resource.split("?");
|
|
70
144
|
const pathnameWithoutExtension = currentExtension
|
|
71
145
|
? pathname.slice(0, -currentExtension.length)
|
|
72
|
-
: pathname
|
|
73
|
-
const newPathname = `${pathnameWithoutExtension}${extension}
|
|
74
|
-
return `${origin}${newPathname}${search ? `?${search}` : ""}
|
|
75
|
-
}
|
|
146
|
+
: pathname;
|
|
147
|
+
const newPathname = `${pathnameWithoutExtension}${extension}`;
|
|
148
|
+
return `${origin}${newPathname}${search ? `?${search}` : ""}`;
|
|
149
|
+
};
|
|
76
150
|
|
|
77
151
|
export const setUrlFilename = (url, filename) => {
|
|
78
|
-
const urlObject = new URL(url)
|
|
79
|
-
let { origin, search, hash } = urlObject
|
|
152
|
+
const urlObject = new URL(url);
|
|
153
|
+
let { origin, search, hash } = urlObject;
|
|
80
154
|
// origin is "null" for "file://" urls with Node.js
|
|
81
155
|
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
82
|
-
origin = "file://"
|
|
156
|
+
origin = "file://";
|
|
83
157
|
}
|
|
84
|
-
const parentPathname = new URL("./", urlObject).pathname
|
|
85
|
-
return `${origin}${parentPathname}${filename}${search}${hash}
|
|
86
|
-
}
|
|
158
|
+
const parentPathname = new URL("./", urlObject).pathname;
|
|
159
|
+
return `${origin}${parentPathname}${filename}${search}${hash}`;
|
|
160
|
+
};
|
|
87
161
|
|
|
88
162
|
export const ensurePathnameTrailingSlash = (url) => {
|
|
89
|
-
const urlObject = new URL(url)
|
|
90
|
-
const { pathname } = urlObject
|
|
163
|
+
const urlObject = new URL(url);
|
|
164
|
+
const { pathname } = urlObject;
|
|
91
165
|
if (pathname.endsWith("/")) {
|
|
92
|
-
return url
|
|
166
|
+
return url;
|
|
93
167
|
}
|
|
94
|
-
let { origin } = urlObject
|
|
168
|
+
let { origin } = urlObject;
|
|
95
169
|
// origin is "null" for "file://" urls with Node.js
|
|
96
170
|
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
97
|
-
origin = "file://"
|
|
171
|
+
origin = "file://";
|
|
98
172
|
}
|
|
99
|
-
const { search, hash } = urlObject
|
|
100
|
-
return `${origin}${pathname}/${search}${hash}
|
|
101
|
-
}
|
|
173
|
+
const { search, hash } = urlObject;
|
|
174
|
+
return `${origin}${pathname}/${search}${hash}`;
|
|
175
|
+
};
|
|
102
176
|
|
|
103
177
|
export const asUrlUntilPathname = (url) => {
|
|
104
|
-
const urlObject = new URL(url)
|
|
105
|
-
let { origin, pathname } = urlObject
|
|
178
|
+
const urlObject = new URL(url);
|
|
179
|
+
let { origin, pathname } = urlObject;
|
|
106
180
|
// origin is "null" for "file://" urls with Node.js
|
|
107
181
|
if (origin === "null" && urlObject.href.startsWith("file:")) {
|
|
108
|
-
origin = "file://"
|
|
182
|
+
origin = "file://";
|
|
109
183
|
}
|
|
110
|
-
const urlUntilPathname = `${origin}${pathname}
|
|
111
|
-
return urlUntilPathname
|
|
112
|
-
}
|
|
184
|
+
const urlUntilPathname = `${origin}${pathname}`;
|
|
185
|
+
return urlUntilPathname;
|
|
186
|
+
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export const startsWithWindowsDriveLetter = (string) => {
|
|
2
|
-
const firstChar = string[0]
|
|
3
|
-
if (!/[a-zA-Z]/.test(firstChar)) return false
|
|
2
|
+
const firstChar = string[0];
|
|
3
|
+
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
4
4
|
|
|
5
|
-
const secondChar = string[1]
|
|
6
|
-
if (secondChar !== ":") return false
|
|
5
|
+
const secondChar = string[1];
|
|
6
|
+
if (secondChar !== ":") return false;
|
|
7
7
|
|
|
8
|
-
return true
|
|
9
|
-
}
|
|
8
|
+
return true;
|
|
9
|
+
};
|
|
10
10
|
|
|
11
11
|
export const windowsFilePathToUrl = (windowsFilePath) => {
|
|
12
|
-
return `file:///${replaceBackSlashesWithSlashes(windowsFilePath)}
|
|
13
|
-
}
|
|
12
|
+
return `file:///${replaceBackSlashesWithSlashes(windowsFilePath)}`;
|
|
13
|
+
};
|
|
14
14
|
|
|
15
15
|
export const replaceBackSlashesWithSlashes = (string) =>
|
|
16
|
-
string.replace(/\\/g, "/")
|
|
16
|
+
string.replace(/\\/g, "/");
|