safe lint from biome

This commit is contained in:
fyears 2024-05-08 00:20:15 +08:00
parent 6ed6122bb6
commit a081d09212
33 changed files with 230 additions and 236 deletions

View File

@ -3,10 +3,13 @@
"organizeImports": {
"enabled": true
},
"files": {
"ignore": ["main.js"]
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"ignore": ["main.js"],
"ignore": [],
"attributePosition": "auto",
"indentStyle": "space",
"indentWidth": 2,
@ -27,7 +30,14 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
},
"style": {
"noUselessElse": "off",
"useNodejsImportProtocol": "off"
}
}
}
}

View File

@ -2,7 +2,7 @@
const http = require("http");
const requestHandler = (req, res) => {
let body = [];
const body = [];
req
.on("data", (chunk) => {
body.push(chunk);

View File

@ -1,7 +1,6 @@
import dotenv from "dotenv/config";
import esbuild from "esbuild";
import process from "process";
import inlineWorkerPlugin from "esbuild-plugin-inline-worker";
import process from "process";
// import builtins from 'builtin-modules'
const banner = `/*

View File

@ -1,2 +1,2 @@
export let Buffer = require("buffer").Buffer;
export let process = require("process/browser");
export const Buffer = require("buffer").Buffer;
export const process = require("process/browser");

View File

@ -7,7 +7,7 @@
"build2": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"build": "webpack --mode production",
"dev": "webpack --mode development --watch",
"format": "npx @biomejs/biome format --write .",
"format": "npx @biomejs/biome check --apply .",
"clean": "npx rimraf main.js",
"test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha -r ts-node/register 'tests/**/*.ts'"
},

View File

@ -3,7 +3,7 @@
* To avoid circular dependency.
*/
import type { LangType, LangTypeAndAuto } from "./i18n";
import type { LangTypeAndAuto } from "./i18n";
export const DEFAULT_CONTENT_TYPE = "application/octet-stream";

View File

@ -1,4 +1,4 @@
import { base64, base64url } from "rfc4648";
import { base64url } from "rfc4648";
import { reverseString } from "./misc";
import type { RemotelySavePluginSettings } from "./baseTypes";

View File

@ -1,16 +1,16 @@
import { TAbstractFile, TFolder, TFile, Vault } from "obsidian";
import type { Vault } from "obsidian";
import {
readAllProfilerResultsByVault,
readAllSyncPlanRecordTextsByVault,
} from "./localdb";
import type { InternalDBs } from "./localdb";
import { mkdirpInVault, unixTimeToStr } from "./misc";
import {
DEFAULT_DEBUG_FOLDER,
DEFAULT_PROFILER_RESULT_FILE_PREFIX,
DEFAULT_SYNC_PLANS_HISTORY_FILE_PREFIX,
} from "./baseTypes";
import {
readAllProfilerResultsByVault,
readAllSyncPlanRecordTextsByVault,
} from "./localdb";
import type { InternalDBs } from "./localdb";
import { mkdirpInVault } from "./misc";
export const exportVaultSyncPlansToFiles = async (
db: InternalDBs,

View File

@ -39,7 +39,7 @@ export const encryptArrayBuffer = async (
arrBuf: ArrayBuffer,
password: string,
rounds: number = DEFAULT_ITER,
saltHex: string = ""
saltHex = ""
) => {
let salt: Uint8Array;
if (saltHex !== "") {
@ -109,7 +109,7 @@ export const encryptStringToBase32 = async (
text: string,
password: string,
rounds: number = DEFAULT_ITER,
saltHex: string = ""
saltHex = ""
) => {
const enc = await encryptArrayBuffer(
bufferToArrayBuffer(new TextEncoder().encode(text)),
@ -138,7 +138,7 @@ export const encryptStringToBase64url = async (
text: string,
password: string,
rounds: number = DEFAULT_ITER,
saltHex: string = ""
saltHex = ""
) => {
const enc = await encryptArrayBuffer(
bufferToArrayBuffer(new TextEncoder().encode(text)),

View File

@ -1,5 +1,5 @@
import { nanoid } from "nanoid";
import { Cipher as CipherRCloneCryptPack } from "@fyears/rclone-crypt";
import { nanoid } from "nanoid";
const ctx: WorkerGlobalScope = self as any;

View File

@ -1,4 +1,4 @@
import { Entity } from "./baseTypes";
import type { Entity } from "./baseTypes";
export abstract class FakeFs {
abstract kind: string;

View File

@ -1,13 +1,13 @@
import { FakeFs } from "./fsAll";
import { Dropbox, DropboxAuth } from "dropbox";
import type { files, DropboxResponseError, DropboxResponse } from "dropbox";
import {
DropboxConfig,
COMMAND_CALLBACK_DROPBOX,
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
Entity,
} from "./baseTypes";
import type { DropboxResponse, DropboxResponseError, files } from "dropbox";
import random from "lodash/random";
import {
COMMAND_CALLBACK_DROPBOX,
type DropboxConfig,
type Entity,
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
} from "./baseTypes";
import { FakeFs } from "./fsAll";
import {
bufferToArrayBuffer,
delay,
@ -167,7 +167,7 @@ interface ErrSubType {
async function retryReq<T>(
reqFunc: () => Promise<DropboxResponse<T>>,
extraHint: string = ""
extraHint = ""
): Promise<DropboxResponse<T> | undefined> {
const waitSeconds = [1, 2, 4, 8]; // hard code exponential backoff
for (let idx = 0; idx < waitSeconds.length; ++idx) {
@ -205,7 +205,7 @@ async function retryReq<T>(
const headers = headersToRecord(err.headers);
const svrSec =
err.error.error.retry_after ||
parseInt(headers["retry-after"] || "1") ||
Number.parseInt(headers["retry-after"] || "1") ||
1;
const fallbackSec = waitSeconds[idx];
const secMin = Math.max(svrSec, fallbackSec);
@ -233,7 +233,7 @@ async function retryReq<T>(
export const getAuthUrlAndVerifier = async (
appKey: string,
needManualPatse: boolean = false
needManualPatse = false
) => {
const auth = new DropboxAuth({
clientId: appKey,
@ -328,9 +328,9 @@ export const setConfigBySuccessfullAuthInplace = async (
console.info("start updating local info of Dropbox token");
config.accessToken = authRes.access_token;
config.accessTokenExpiresInSeconds = parseInt(authRes.expires_in);
config.accessTokenExpiresInSeconds = Number.parseInt(authRes.expires_in);
config.accessTokenExpiresAtTime =
Date.now() + parseInt(authRes.expires_in) * 1000 - 10 * 1000;
Date.now() + Number.parseInt(authRes.expires_in) * 1000 - 10 * 1000;
// manually set it expired after 80 days;
config.credentialsShouldBeDeletedAtTime =

View File

@ -1,10 +1,10 @@
import { CipherMethodType, Entity } from "./baseTypes";
import type { CipherMethodType, Entity } from "./baseTypes";
import * as openssl from "./encryptOpenSSL";
import * as rclone from "./encryptRClone";
import { isVaildText } from "./misc";
import { FakeFs } from "./fsAll";
import cloneDeep from "lodash/cloneDeep";
import { FakeFs } from "./fsAll";
/**
* quick guess, no actual decryption here

View File

@ -1,5 +1,5 @@
import { RemotelySavePluginSettings } from "./baseTypes";
import { FakeFs } from "./fsAll";
import type { RemotelySavePluginSettings } from "./baseTypes";
import type { FakeFs } from "./fsAll";
import { FakeFsDropbox } from "./fsDropbox";
import { FakeFsOnedrive } from "./fsOnedrive";
import { FakeFsS3 } from "./fsS3";

View File

@ -1,10 +1,10 @@
import { DEFAULT_DEBUG_FOLDER, Entity } from "./baseTypes";
import { DEFAULT_DEBUG_FOLDER, type Entity } from "./baseTypes";
import { FakeFs } from "./fsAll";
import { TFile, TFolder, type Vault } from "obsidian";
import { mkdirpInVault, statFix, unixTimeToStr } from "./misc";
import { listFilesInObsFolder } from "./obsFolderLister";
import { Profiler } from "./profiler";
import { getFolderLevels, mkdirpInVault, statFix, unixTimeToStr } from "./misc";
import type { Profiler } from "./profiler";
export class FakeFsLocal extends FakeFs {
vault: Vault;

View File

@ -1,4 +1,4 @@
import { Entity } from "./baseTypes";
import type { Entity } from "./baseTypes";
import { FakeFs } from "./fsAll";
export class FakeFsMock extends FakeFs {

View File

@ -1,19 +1,19 @@
import { CryptoProvider, PublicClientApplication } from "@azure/msal-node";
import type { AuthenticationProvider } from "@microsoft/microsoft-graph-client";
import type {
DriveItem,
FileSystemInfo,
UploadSession,
User,
} from "@microsoft/microsoft-graph-types";
import { CryptoProvider, PublicClientApplication } from "@azure/msal-node";
import { AuthenticationProvider } from "@microsoft/microsoft-graph-client";
import cloneDeep from "lodash/cloneDeep";
import { request, requestUrl } from "obsidian";
import {
COMMAND_CALLBACK_ONEDRIVE,
DEFAULT_CONTENT_TYPE,
Entity,
type Entity,
OAUTH2_FORCE_EXPIRE_MILLISECONDS,
OnedriveConfig,
type OnedriveConfig,
} from "./baseTypes";
import { VALID_REQURL } from "./baseTypesObs";
import { FakeFs } from "./fsAll";
@ -658,7 +658,7 @@ export class FakeFsOnedrive extends FakeFs {
let res = await this._getJson(
`/drive/special/approot:/${this.remoteBaseDir}:/delta`
);
let driveItems = res.value as DriveItem[];
const driveItems = res.value as DriveItem[];
// console.debug(driveItems);
while (NEXT_LINK_KEY in res) {
@ -719,7 +719,7 @@ export class FakeFsOnedrive extends FakeFs {
} else {
// https://stackoverflow.com/questions/56479865/creating-nested-folders-in-one-go-onedrive-api
// use PATCH to create folder recursively!!!
let playload: any = {
const playload: any = {
folder: {},
"@microsoft.graph.conflictBehavior": "replace",
};

View File

@ -1,36 +1,36 @@
import type { _Object, PutObjectCommandInput } from "@aws-sdk/client-s3";
import { Buffer } from "buffer";
import * as path from "path";
import { Readable } from "stream";
import type { PutObjectCommandInput, _Object } from "@aws-sdk/client-s3";
import {
DeleteObjectCommand,
GetObjectCommand,
HeadObjectCommand,
HeadObjectCommandOutput,
type HeadObjectCommandOutput,
ListObjectsV2Command,
ListObjectsV2CommandInput,
type ListObjectsV2CommandInput,
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
import { HttpRequest, HttpResponse } from "@smithy/protocol-http";
import type { HttpHandlerOptions } from "@aws-sdk/types";
import {
FetchHttpHandler,
FetchHttpHandlerOptions,
type FetchHttpHandlerOptions,
} from "@smithy/fetch-http-handler";
// @ts-ignore
import { requestTimeout } from "@smithy/fetch-http-handler/dist-es/request-timeout";
import { type HttpRequest, HttpResponse } from "@smithy/protocol-http";
import { buildQueryString } from "@smithy/querystring-builder";
import { HttpHandlerOptions } from "@aws-sdk/types";
import { Buffer } from "buffer";
import * as mime from "mime-types";
import { Platform, requestUrl, RequestUrlParam } from "obsidian";
import { Readable } from "stream";
import * as path from "path";
import AggregateError from "aggregate-error";
import { DEFAULT_CONTENT_TYPE, S3Config } from "./baseTypes";
import * as mime from "mime-types";
import { Platform, type RequestUrlParam, requestUrl } from "obsidian";
import PQueue from "p-queue";
import { DEFAULT_CONTENT_TYPE, type S3Config } from "./baseTypes";
import { VALID_REQURL } from "./baseTypesObs";
import { bufferToArrayBuffer, getFolderLevels } from "./misc";
import PQueue from "p-queue";
import { Entity } from "./baseTypes";
import type { Entity } from "./baseTypes";
import { FakeFs } from "./fsAll";
////////////////////////////////////////////////////////////////////////////////
@ -349,7 +349,7 @@ const fromS3HeadObjectToEntity = (
let mtimeCli = mtimeSvr;
if (useAccurateMTime && x.Metadata !== undefined) {
const m2 = Math.floor(
parseFloat(x.Metadata.mtime || x.Metadata.MTime || "0")
Number.parseFloat(x.Metadata.mtime || x.Metadata.MTime || "0")
);
if (m2 !== 0) {
// to be compatible with RClone, we read and store the time in seconds in new version!
@ -458,12 +458,12 @@ export class FakeFsS3 extends FakeFs {
// pass
} else {
mtimeRecords[content.Key!] = Math.floor(
parseFloat(
Number.parseFloat(
rspHead.Metadata.mtime || rspHead.Metadata.MTime || "0"
)
);
ctimeRecords[content.Key!] = Math.floor(
parseFloat(
Number.parseFloat(
rspHead.Metadata.ctime || rspHead.Metadata.CTime || "0"
)
);

View File

@ -1,21 +1,21 @@
import { getReasonPhrase } from "http-status-codes/build/cjs/utils-functions";
import { Buffer } from "buffer";
import cloneDeep from "lodash/cloneDeep";
import { Queue } from "@fyears/tsqueue";
import { getReasonPhrase } from "http-status-codes/build/cjs/utils-functions";
import chunk from "lodash/chunk";
import cloneDeep from "lodash/cloneDeep";
import flatten from "lodash/flatten";
import { Platform, requestUrl } from "obsidian";
import { FakeFs } from "./fsAll";
import { bufferToArrayBuffer } from "./misc";
import { Entity, WebdavConfig } from "./baseTypes";
import { VALID_REQURL } from "./baseTypesObs";
import type {
FileStat,
WebDAVClient,
RequestOptionsWithState,
WebDAVClient,
// Response,
// ResponseDataDetailed,
} from "webdav";
import type { Entity, WebdavConfig } from "./baseTypes";
import { VALID_REQURL } from "./baseTypesObs";
import { FakeFs } from "./fsAll";
import { bufferToArrayBuffer } from "./misc";
/**
* https://stackoverflow.com/questions/32850898/how-to-check-if-a-string-has-any-non-iso-8859-1-characters-with-javascript
@ -95,7 +95,7 @@ if (VALID_REQURL) {
console.debug(`after request:`);
const rspHeaders = objKeyToLower({ ...r.headers });
console.debug(`rspHeaders: ${JSON.stringify(rspHeaders, null, 2)}`);
for (let key in rspHeaders) {
for (const key in rspHeaders) {
if (rspHeaders.hasOwnProperty(key)) {
// avoid the error:
// Failed to read the 'headers' property from 'ResponseInit': String contains non ISO-8859-1 code point.
@ -143,6 +143,7 @@ if (VALID_REQURL) {
}
// @ts-ignore
// biome-ignore lint: we want to ts-ignore the next line
import { AuthType, BufferLike, createClient } from "webdav/dist/web/index.js";
export const DEFAULT_WEBDAV_CONFIG = {

View File

@ -1,5 +1,9 @@
import { cloneDeep, isEqual } from "lodash";
import { DEFAULT_CONTENT_TYPE, Entity, WebdisConfig } from "./baseTypes";
import { isEqual } from "lodash";
import {
DEFAULT_CONTENT_TYPE,
type Entity,
type WebdisConfig,
} from "./baseTypes";
import { FakeFs } from "./fsAll";
export const DEFAULT_WEBDIS_CONFIG: WebdisConfig = {
@ -149,10 +153,10 @@ export class FakeFsWebdis extends FakeFs {
return {
key: realKey,
keyRaw: realKey,
mtimeCli: parseInt(rsp["mtime"]),
mtimeSvr: parseInt(rsp["mtime"]),
size: parseInt(rsp["size"]),
sizeRaw: parseInt(rsp["size"]),
mtimeCli: Number.parseInt(rsp["mtime"]),
mtimeSvr: Number.parseInt(rsp["mtime"]),
size: Number.parseInt(rsp["size"]),
sizeRaw: Number.parseInt(rsp["size"]),
};
}

View File

@ -1,11 +1,11 @@
import QRCode from "qrcode";
import cloneDeep from "lodash/cloneDeep";
import QRCode from "qrcode";
import {
COMMAND_URI,
UriParams,
RemotelySavePluginSettings,
QRExportType,
type QRExportType,
type RemotelySavePluginSettings,
type UriParams,
} from "./baseTypes";
import { getShrinkedSettings } from "./fsOnedrive";
@ -64,7 +64,7 @@ export const importQrCodeUri = (
inputParams: any,
currentVaultName: string
): ProcessQrCodeResultType => {
let params = inputParams as UriParams;
const params = inputParams as UriParams;
if (
params.func === undefined ||
params.func !== "settings" ||

View File

@ -4,9 +4,9 @@ extendPrototype(localforage);
export type LocalForage = typeof localforage;
import { nanoid } from "nanoid";
import type { Entity, MixedEntity, SUPPORTED_SERVICES_TYPE } from "./baseTypes";
import type { SyncPlanType } from "./sync";
import type { Entity, SUPPORTED_SERVICES_TYPE } from "./baseTypes";
import { unixTimeToStr } from "./misc";
import type { SyncPlanType } from "./sync";
const DB_VERSION_NUMBER_IN_HISTORY = [20211114, 20220108, 20220326, 20240220];
export const DEFAULT_DB_VERSION_NUMBER: number = 20240220;
@ -400,7 +400,7 @@ export const clearExpiredSyncPlanRecords = async (db: InternalDBs) => {
const expiredTs = currTs - MILLISECONDS_OLD;
let records = (await db.syncPlansTbl.keys()).map((key) => {
const ts = parseInt(key.split("\t")[1]);
const ts = Number.parseInt(key.split("\t")[1]);
const expired = ts <= expiredTs;
return {
ts: ts,
@ -542,7 +542,7 @@ export const insertProfilerResultByVault = async (
// clear older one while writing
const records = (await db.profilerResultsTbl.keys())
.filter((x) => x.startsWith(`${vaultRandomID}\t`))
.map((x) => parseInt(x.split("\t")[1]));
.map((x) => Number.parseInt(x.split("\t")[1]));
records.sort((a, b) => -(a - b)); // descending
while (records.length > 5) {
const ts = records.pop()!;
@ -559,7 +559,7 @@ export const readAllProfilerResultsByVault = async (
if (key.startsWith(`${vaultRandomID}\t`)) {
records.push({
val: value as string,
ts: parseInt(key.split("\t")[1]),
ts: Number.parseInt(key.split("\t")[1]),
});
}
});

View File

@ -1,68 +1,68 @@
import {
Modal,
Notice,
Plugin,
Setting,
addIcon,
setIcon,
FileSystemAdapter,
Platform,
requireApiVersion,
Events,
TFolder,
} from "obsidian";
import cloneDeep from "lodash/cloneDeep";
import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide";
import { FileText, RefreshCcw, RotateCcw, createElement } from "lucide";
import {
Events,
FileSystemAdapter,
type Modal,
Notice,
Platform,
Plugin,
type Setting,
TFolder,
addIcon,
requireApiVersion,
setIcon,
} from "obsidian";
import type {
RemotelySavePluginSettings,
SyncTriggerSourceType,
} from "./baseTypes";
import {
COMMAND_CALLBACK,
COMMAND_CALLBACK_ONEDRIVE,
COMMAND_CALLBACK_DROPBOX,
COMMAND_CALLBACK_ONEDRIVE,
COMMAND_URI,
} from "./baseTypes";
import { API_VER_ENSURE_REQURL_OK } from "./baseTypesObs";
import { importQrCodeUri } from "./importExport";
import {
prepareDBs,
InternalDBs,
clearExpiredSyncPlanRecords,
upsertPluginVersionByVault,
clearAllLoggerOutputRecords,
upsertLastSuccessSyncTimeByVault,
getLastSuccessSyncTimeByVault,
} from "./localdb";
import { messyConfigToNormal, normalConfigToMessy } from "./configPersist";
import {
DEFAULT_DROPBOX_CONFIG,
sendAuthReq as sendAuthReqDropbox,
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceDropbox,
} from "./fsDropbox";
import {
AccessCodeResponseSuccessfulType,
type AccessCodeResponseSuccessfulType,
DEFAULT_ONEDRIVE_CONFIG,
sendAuthReq as sendAuthReqOnedrive,
setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceOnedrive,
} from "./fsOnedrive";
import { DEFAULT_S3_CONFIG } from "./fsS3";
import { DEFAULT_WEBDAV_CONFIG } from "./fsWebdav";
import { RemotelySaveSettingTab } from "./settings";
import { messyConfigToNormal, normalConfigToMessy } from "./configPersist";
import { I18n } from "./i18n";
import type { LangTypeAndAuto, TransItemType } from "./i18n";
import { importQrCodeUri } from "./importExport";
import {
type InternalDBs,
clearAllLoggerOutputRecords,
clearExpiredSyncPlanRecords,
getLastSuccessSyncTimeByVault,
prepareDBs,
upsertLastSuccessSyncTimeByVault,
upsertPluginVersionByVault,
} from "./localdb";
import { RemotelySaveSettingTab } from "./settings";
import { SyncAlgoV3Modal } from "./syncAlgoV3Notice";
import AggregateError from "aggregate-error";
import throttle from "lodash/throttle";
import { exportVaultSyncPlansToFiles } from "./debugMode";
import { FakeFsEncrypt } from "./fsEncrypt";
import { getClient } from "./fsGetter";
import { FakeFsLocal } from "./fsLocal";
import { DEFAULT_WEBDIS_CONFIG } from "./fsWebdis";
import { changeMobileStatusBar } from "./misc";
import { Profiler } from "./profiler";
import { FakeFsLocal } from "./fsLocal";
import { FakeFsEncrypt } from "./fsEncrypt";
import { syncer } from "./sync";
import { getClient } from "./fsGetter";
import throttle from "lodash/throttle";
import { DEFAULT_WEBDIS_CONFIG } from "./fsWebdis";
const DEFAULT_SETTINGS: RemotelySavePluginSettings = {
s3: DEFAULT_S3_CONFIG,
@ -331,7 +331,7 @@ export default class RemotelySavePlugin extends Plugin {
// last step
if (this.syncRibbon !== undefined) {
setIcon(this.syncRibbon, iconNameSyncWait);
let originLabel = `${this.manifest.name}`;
const originLabel = `${this.manifest.name}`;
this.syncRibbon.setAttribute("aria-label", originLabel);
}
}
@ -535,7 +535,7 @@ export default class RemotelySavePlugin extends Plugin {
return;
}
let authRes = await sendAuthReqDropbox(
const authRes = await sendAuthReqDropbox(
this.settings.dropbox.clientID,
this.oauth2Info.verifier,
inputParams.code,
@ -620,7 +620,7 @@ export default class RemotelySavePlugin extends Plugin {
});
}
let rsp = await sendAuthReqOnedrive(
const rsp = await sendAuthReqOnedrive(
this.settings.onedrive.clientID,
this.settings.onedrive.authority,
inputParams.code,
@ -957,7 +957,7 @@ export default class RemotelySavePlugin extends Plugin {
}
async checkIfOauthExpires() {
let needSave: boolean = false;
let needSave = false;
const current = Date.now();
// fullfill old version settings
@ -1298,7 +1298,7 @@ export default class RemotelySavePlugin extends Plugin {
timeText = t("statusbar_now");
}
let dateText = new Date(lastSuccessSyncMillis).toLocaleTimeString(
const dateText = new Date(lastSuccessSyncMillis).toLocaleTimeString(
navigator.language,
{
weekday: "long",

View File

@ -1,9 +1,9 @@
import { Platform, Vault } from "obsidian";
import * as path from "path";
import type { Vault } from "obsidian";
import { base32, base64url } from "rfc4648";
import XRegExp from "xregexp";
import emojiRegex from "emoji-regex";
import { base32 } from "rfc4648";
import XRegExp from "xregexp";
declare global {
interface Window {
@ -18,11 +18,7 @@ declare global {
* @param underscore
* @returns
*/
export const isHiddenPath = (
item: string,
dot: boolean = true,
underscore: boolean = true
) => {
export const isHiddenPath = (item: string, dot = true, underscore = true) => {
if (!(dot || underscore)) {
throw Error("parameter error for isHiddenPath");
}
@ -50,7 +46,7 @@ export const isHiddenPath = (
* @param x string
* @returns string[] might be empty
*/
export const getFolderLevels = (x: string, addEndingSlash: boolean = false) => {
export const getFolderLevels = (x: string, addEndingSlash = false) => {
const res: string[] = [];
if (x === "" || x === "/") {
@ -58,7 +54,7 @@ export const getFolderLevels = (x: string, addEndingSlash: boolean = false) => {
}
const y1 = x.split("/");
let i = 0;
const i = 0;
for (let index = 0; index + 1 < y1.length; index++) {
let k = y1.slice(0, index + 1).join("/");
if (k === "" || k === "/") {
@ -134,18 +130,14 @@ export const hexStringToTypedArray = (hex: string) => {
if (f === null) {
throw Error(`input ${hex} is not hex, no way to transform`);
}
return new Uint8Array(
f.map(function (h) {
return parseInt(h, 16);
})
);
return new Uint8Array(f.map((h) => Number.parseInt(h, 16)));
};
export const base64ToBase32 = (a: string) => {
return base32.stringify(Buffer.from(a, "base64"));
};
export const base64ToBase64url = (a: string, pad: boolean = false) => {
export const base64ToBase64url = (a: string, pad = false) => {
let b = a.replace(/\+/g, "-").replace(/\//g, "_");
if (!pad) {
b = b.replace(/=/g, "");
@ -190,7 +182,7 @@ export const hasEmojiInText = (a: string) => {
* @param toLower
* @returns
*/
export const headersToRecord = (h: Headers, toLower: boolean = true) => {
export const headersToRecord = (h: Headers, toLower = true) => {
const res: Record<string, string> = {};
h.forEach((v, k) => {
if (toLower) {
@ -240,11 +232,11 @@ export const getParentFolder = (a: string) => {
* @param delimiter
* @returns
*/
export const setToString = (a: Set<string>, delimiter: string = ",") => {
export const setToString = (a: Set<string>, delimiter = ",") => {
return [...a].join(delimiter);
};
export const extractSvgSub = (x: string, subEl: string = "rect") => {
export const extractSvgSub = (x: string, subEl = "rect") => {
const parser = new window.DOMParser();
const dom = parser.parseFromString(x, "image/svg+xml");
const svg = dom.querySelector("svg")!;
@ -261,7 +253,7 @@ export const extractSvgSub = (x: string, subEl: string = "rect") => {
export const getRandomIntInclusive = (min: number, max: number) => {
const randomBuffer = new Uint32Array(1);
window.crypto.getRandomValues(randomBuffer);
let randomNumber = randomBuffer[0] / (0xffffffff + 1);
const randomNumber = randomBuffer[0] / (0xffffffff + 1);
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(randomNumber * (max - min + 1)) + min;
@ -446,7 +438,7 @@ export const isSpecialFolderNameToSkip = (
x: string,
more: string[] | undefined
) => {
let specialFolders = [
const specialFolders = [
".git",
".github",
".gitlab",

View File

@ -1,10 +1,10 @@
import type { Vault, Stat, ListedFiles } from "obsidian";
import type { Entity, MixedEntity } from "./baseTypes";
import type { ListedFiles, Vault } from "obsidian";
import type { Entity } from "./baseTypes";
import { Queue } from "@fyears/tsqueue";
import chunk from "lodash/chunk";
import flatten from "lodash/flatten";
import { statFix, isSpecialFolderNameToSkip } from "./misc";
import { isSpecialFolderNameToSkip, statFix } from "./misc";
const isPluginDirItself = (x: string, pluginId: string) => {
return (

View File

@ -1,5 +1,5 @@
import { SUPPORTED_SERVICES_TYPE } from "./baseTypes";
import { InternalDBs, insertProfilerResultByVault } from "./localdb";
import type { SUPPORTED_SERVICES_TYPE } from "./baseTypes";
import { type InternalDBs, insertProfilerResultByVault } from "./localdb";
import { unixTimeToStr } from "./misc";
interface BreakPoint {

View File

@ -1,37 +1,45 @@
import { Eye, EyeOff, createElement } from "lucide";
import {
App,
type App,
Modal,
Notice,
Platform,
PluginSettingTab,
Setting,
Platform,
requireApiVersion,
requestUrl,
} from "obsidian";
import type { TextComponent } from "obsidian";
import { createElement, Eye, EyeOff } from "lucide";
import {
import type {
CipherMethodType,
ConflictActionType,
DEFAULT_DEBUG_FOLDER,
EmptyFolderCleanType,
QRExportType,
SUPPORTED_SERVICES_TYPE,
SUPPORTED_SERVICES_TYPE_WITH_REMOTE_BASE_DIR,
SyncDirectionType,
WebdavAuthType,
WebdavDepthType,
CipherMethodType,
QRExportType,
} from "./baseTypes";
import {
API_VER_ENSURE_REQURL_OK,
API_VER_REQURL,
VALID_REQURL,
} from "./baseTypesObs";
import cloneDeep from "lodash/cloneDeep";
import { API_VER_ENSURE_REQURL_OK, VALID_REQURL } from "./baseTypesObs";
import { messyConfigToNormal } from "./configPersist";
import {
exportVaultProfilerResultsToFiles,
exportVaultSyncPlansToFiles,
} from "./debugMode";
import {
DEFAULT_DROPBOX_CONFIG,
getAuthUrlAndVerifier as getAuthUrlAndVerifierDropbox,
sendAuthReq as sendAuthReqDropbox,
setConfigBySuccessfullAuthInplace,
} from "./fsDropbox";
import { getClient } from "./fsGetter";
import {
DEFAULT_ONEDRIVE_CONFIG,
getAuthUrlAndVerifier as getAuthUrlAndVerifierOnedrive,
} from "./fsOnedrive";
import { simpleTransRemotePrefix } from "./fsS3";
import type { TransItemType } from "./i18n";
import {
exportQrCodeUri,
importQrCodeUri,
@ -44,27 +52,11 @@ import {
upsertLastSuccessSyncTimeByVault,
} from "./localdb";
import type RemotelySavePlugin from "./main"; // unavoidable
import { FakeFs } from "./fsAll";
import {
DEFAULT_DROPBOX_CONFIG,
getAuthUrlAndVerifier as getAuthUrlAndVerifierDropbox,
sendAuthReq as sendAuthReqDropbox,
setConfigBySuccessfullAuthInplace,
} from "./fsDropbox";
import {
DEFAULT_ONEDRIVE_CONFIG,
getAuthUrlAndVerifier as getAuthUrlAndVerifierOnedrive,
} from "./fsOnedrive";
import { messyConfigToNormal } from "./configPersist";
import type { TransItemType } from "./i18n";
import {
changeMobileStatusBar,
checkHasSpecialCharForDir,
stringToFragment,
} from "./misc";
import { simpleTransRemotePrefix } from "./fsS3";
import cloneDeep from "lodash/cloneDeep";
import { getClient } from "./fsGetter";
class PasswordModal extends Modal {
plugin: RemotelySavePlugin;
@ -76,7 +68,7 @@ class PasswordModal extends Modal {
}
onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -131,7 +123,7 @@ class PasswordModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -144,7 +136,7 @@ class EncryptionMethodModal extends Modal {
}
onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -170,7 +162,7 @@ class EncryptionMethodModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -192,7 +184,7 @@ class ChangeRemoteBaseDirModal extends Modal {
}
onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -264,7 +256,7 @@ class ChangeRemoteBaseDirModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -283,7 +275,7 @@ class ChangeRemotePrefixModal extends Modal {
}
onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -346,7 +338,7 @@ class ChangeRemotePrefixModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -371,7 +363,7 @@ class DropboxAuthModal extends Modal {
}
async onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -509,7 +501,7 @@ class DropboxAuthModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -534,7 +526,7 @@ export class OnedriveAuthModal extends Modal {
}
async onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const { authUrl, verifier } = await getAuthUrlAndVerifierOnedrive(
this.plugin.settings.onedrive.clientID,
@ -583,7 +575,7 @@ export class OnedriveAuthModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -605,7 +597,7 @@ export class OnedriveRevokeAuthModal extends Modal {
}
async onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
};
@ -653,7 +645,7 @@ export class OnedriveRevokeAuthModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -672,7 +664,7 @@ class SyncConfigDirModal extends Modal {
}
async onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -706,7 +698,7 @@ class SyncConfigDirModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -721,7 +713,7 @@ class ExportSettingsQrCodeModal extends Modal {
}
async onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
@ -770,7 +762,7 @@ class ExportSettingsQrCodeModal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
}
}
@ -810,7 +802,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
}
display(): void {
let { containerEl } = this;
const { containerEl } = this;
containerEl.style.setProperty("overflow-wrap", "break-word");
containerEl.empty();
@ -1007,7 +999,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.s3.partsConcurrency}`)
.onChange(async (val) => {
const realVal = parseInt(val);
const realVal = Number.parseInt(val);
this.plugin.settings.s3.partsConcurrency = realVal;
await this.plugin.saveSettings();
});
@ -1178,7 +1170,6 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_dropbox_revoke_button"));
button.onClick(async () => {
try {
const self = this;
const client = getClient(
this.plugin.settings,
this.app.vault.getName(),
@ -1289,7 +1280,6 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_checkonnectivity_button"));
button.onClick(async () => {
new Notice(t("settings_checkonnectivity_checking"));
const self = this;
const client = getClient(
this.plugin.settings,
this.app.vault.getName(),
@ -1434,7 +1424,6 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_checkonnectivity_button"));
button.onClick(async () => {
new Notice(t("settings_checkonnectivity_checking"));
const self = this;
const client = getClient(
this.plugin.settings,
this.app.vault.getName(),
@ -1639,7 +1628,6 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_checkonnectivity_button"));
button.onClick(async () => {
new Notice(t("settings_checkonnectivity_checking"));
const self = this;
const client = getClient(
this.plugin.settings,
this.app.vault.getName(),
@ -1769,7 +1757,6 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
button.setButtonText(t("settings_checkonnectivity_button"));
button.onClick(async () => {
new Notice(t("settings_checkonnectivity_checking"));
const self = this;
const client = getClient(
this.plugin.settings,
this.app.vault.getName(),
@ -1889,7 +1876,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.autoRunEveryMilliseconds}`)
.onChange(async (val: string) => {
const realVal = parseInt(val);
const realVal = Number.parseInt(val);
this.plugin.settings.autoRunEveryMilliseconds = realVal;
await this.plugin.saveSettings();
if (
@ -1934,7 +1921,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.initRunAfterMilliseconds}`)
.onChange(async (val: string) => {
const realVal = parseInt(val);
const realVal = Number.parseInt(val);
this.plugin.settings.initRunAfterMilliseconds = realVal;
await this.plugin.saveSettings();
});
@ -1954,7 +1941,8 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${syncOnSaveEnabled ? "1000" : "-1"}`)
.onChange(async (val: string) => {
this.plugin.settings.syncOnSaveAfterMilliseconds = parseInt(val);
this.plugin.settings.syncOnSaveAfterMilliseconds =
Number.parseInt(val);
await this.plugin.saveSettings();
this.plugin.toggleSyncOnSaveIfSet();
});
@ -1973,7 +1961,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.skipSizeLargerThan}`)
.onChange(async (val) => {
this.plugin.settings.skipSizeLargerThan = parseInt(val);
this.plugin.settings.skipSizeLargerThan = Number.parseInt(val);
await this.plugin.saveSettings();
});
});
@ -2055,7 +2043,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.concurrency}`)
.onChange(async (val) => {
const realVal = parseInt(val);
const realVal = Number.parseInt(val);
this.plugin.settings.concurrency = realVal;
await this.plugin.saveSettings();
});
@ -2183,7 +2171,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
dropdown
.setValue(`${this.plugin.settings.protectModifyPercentage ?? 50}`)
.onChange(async (val) => {
this.plugin.settings.protectModifyPercentage = parseInt(val);
this.plugin.settings.protectModifyPercentage = Number.parseInt(val);
await this.plugin.saveSettings();
});
});
@ -2515,7 +2503,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
}
hide() {
let { containerEl } = this;
const { containerEl } = this;
containerEl.empty();
super.hide();
}

View File

@ -1,5 +1,7 @@
import AggregateError from "aggregate-error";
import PQueue from "p-queue";
import XRegExp from "xregexp";
import {
import type {
ConflictActionType,
EmptyFolderCleanType,
Entity,
@ -9,15 +11,19 @@ import {
SyncDirectionType,
SyncTriggerSourceType,
} from "./baseTypes";
import { FakeFs } from "./fsAll";
import { FakeFsEncrypt } from "./fsEncrypt";
import type { FakeFs } from "./fsAll";
import type { FakeFsEncrypt } from "./fsEncrypt";
import {
InternalDBs,
type InternalDBs,
clearPrevSyncRecordByVaultAndProfile,
getAllPrevSyncRecordsByVaultAndProfile,
insertSyncPlanRecordByVault,
upsertPrevSyncRecordByVaultAndProfile,
} from "./localdb";
import {
DEFAULT_FILE_NAME_FOR_METADATAONREMOTE,
DEFAULT_FILE_NAME_FOR_METADATAONREMOTE2,
} from "./metadataOnRemote";
import {
atWhichLevel,
getParentFolder,
@ -25,13 +31,7 @@ import {
isSpecialFolderNameToSkip,
unixTimeToStr,
} from "./misc";
import { Profiler } from "./profiler";
import {
DEFAULT_FILE_NAME_FOR_METADATAONREMOTE,
DEFAULT_FILE_NAME_FOR_METADATAONREMOTE2,
} from "./metadataOnRemote";
import AggregateError from "aggregate-error";
import PQueue from "p-queue";
import type { Profiler } from "./profiler";
const copyEntityAndFixTimeFormat = (
src: Entity,

View File

@ -1,6 +1,6 @@
import { App, Modal, Notice, PluginSettingTab, Setting } from "obsidian";
import type RemotelySavePlugin from "./main"; // unavoidable
import { type App, Modal } from "obsidian";
import type { TransItemType } from "./i18n";
import type RemotelySavePlugin from "./main"; // unavoidable
import { stringToFragment } from "./misc";
@ -17,7 +17,7 @@ export class SyncAlgoV3Modal extends Modal {
this.requireUpdateAllDev = false;
}
onOpen() {
let { contentEl } = this;
const { contentEl } = this;
const t = (x: TransItemType, vars?: any) => {
return this.plugin.i18n.t(x, vars);
};
@ -112,7 +112,7 @@ export class SyncAlgoV3Modal extends Modal {
}
onClose() {
let { contentEl } = this;
const { contentEl } = this;
contentEl.empty();
if (this.agree) {
console.info("agree to use the new algorithm");

View File

@ -1,6 +1,6 @@
import { strict as assert } from "assert";
import { RemotelySavePluginSettings } from "../src/baseTypes";
import type { RemotelySavePluginSettings } from "../src/baseTypes";
import { messyConfigToNormal, normalConfigToMessy } from "../src/configPersist";
const DEFAULT_SETTINGS: RemotelySavePluginSettings = {

View File

@ -13,7 +13,7 @@ import {
import { base64ToBase64url, bufferToArrayBuffer } from "../src/misc";
describe("Encryption OpenSSL tests", () => {
beforeEach(function () {
beforeEach(() => {
global.window = {
crypto: require("crypto").webcrypto,
} as any;
@ -157,7 +157,7 @@ describe("Encryption OpenSSL tests", () => {
assert.throws(() => getSizeFromEncToOrig(14787231));
let { minSize, maxSize } = getSizeFromEncToOrig(14787232);
const { minSize, maxSize } = getSizeFromEncToOrig(14787232);
assert.ok(minSize <= 14787203 && 14787203 <= maxSize);
});
});

View File

@ -1,7 +1,7 @@
import { strict as assert } from "assert";
import {
type MetadataOnRemote,
isEqualMetadataOnRemote,
MetadataOnRemote,
} from "../src/metadataOnRemote";
describe("Metadata operations tests", () => {

View File

@ -179,7 +179,7 @@ describe("Misc: get dirname", () => {
});
describe("Misc: extract svg", () => {
beforeEach(function () {
beforeEach(() => {
const fakeBrowser = new JSDOM("");
global.window = fakeBrowser.window as any;
});