remotely-save/src/misc.ts
2021-11-10 00:30:11 +08:00

133 lines
3.4 KiB
TypeScript

import { Vault } from "obsidian";
import * as path from "path";
import { base32 } from "rfc4648";
import XRegExp from "xregexp";
export type SUPPORTED_SERVICES_TYPE = "s3" | "webdav" | "ftp";
/**
* If any part of the file starts with '.' or '_' then it's a hidden file.
* @param item
* @param loose
* @returns
*/
export const isHiddenPath = (item: string, loose: boolean = true) => {
const k = path.posix.normalize(item); // TODO: only unix path now
const k2 = k.split("/"); // TODO: only unix path now
// console.log(k2)
for (const singlePart of k2) {
if (singlePart === "." || singlePart === ".." || singlePart === "") {
continue;
}
if (singlePart[0] === ".") {
return true;
}
if (loose && singlePart[0] === "_") {
return true;
}
}
return false;
};
/**
* Util func for mkdir -p based on the "path" of original file or folder
* "a/b/c/" => ["a", "a/b", "a/b/c"]
* "a/b/c/d/e.txt" => ["a", "a/b", "a/b/c", "a/b/c/d"]
* @param x string
* @returns string[] might be empty
*/
export const getFolderLevels = (x: string) => {
const res: string[] = [];
if (x === "" || x === "/") {
return res;
}
const y1 = x.split("/");
let i = 0;
for (let index = 0; index + 1 < y1.length; index++) {
res.push(y1.slice(0, index + 1).join("/"));
}
return res;
};
export const mkdirpInVault = async (thePath: string, vault: Vault) => {
// console.log(thePath);
const foldersToBuild = getFolderLevels(thePath);
// console.log(foldersToBuild);
for (const folder of foldersToBuild) {
const r = await vault.adapter.exists(folder);
// console.log(r);
if (!r) {
console.log(`mkdir ${folder}`);
await vault.adapter.mkdir(folder);
}
}
};
/**
* https://stackoverflow.com/questions/8609289
* @param b Buffer
* @returns ArrayBuffer
*/
export const bufferToArrayBuffer = (b: Buffer | Uint8Array) => {
return b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
};
/**
* Simple func.
* @param b
* @returns
*/
export const arrayBufferToBuffer = (b: ArrayBuffer) => {
return Buffer.from(b);
};
export const arrayBufferToBase64 = (b: ArrayBuffer) => {
return arrayBufferToBuffer(b).toString("base64");
};
export const arrayBufferToHex = (b: ArrayBuffer) => {
return arrayBufferToBuffer(b).toString("hex");
};
export const base64ToArrayBuffer = (b64text: string) => {
return bufferToArrayBuffer(Buffer.from(b64text, "base64"));
};
/**
* https://stackoverflow.com/questions/43131242
* @param hex
* @returns
*/
export const hexStringToTypedArray = (hex: string) => {
return new Uint8Array(
hex.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16);
})
);
};
export const base64ToBase32 = (a: string) => {
return base32.stringify(Buffer.from(a, "base64"));
};
/**
* iOS Safari could decrypt string with invalid password!
* So we need an extra way to test the decrypted result.
* One simple way is testing the result are "valid", printable chars or not.
*
* https://stackoverflow.com/questions/6198986
* https://www.regular-expressions.info/unicode.html
* Manual test shows that emojis like '🍎' match '\\p{Cs}',
* so we need to write the regrex in a form that \p{C} minus \p{Cs}
* @param a
*/
export const isVaildText = (a: string) => {
// If the regex matches, the string is invalid.
return !XRegExp("\\p{Cc}|\\p{Cf}|\\p{Co}|\\p{Cn}|\\p{Zl}|\\p{Zp}", "A").test(
a
);
};