kura
Version:
The FileSystem API abstraction library.
242 lines (217 loc) • 5.88 kB
text/typescript
import { DirectoryEntryAsync } from "./DirectoryEntryAsync";
import { FileEntryAsync } from "./FileEntryAsync";
import { DirectoryEntry, Entry, ErrorCallback, FileEntry } from "./filesystem";
import { FileSystemAsync } from "./FileSystemAsync";
import {
DEFAULT_CONTENT_TYPE,
DIR_SEPARATOR,
INDEX_DIR_PATH,
LAST_DIR_SEPARATORS,
} from "./FileSystemConstants";
import { FileSystemObject } from "./FileSystemObject";
const LAST_PATH_PART = /\/([^/]+)\/?$/;
export function getParentPath(fullPath: string) {
const parentPath = fullPath.replace(LAST_PATH_PART, "");
return parentPath === "" ? DIR_SEPARATOR : parentPath;
}
export function createFileSystemObject(
fullPath: string,
isFile: boolean
): FileSystemObject {
const obj: FileSystemObject = {
fullPath,
name: getName(fullPath),
};
if (isFile) {
obj.lastModified = Date.now();
obj.size = 0;
}
return obj;
}
export function getName(fullPath: string) {
if (!fullPath || fullPath === DIR_SEPARATOR) {
return "";
}
if (fullPath.endsWith(DIR_SEPARATOR)) {
fullPath = fullPath.substr(0, fullPath.length - 1);
}
const chunks = fullPath.split(DIR_SEPARATOR);
if (0 < chunks.length) {
return chunks[chunks.length - 1];
} else {
return fullPath;
}
}
export function getExtension(fullPath: string) {
if (!fullPath || fullPath === DIR_SEPARATOR) {
return "";
}
const name = getName(fullPath);
const chunks = name.split(".");
if (chunks.length <= 1) {
return "";
} else if (chunks.length === 2) {
if (!chunks[0]) {
return name;
} else {
return chunks[1];
}
} else {
return chunks[chunks.length - 1];
}
}
export function getBaseName(fullPath: string) {
if (!fullPath || fullPath === DIR_SEPARATOR) {
return "";
}
const name = getName(fullPath);
const chunks = name.split(".");
if (chunks.length === 0) {
return "";
} else if (chunks.length === 1) {
return chunks[0];
} else if (chunks.length === 2) {
if (!chunks[0]) {
return name;
} else {
return chunks[0];
}
} else {
chunks.splice(chunks.length - 1);
return chunks.join(".");
}
}
export function createEntry(fileSystemAsync: FileSystemAsync, entry: Entry) {
return entry.isFile
? new FileEntryAsync(fileSystemAsync, entry as FileEntry)
: new DirectoryEntryAsync(fileSystemAsync, entry as DirectoryEntry);
}
export function resolveToFullPath(cwdFullPath: string, path: string) {
if (!path) {
return cwdFullPath;
}
cwdFullPath = cwdFullPath.replace(LAST_DIR_SEPARATORS, "");
const relativePath = path[0] != DIR_SEPARATOR;
if (relativePath) {
path = cwdFullPath + DIR_SEPARATOR + path;
}
return normalizePath(path);
}
export function normalizePath(fullPath: string) {
// Normalize '.'s, '..'s and '//'s.
const parts = fullPath.split(DIR_SEPARATOR);
const finalParts = [];
for (const part of parts) {
if (part === "..") {
// Go up one level.
if (!finalParts.length) {
throw Error("Invalid path");
}
finalParts.pop();
} else if (part === ".") {
// Skip over the current directory.
} else if (part !== "") {
// Eliminate sequences of '/'s as well as possible leading/trailing '/'s.
finalParts.push(part);
}
}
fullPath = DIR_SEPARATOR + finalParts.join(DIR_SEPARATOR);
// fullPath is guaranteed to be normalized by construction at this point:
// '.'s, '..'s, '//'s will never appear in it.
return fullPath;
}
export function blobToFile(
fileBits: BlobPart[],
name: string,
lastModified: number,
type?: string
) {
const file = new File(fileBits, name, {
lastModified: lastModified,
type: type || DEFAULT_CONTENT_TYPE,
});
return file;
}
export function dataUrlToBase64(dataUrl: string) {
const index = dataUrl.indexOf(",");
if (0 <= index) {
return dataUrl.substr(index + 1);
}
return dataUrl;
}
export function createEmptyFile(name: string) {
return new File([], name, {
lastModified: Date.now(),
type: DEFAULT_CONTENT_TYPE,
});
}
export function getMemorySize(content: Blob | BufferSource | string) {
if (!content) {
return 0;
}
let size: number;
if (typeof content === "string") {
size = content.length * 2; // UTF-16
} else if (content instanceof Blob) {
size = content.size;
} else {
size = content.byteLength;
}
return size;
}
export function getSize(content: Blob | BufferSource | string) {
if (!content) {
return 0;
}
let size: number;
if (typeof content === "string") {
const length = content.length;
let paddingCount = 0;
for (let i = length - 1; 0 <= i; i--) {
const c = content.charAt(i);
if (c !== "=") {
break;
}
paddingCount++;
}
size = length - paddingCount;
} else if (content instanceof Blob) {
size = content.size;
} else {
size = content.byteLength;
}
return size;
}
export function getTextSize(text: string) {
return encodeURIComponent(text).replace(/%../g, "x").length; // UTF-8
}
export function isIllegalFileName(name: string) {
// eslint-disable-next-line no-control-regex
return /[\x00-\x1f\x7f-\x9f\\/:*?"<>|]/.test(name);
}
export function isIllegalPath(fullPath: string, index: boolean) {
if (fullPath === DIR_SEPARATOR) {
return true;
}
if (index && fullPath.startsWith(INDEX_DIR_PATH)) {
return true;
}
return false;
}
export function isIllegalObject(obj: FileSystemObject, index: boolean) {
if (isIllegalPath(obj.fullPath, index)) {
return true;
}
if (isIllegalFileName(obj.name)) {
return true;
}
return false;
}
export function onError(err: any, errorCallback?: ErrorCallback) {
if (errorCallback) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
errorCallback(err);
} else {
console.error(err);
}
}