mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 00:29:09 -05:00
d47147fb6a
This commit moves "deno_std/node" in "ext/node" crate. The code is transpiled and snapshotted during the build process. During the first pass a minimal amount of work was done to create the snapshot, a lot of code in "ext/node" depends on presence of "Deno" global. This code will be gradually fixed in the follow up PRs to migrate it to import relevant APIs from "internal:" modules. Currently the code from snapshot is not used in any way, and all Node/npm compatibility still uses code from "https://deno.land/std/node" (or from the location specified by "DENO_NODE_COMPAT_URL"). This will also be handled in a follow up PRs. --------- Co-authored-by: crowlkats <crowlkats@toaxl.com> Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com> Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
131 lines
3.8 KiB
TypeScript
131 lines
3.8 KiB
TypeScript
// Copyright the Browserify authors. MIT License.
|
|
// Ported from https://github.com/browserify/path-browserify/
|
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
|
|
import type { FormatInputPathObject } from "internal:deno_node/polyfills/path/_interface.ts";
|
|
import {
|
|
CHAR_BACKWARD_SLASH,
|
|
CHAR_DOT,
|
|
CHAR_FORWARD_SLASH,
|
|
CHAR_LOWERCASE_A,
|
|
CHAR_LOWERCASE_Z,
|
|
CHAR_UPPERCASE_A,
|
|
CHAR_UPPERCASE_Z,
|
|
} from "internal:deno_node/polyfills/path/_constants.ts";
|
|
import { ERR_INVALID_ARG_TYPE } from "internal:deno_node/polyfills/internal/errors.ts";
|
|
|
|
export function assertPath(path: string) {
|
|
if (typeof path !== "string") {
|
|
throw new ERR_INVALID_ARG_TYPE("path", ["string"], path);
|
|
}
|
|
}
|
|
|
|
export function isPosixPathSeparator(code: number): boolean {
|
|
return code === CHAR_FORWARD_SLASH;
|
|
}
|
|
|
|
export function isPathSeparator(code: number): boolean {
|
|
return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH;
|
|
}
|
|
|
|
export function isWindowsDeviceRoot(code: number): boolean {
|
|
return (
|
|
(code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) ||
|
|
(code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z)
|
|
);
|
|
}
|
|
|
|
// Resolves . and .. elements in a path with directory names
|
|
export function normalizeString(
|
|
path: string,
|
|
allowAboveRoot: boolean,
|
|
separator: string,
|
|
isPathSeparator: (code: number) => boolean,
|
|
): string {
|
|
let res = "";
|
|
let lastSegmentLength = 0;
|
|
let lastSlash = -1;
|
|
let dots = 0;
|
|
let code: number | undefined;
|
|
for (let i = 0, len = path.length; i <= len; ++i) {
|
|
if (i < len) code = path.charCodeAt(i);
|
|
else if (isPathSeparator(code!)) break;
|
|
else code = CHAR_FORWARD_SLASH;
|
|
|
|
if (isPathSeparator(code!)) {
|
|
if (lastSlash === i - 1 || dots === 1) {
|
|
// NOOP
|
|
} else if (lastSlash !== i - 1 && dots === 2) {
|
|
if (
|
|
res.length < 2 ||
|
|
lastSegmentLength !== 2 ||
|
|
res.charCodeAt(res.length - 1) !== CHAR_DOT ||
|
|
res.charCodeAt(res.length - 2) !== CHAR_DOT
|
|
) {
|
|
if (res.length > 2) {
|
|
const lastSlashIndex = res.lastIndexOf(separator);
|
|
if (lastSlashIndex === -1) {
|
|
res = "";
|
|
lastSegmentLength = 0;
|
|
} else {
|
|
res = res.slice(0, lastSlashIndex);
|
|
lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
|
|
}
|
|
lastSlash = i;
|
|
dots = 0;
|
|
continue;
|
|
} else if (res.length === 2 || res.length === 1) {
|
|
res = "";
|
|
lastSegmentLength = 0;
|
|
lastSlash = i;
|
|
dots = 0;
|
|
continue;
|
|
}
|
|
}
|
|
if (allowAboveRoot) {
|
|
if (res.length > 0) res += `${separator}..`;
|
|
else res = "..";
|
|
lastSegmentLength = 2;
|
|
}
|
|
} else {
|
|
if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
|
|
else res = path.slice(lastSlash + 1, i);
|
|
lastSegmentLength = i - lastSlash - 1;
|
|
}
|
|
lastSlash = i;
|
|
dots = 0;
|
|
} else if (code === CHAR_DOT && dots !== -1) {
|
|
++dots;
|
|
} else {
|
|
dots = -1;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
export function _format(
|
|
sep: string,
|
|
pathObject: FormatInputPathObject,
|
|
): string {
|
|
const dir: string | undefined = pathObject.dir || pathObject.root;
|
|
const base: string = pathObject.base ||
|
|
(pathObject.name || "") + (pathObject.ext || "");
|
|
if (!dir) return base;
|
|
if (dir === pathObject.root) return dir + base;
|
|
return dir + sep + base;
|
|
}
|
|
|
|
const WHITESPACE_ENCODINGS: Record<string, string> = {
|
|
"\u0009": "%09",
|
|
"\u000A": "%0A",
|
|
"\u000B": "%0B",
|
|
"\u000C": "%0C",
|
|
"\u000D": "%0D",
|
|
"\u0020": "%20",
|
|
};
|
|
|
|
export function encodeWhitespace(string: string): string {
|
|
return string.replaceAll(/[\s]/g, (c) => {
|
|
return WHITESPACE_ENCODINGS[c] ?? c;
|
|
});
|
|
}
|