Started to implement server
This commit is contained in:
1 parent
1f2ea8b7e5
commit
17a1b4bed3
177 files changed
+29894
-74
No files matched your search
+194
@@ -0,0 +1,194 @@
|
||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||
// Copyright the Browserify authors. MIT License.
|
||||
// Ported from https://github.com/browserify/path-browserify/
|
||||
// This module is browser compatible.
|
||||
|
||||
import type { FormatInputPathObject } from "./_interface.ts";
|
||||
import {
|
||||
CHAR_BACKWARD_SLASH,
|
||||
CHAR_DOT,
|
||||
CHAR_FORWARD_SLASH,
|
||||
CHAR_LOWERCASE_A,
|
||||
CHAR_LOWERCASE_Z,
|
||||
CHAR_UPPERCASE_A,
|
||||
CHAR_UPPERCASE_Z,
|
||||
} from "./_constants.ts";
|
||||
|
||||
export function assertPath(path: string) {
|
||||
if (typeof path !== "string") {
|
||||
throw new TypeError(
|
||||
`Path must be a string. Received ${JSON.stringify(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 (base === sep) return dir;
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
export function lastPathSegment(
|
||||
path: string,
|
||||
isSep: (char: number) => boolean,
|
||||
start = 0,
|
||||
): string {
|
||||
let matchedNonSeparator = false;
|
||||
let end = path.length;
|
||||
|
||||
for (let i = path.length - 1; i >= start; --i) {
|
||||
if (isSep(path.charCodeAt(i))) {
|
||||
if (matchedNonSeparator) {
|
||||
start = i + 1;
|
||||
break;
|
||||
}
|
||||
} else if (!matchedNonSeparator) {
|
||||
matchedNonSeparator = true;
|
||||
end = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return path.slice(start, end);
|
||||
}
|
||||
|
||||
export function stripTrailingSeparators(
|
||||
segment: string,
|
||||
isSep: (char: number) => boolean,
|
||||
): string {
|
||||
if (segment.length <= 1) {
|
||||
return segment;
|
||||
}
|
||||
|
||||
let end = segment.length;
|
||||
|
||||
for (let i = segment.length - 1; i > 0; i--) {
|
||||
if (isSep(segment.charCodeAt(i))) {
|
||||
end = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return segment.slice(0, end);
|
||||
}
|
||||
|
||||
export function stripSuffix(name: string, suffix: string): string {
|
||||
if (suffix.length >= name.length) {
|
||||
return name;
|
||||
}
|
||||
|
||||
const lenDiff = name.length - suffix.length;
|
||||
|
||||
for (let i = suffix.length - 1; i >= 0; --i) {
|
||||
if (name.charCodeAt(lenDiff + i) !== suffix.charCodeAt(i)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return name.slice(0, -suffix.length);
|
||||
}
|
||||
Reference in new issue
Block a user