4930 lines
190 KiB
JavaScript
4930 lines
190 KiB
JavaScript
/*
|
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
if you want to view the source, please visit the github repository of this plugin
|
|
*/
|
|
|
|
"use strict";
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __commonJS = (cb, mod) => function __require() {
|
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
};
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
// file that has been converted to a CommonJS file using a Babel-
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
mod
|
|
));
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/Function.cjs
|
|
var require_Function = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/Function.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Function_exports = {};
|
|
__export2(Function_exports, {
|
|
noop: () => noop,
|
|
noopAsync: () => noopAsync,
|
|
omitAsyncReturnType: () => omitAsyncReturnType2,
|
|
omitReturnType: () => omitReturnType
|
|
});
|
|
module2.exports = __toCommonJS2(Function_exports);
|
|
function noop() {
|
|
}
|
|
async function noopAsync() {
|
|
}
|
|
function omitAsyncReturnType2(fn) {
|
|
return async (...args) => {
|
|
await fn(...args);
|
|
};
|
|
}
|
|
function omitReturnType(fn) {
|
|
return (...args) => {
|
|
fn(...args);
|
|
};
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-typings/dist/implementations.cjs
|
|
var require_implementations = __commonJS({
|
|
"node_modules/obsidian-typings/dist/implementations.cjs"(exports2, module2) {
|
|
"use strict";
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var implementations_exports = {};
|
|
__export2(implementations_exports, {
|
|
CustomArrayDictImpl: () => CustomArrayDictImpl,
|
|
InternalPluginName: () => InternalPluginName,
|
|
constructApp: () => constructApp,
|
|
constructInternalPlugin: () => constructInternalPlugin,
|
|
constructInternalPlugins: () => constructInternalPlugins,
|
|
constructTFile: () => constructTFile,
|
|
constructTFolder: () => constructTFolder,
|
|
createTFileInstance: () => createTFileInstance,
|
|
createTFolderInstance: () => createTFolderInstance,
|
|
isEmbedCache: () => isEmbedCache,
|
|
isFrontmatterLinkCache: () => isFrontmatterLinkCache,
|
|
isLinkCache: () => isLinkCache,
|
|
isReferenceCache: () => isReferenceCache,
|
|
parentFolderPath: () => parentFolderPath
|
|
});
|
|
module2.exports = __toCommonJS2(implementations_exports);
|
|
function parentFolderPath(path) {
|
|
return path.replace(/\/?[^\/]*$/, "") || "/";
|
|
}
|
|
var import_obsidian5 = require("obsidian");
|
|
function constructTFolder(vault, path) {
|
|
return new import_obsidian5.TFolder(vault, path);
|
|
}
|
|
function createTFolderInstance(vault, path) {
|
|
let folder = vault.getFolderByPath(path);
|
|
if (folder) {
|
|
return folder;
|
|
}
|
|
folder = constructTFolder(vault, path);
|
|
folder.parent = createTFolderInstance(vault, parentFolderPath(path));
|
|
folder.deleted = true;
|
|
return folder;
|
|
}
|
|
var CustomArrayDictImpl = class {
|
|
data = /* @__PURE__ */ new Map();
|
|
add(key, value) {
|
|
let values = this.get(key);
|
|
if (!values) {
|
|
values = [];
|
|
this.data.set(key, values);
|
|
}
|
|
if (!values.includes(value)) {
|
|
values.push(value);
|
|
}
|
|
}
|
|
remove(key, value) {
|
|
const values = this.get(key);
|
|
if (!values) {
|
|
return;
|
|
}
|
|
values.remove(value);
|
|
if (values.length === 0) {
|
|
this.clear(key);
|
|
}
|
|
}
|
|
get(key) {
|
|
return this.data.get(key) || null;
|
|
}
|
|
keys() {
|
|
return Array.from(this.data.keys());
|
|
}
|
|
clear(key) {
|
|
this.data.delete(key);
|
|
}
|
|
clearAll() {
|
|
this.data.clear();
|
|
}
|
|
contains(key, value) {
|
|
return !!this.get(key)?.contains(value);
|
|
}
|
|
count() {
|
|
let ans = 0;
|
|
for (const key in this.keys()) {
|
|
ans += this.get(key)?.length ?? 0;
|
|
}
|
|
return ans;
|
|
}
|
|
};
|
|
var InternalPluginName = {
|
|
AudioRecorder: "audio-recorder",
|
|
Backlink: "backlink",
|
|
Bookmarks: "bookmarks",
|
|
Canvas: "canvas",
|
|
CommandPalette: "command-palette",
|
|
DailyNotes: "daily-notes",
|
|
EditorStatus: "editor-status",
|
|
FileExplorer: "file-explorer",
|
|
FileRecovery: "file-recovery",
|
|
GlobalSearch: "global-search",
|
|
Graph: "graph",
|
|
MarkdownImporter: "markdown-importer",
|
|
NoteComposer: "note-composer",
|
|
OutgoingLink: "outgoing-link",
|
|
Outline: "outline",
|
|
PagePreview: "page-preview",
|
|
Properties: "properties",
|
|
Publish: "publish",
|
|
RandomNote: "random-note",
|
|
SlashCommand: "slash-command",
|
|
Slides: "slides",
|
|
Switcher: "switcher",
|
|
Sync: "sync",
|
|
TagPane: "tag-pane",
|
|
Templates: "templates",
|
|
WordCount: "word-count",
|
|
Workspaces: "workspaces",
|
|
ZkPrefixer: "zk-prefixer"
|
|
};
|
|
var import_obsidian22 = require("obsidian");
|
|
function constructTFile(vault, path) {
|
|
return new import_obsidian22.TFile(vault, path);
|
|
}
|
|
function createTFileInstance(vault, path) {
|
|
let file = vault.getFileByPath(path);
|
|
if (file) {
|
|
return file;
|
|
}
|
|
file = constructTFile(vault, path);
|
|
file.parent = createTFolderInstance(vault, parentFolderPath(path));
|
|
file.deleted = true;
|
|
return file;
|
|
}
|
|
function isReferenceCache(reference) {
|
|
return !!reference.position;
|
|
}
|
|
function isEmbedCache(reference) {
|
|
return isReferenceCache(reference) && reference.original[0] === "!";
|
|
}
|
|
function isFrontmatterLinkCache(reference) {
|
|
return !!reference.key;
|
|
}
|
|
function isLinkCache(reference) {
|
|
return isReferenceCache(reference) && reference.original[0] !== "!";
|
|
}
|
|
function constructInternalPlugins(app) {
|
|
return new app.internalPlugins.constructor(app);
|
|
}
|
|
function constructInternalPlugin(app, instance, internalPlugins) {
|
|
const anyPlugin = Object.values(app.internalPlugins.plugins)[0];
|
|
if (!anyPlugin) {
|
|
throw new Error("No internal plugin found");
|
|
}
|
|
return new anyPlugin.constructor(app, instance, internalPlugins);
|
|
}
|
|
var import_obsidian32 = require("obsidian");
|
|
function constructApp(adapter, appId) {
|
|
return new import_obsidian32.App(adapter, appId);
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/path-browserify/index.js
|
|
var require_path_browserify = __commonJS({
|
|
"node_modules/path-browserify/index.js"(exports2, module2) {
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
function assertPath(path) {
|
|
if (typeof path !== "string") {
|
|
throw new TypeError("Path must be a string. Received " + JSON.stringify(path));
|
|
}
|
|
}
|
|
function normalizeStringPosix(path, allowAboveRoot) {
|
|
var res = "";
|
|
var lastSegmentLength = 0;
|
|
var lastSlash = -1;
|
|
var dots = 0;
|
|
var code;
|
|
for (var i = 0; i <= path.length; ++i) {
|
|
if (i < path.length)
|
|
code = path.charCodeAt(i);
|
|
else if (code === 47)
|
|
break;
|
|
else
|
|
code = 47;
|
|
if (code === 47) {
|
|
if (lastSlash === i - 1 || dots === 1) {
|
|
} else if (lastSlash !== i - 1 && dots === 2) {
|
|
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
|
|
if (res.length > 2) {
|
|
var lastSlashIndex = res.lastIndexOf("/");
|
|
if (lastSlashIndex !== res.length - 1) {
|
|
if (lastSlashIndex === -1) {
|
|
res = "";
|
|
lastSegmentLength = 0;
|
|
} else {
|
|
res = res.slice(0, lastSlashIndex);
|
|
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
}
|
|
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 += "/..";
|
|
else
|
|
res = "..";
|
|
lastSegmentLength = 2;
|
|
}
|
|
} else {
|
|
if (res.length > 0)
|
|
res += "/" + path.slice(lastSlash + 1, i);
|
|
else
|
|
res = path.slice(lastSlash + 1, i);
|
|
lastSegmentLength = i - lastSlash - 1;
|
|
}
|
|
lastSlash = i;
|
|
dots = 0;
|
|
} else if (code === 46 && dots !== -1) {
|
|
++dots;
|
|
} else {
|
|
dots = -1;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
function _format(sep, pathObject) {
|
|
var dir = pathObject.dir || pathObject.root;
|
|
var base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
if (!dir) {
|
|
return base;
|
|
}
|
|
if (dir === pathObject.root) {
|
|
return dir + base;
|
|
}
|
|
return dir + sep + base;
|
|
}
|
|
var posix = {
|
|
// path.resolve([from ...], to)
|
|
resolve: function resolve() {
|
|
var resolvedPath = "";
|
|
var resolvedAbsolute = false;
|
|
var cwd;
|
|
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|
var path;
|
|
if (i >= 0)
|
|
path = arguments[i];
|
|
else {
|
|
if (cwd === void 0)
|
|
cwd = __process2.cwd();
|
|
path = cwd;
|
|
}
|
|
assertPath(path);
|
|
if (path.length === 0) {
|
|
continue;
|
|
}
|
|
resolvedPath = path + "/" + resolvedPath;
|
|
resolvedAbsolute = path.charCodeAt(0) === 47;
|
|
}
|
|
resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);
|
|
if (resolvedAbsolute) {
|
|
if (resolvedPath.length > 0)
|
|
return "/" + resolvedPath;
|
|
else
|
|
return "/";
|
|
} else if (resolvedPath.length > 0) {
|
|
return resolvedPath;
|
|
} else {
|
|
return ".";
|
|
}
|
|
},
|
|
normalize: function normalize(path) {
|
|
assertPath(path);
|
|
if (path.length === 0) return ".";
|
|
var isAbsolute = path.charCodeAt(0) === 47;
|
|
var trailingSeparator = path.charCodeAt(path.length - 1) === 47;
|
|
path = normalizeStringPosix(path, !isAbsolute);
|
|
if (path.length === 0 && !isAbsolute) path = ".";
|
|
if (path.length > 0 && trailingSeparator) path += "/";
|
|
if (isAbsolute) return "/" + path;
|
|
return path;
|
|
},
|
|
isAbsolute: function isAbsolute(path) {
|
|
assertPath(path);
|
|
return path.length > 0 && path.charCodeAt(0) === 47;
|
|
},
|
|
join: function join2() {
|
|
if (arguments.length === 0)
|
|
return ".";
|
|
var joined;
|
|
for (var i = 0; i < arguments.length; ++i) {
|
|
var arg = arguments[i];
|
|
assertPath(arg);
|
|
if (arg.length > 0) {
|
|
if (joined === void 0)
|
|
joined = arg;
|
|
else
|
|
joined += "/" + arg;
|
|
}
|
|
}
|
|
if (joined === void 0)
|
|
return ".";
|
|
return posix.normalize(joined);
|
|
},
|
|
relative: function relative(from, to) {
|
|
assertPath(from);
|
|
assertPath(to);
|
|
if (from === to) return "";
|
|
from = posix.resolve(from);
|
|
to = posix.resolve(to);
|
|
if (from === to) return "";
|
|
var fromStart = 1;
|
|
for (; fromStart < from.length; ++fromStart) {
|
|
if (from.charCodeAt(fromStart) !== 47)
|
|
break;
|
|
}
|
|
var fromEnd = from.length;
|
|
var fromLen = fromEnd - fromStart;
|
|
var toStart = 1;
|
|
for (; toStart < to.length; ++toStart) {
|
|
if (to.charCodeAt(toStart) !== 47)
|
|
break;
|
|
}
|
|
var toEnd = to.length;
|
|
var toLen = toEnd - toStart;
|
|
var length = fromLen < toLen ? fromLen : toLen;
|
|
var lastCommonSep = -1;
|
|
var i = 0;
|
|
for (; i <= length; ++i) {
|
|
if (i === length) {
|
|
if (toLen > length) {
|
|
if (to.charCodeAt(toStart + i) === 47) {
|
|
return to.slice(toStart + i + 1);
|
|
} else if (i === 0) {
|
|
return to.slice(toStart + i);
|
|
}
|
|
} else if (fromLen > length) {
|
|
if (from.charCodeAt(fromStart + i) === 47) {
|
|
lastCommonSep = i;
|
|
} else if (i === 0) {
|
|
lastCommonSep = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
var fromCode = from.charCodeAt(fromStart + i);
|
|
var toCode = to.charCodeAt(toStart + i);
|
|
if (fromCode !== toCode)
|
|
break;
|
|
else if (fromCode === 47)
|
|
lastCommonSep = i;
|
|
}
|
|
var out = "";
|
|
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
|
|
if (i === fromEnd || from.charCodeAt(i) === 47) {
|
|
if (out.length === 0)
|
|
out += "..";
|
|
else
|
|
out += "/..";
|
|
}
|
|
}
|
|
if (out.length > 0)
|
|
return out + to.slice(toStart + lastCommonSep);
|
|
else {
|
|
toStart += lastCommonSep;
|
|
if (to.charCodeAt(toStart) === 47)
|
|
++toStart;
|
|
return to.slice(toStart);
|
|
}
|
|
},
|
|
_makeLong: function _makeLong(path) {
|
|
return path;
|
|
},
|
|
dirname: function dirname4(path) {
|
|
assertPath(path);
|
|
if (path.length === 0) return ".";
|
|
var code = path.charCodeAt(0);
|
|
var hasRoot = code === 47;
|
|
var end = -1;
|
|
var matchedSlash = true;
|
|
for (var i = path.length - 1; i >= 1; --i) {
|
|
code = path.charCodeAt(i);
|
|
if (code === 47) {
|
|
if (!matchedSlash) {
|
|
end = i;
|
|
break;
|
|
}
|
|
} else {
|
|
matchedSlash = false;
|
|
}
|
|
}
|
|
if (end === -1) return hasRoot ? "/" : ".";
|
|
if (hasRoot && end === 1) return "//";
|
|
return path.slice(0, end);
|
|
},
|
|
basename: function basename(path, ext) {
|
|
if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string');
|
|
assertPath(path);
|
|
var start = 0;
|
|
var end = -1;
|
|
var matchedSlash = true;
|
|
var i;
|
|
if (ext !== void 0 && ext.length > 0 && ext.length <= path.length) {
|
|
if (ext.length === path.length && ext === path) return "";
|
|
var extIdx = ext.length - 1;
|
|
var firstNonSlashEnd = -1;
|
|
for (i = path.length - 1; i >= 0; --i) {
|
|
var code = path.charCodeAt(i);
|
|
if (code === 47) {
|
|
if (!matchedSlash) {
|
|
start = i + 1;
|
|
break;
|
|
}
|
|
} else {
|
|
if (firstNonSlashEnd === -1) {
|
|
matchedSlash = false;
|
|
firstNonSlashEnd = i + 1;
|
|
}
|
|
if (extIdx >= 0) {
|
|
if (code === ext.charCodeAt(extIdx)) {
|
|
if (--extIdx === -1) {
|
|
end = i;
|
|
}
|
|
} else {
|
|
extIdx = -1;
|
|
end = firstNonSlashEnd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (start === end) end = firstNonSlashEnd;
|
|
else if (end === -1) end = path.length;
|
|
return path.slice(start, end);
|
|
} else {
|
|
for (i = path.length - 1; i >= 0; --i) {
|
|
if (path.charCodeAt(i) === 47) {
|
|
if (!matchedSlash) {
|
|
start = i + 1;
|
|
break;
|
|
}
|
|
} else if (end === -1) {
|
|
matchedSlash = false;
|
|
end = i + 1;
|
|
}
|
|
}
|
|
if (end === -1) return "";
|
|
return path.slice(start, end);
|
|
}
|
|
},
|
|
extname: function extname(path) {
|
|
assertPath(path);
|
|
var startDot = -1;
|
|
var startPart = 0;
|
|
var end = -1;
|
|
var matchedSlash = true;
|
|
var preDotState = 0;
|
|
for (var i = path.length - 1; i >= 0; --i) {
|
|
var code = path.charCodeAt(i);
|
|
if (code === 47) {
|
|
if (!matchedSlash) {
|
|
startPart = i + 1;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if (end === -1) {
|
|
matchedSlash = false;
|
|
end = i + 1;
|
|
}
|
|
if (code === 46) {
|
|
if (startDot === -1)
|
|
startDot = i;
|
|
else if (preDotState !== 1)
|
|
preDotState = 1;
|
|
} else if (startDot !== -1) {
|
|
preDotState = -1;
|
|
}
|
|
}
|
|
if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot
|
|
preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
|
|
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|
return "";
|
|
}
|
|
return path.slice(startDot, end);
|
|
},
|
|
format: function format(pathObject) {
|
|
if (pathObject === null || typeof pathObject !== "object") {
|
|
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
|
|
}
|
|
return _format("/", pathObject);
|
|
},
|
|
parse: function parse(path) {
|
|
assertPath(path);
|
|
var ret = { root: "", dir: "", base: "", ext: "", name: "" };
|
|
if (path.length === 0) return ret;
|
|
var code = path.charCodeAt(0);
|
|
var isAbsolute = code === 47;
|
|
var start;
|
|
if (isAbsolute) {
|
|
ret.root = "/";
|
|
start = 1;
|
|
} else {
|
|
start = 0;
|
|
}
|
|
var startDot = -1;
|
|
var startPart = 0;
|
|
var end = -1;
|
|
var matchedSlash = true;
|
|
var i = path.length - 1;
|
|
var preDotState = 0;
|
|
for (; i >= start; --i) {
|
|
code = path.charCodeAt(i);
|
|
if (code === 47) {
|
|
if (!matchedSlash) {
|
|
startPart = i + 1;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if (end === -1) {
|
|
matchedSlash = false;
|
|
end = i + 1;
|
|
}
|
|
if (code === 46) {
|
|
if (startDot === -1) startDot = i;
|
|
else if (preDotState !== 1) preDotState = 1;
|
|
} else if (startDot !== -1) {
|
|
preDotState = -1;
|
|
}
|
|
}
|
|
if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot
|
|
preDotState === 0 || // The (right-most) trimmed path component is exactly '..'
|
|
preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|
if (end !== -1) {
|
|
if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);
|
|
else ret.base = ret.name = path.slice(startPart, end);
|
|
}
|
|
} else {
|
|
if (startPart === 0 && isAbsolute) {
|
|
ret.name = path.slice(1, startDot);
|
|
ret.base = path.slice(1, end);
|
|
} else {
|
|
ret.name = path.slice(startPart, startDot);
|
|
ret.base = path.slice(startPart, end);
|
|
}
|
|
ret.ext = path.slice(startDot, end);
|
|
}
|
|
if (startPart > 0) ret.dir = path.slice(0, startPart - 1);
|
|
else if (isAbsolute) ret.dir = "/";
|
|
return ret;
|
|
},
|
|
sep: "/",
|
|
delimiter: ":",
|
|
win32: null,
|
|
posix: null
|
|
};
|
|
posix.posix = posix;
|
|
module2.exports = posix;
|
|
}
|
|
});
|
|
|
|
// node_modules/eventemitter3/index.js
|
|
var require_eventemitter3 = __commonJS({
|
|
"node_modules/eventemitter3/index.js"(exports2, module2) {
|
|
"use strict";
|
|
var has = Object.prototype.hasOwnProperty;
|
|
var prefix = "~";
|
|
function Events() {
|
|
}
|
|
if (Object.create) {
|
|
Events.prototype = /* @__PURE__ */ Object.create(null);
|
|
if (!new Events().__proto__) prefix = false;
|
|
}
|
|
function EE(fn, context, once) {
|
|
this.fn = fn;
|
|
this.context = context;
|
|
this.once = once || false;
|
|
}
|
|
function addListener(emitter, event, fn, context, once) {
|
|
if (typeof fn !== "function") {
|
|
throw new TypeError("The listener must be a function");
|
|
}
|
|
var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
|
|
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
|
|
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
|
|
else emitter._events[evt] = [emitter._events[evt], listener];
|
|
return emitter;
|
|
}
|
|
function clearEvent(emitter, evt) {
|
|
if (--emitter._eventsCount === 0) emitter._events = new Events();
|
|
else delete emitter._events[evt];
|
|
}
|
|
function EventEmitter() {
|
|
this._events = new Events();
|
|
this._eventsCount = 0;
|
|
}
|
|
EventEmitter.prototype.eventNames = function eventNames() {
|
|
var names = [], events, name;
|
|
if (this._eventsCount === 0) return names;
|
|
for (name in events = this._events) {
|
|
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
|
|
}
|
|
if (Object.getOwnPropertySymbols) {
|
|
return names.concat(Object.getOwnPropertySymbols(events));
|
|
}
|
|
return names;
|
|
};
|
|
EventEmitter.prototype.listeners = function listeners(event) {
|
|
var evt = prefix ? prefix + event : event, handlers = this._events[evt];
|
|
if (!handlers) return [];
|
|
if (handlers.fn) return [handlers.fn];
|
|
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
|
|
ee[i] = handlers[i].fn;
|
|
}
|
|
return ee;
|
|
};
|
|
EventEmitter.prototype.listenerCount = function listenerCount(event) {
|
|
var evt = prefix ? prefix + event : event, listeners = this._events[evt];
|
|
if (!listeners) return 0;
|
|
if (listeners.fn) return 1;
|
|
return listeners.length;
|
|
};
|
|
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
|
var evt = prefix ? prefix + event : event;
|
|
if (!this._events[evt]) return false;
|
|
var listeners = this._events[evt], len = arguments.length, args, i;
|
|
if (listeners.fn) {
|
|
if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
|
|
switch (len) {
|
|
case 1:
|
|
return listeners.fn.call(listeners.context), true;
|
|
case 2:
|
|
return listeners.fn.call(listeners.context, a1), true;
|
|
case 3:
|
|
return listeners.fn.call(listeners.context, a1, a2), true;
|
|
case 4:
|
|
return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
|
case 5:
|
|
return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
|
case 6:
|
|
return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
|
}
|
|
for (i = 1, args = new Array(len - 1); i < len; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
listeners.fn.apply(listeners.context, args);
|
|
} else {
|
|
var length = listeners.length, j;
|
|
for (i = 0; i < length; i++) {
|
|
if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
|
|
switch (len) {
|
|
case 1:
|
|
listeners[i].fn.call(listeners[i].context);
|
|
break;
|
|
case 2:
|
|
listeners[i].fn.call(listeners[i].context, a1);
|
|
break;
|
|
case 3:
|
|
listeners[i].fn.call(listeners[i].context, a1, a2);
|
|
break;
|
|
case 4:
|
|
listeners[i].fn.call(listeners[i].context, a1, a2, a3);
|
|
break;
|
|
default:
|
|
if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) {
|
|
args[j - 1] = arguments[j];
|
|
}
|
|
listeners[i].fn.apply(listeners[i].context, args);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
EventEmitter.prototype.on = function on(event, fn, context) {
|
|
return addListener(this, event, fn, context, false);
|
|
};
|
|
EventEmitter.prototype.once = function once(event, fn, context) {
|
|
return addListener(this, event, fn, context, true);
|
|
};
|
|
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
|
var evt = prefix ? prefix + event : event;
|
|
if (!this._events[evt]) return this;
|
|
if (!fn) {
|
|
clearEvent(this, evt);
|
|
return this;
|
|
}
|
|
var listeners = this._events[evt];
|
|
if (listeners.fn) {
|
|
if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
|
|
clearEvent(this, evt);
|
|
}
|
|
} else {
|
|
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
|
if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
|
|
events.push(listeners[i]);
|
|
}
|
|
}
|
|
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
|
|
else clearEvent(this, evt);
|
|
}
|
|
return this;
|
|
};
|
|
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
|
var evt;
|
|
if (event) {
|
|
evt = prefix ? prefix + event : event;
|
|
if (this._events[evt]) clearEvent(this, evt);
|
|
} else {
|
|
this._events = new Events();
|
|
this._eventsCount = 0;
|
|
}
|
|
return this;
|
|
};
|
|
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
|
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
|
EventEmitter.prefixed = prefix;
|
|
EventEmitter.EventEmitter = EventEmitter;
|
|
if ("undefined" !== typeof module2) {
|
|
module2.exports = EventEmitter;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/Error.cjs
|
|
var require_Error = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/Error.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Error_exports = {};
|
|
__export2(Error_exports, {
|
|
emitAsyncErrorEvent: () => emitAsyncErrorEvent,
|
|
errorToString: () => errorToString,
|
|
getStackTrace: () => getStackTrace,
|
|
printError: () => printError,
|
|
registerAsyncErrorEventHandler: () => registerAsyncErrorEventHandler,
|
|
throwExpression: () => throwExpression
|
|
});
|
|
module2.exports = __toCommonJS2(Error_exports);
|
|
var import_eventemitter3 = require_eventemitter3();
|
|
var ASYNC_ERROR_EVENT = "asyncError";
|
|
var asyncErrorEventEmitter = new import_eventemitter3.EventEmitter();
|
|
asyncErrorEventEmitter.on(ASYNC_ERROR_EVENT, handleAsyncError);
|
|
function emitAsyncErrorEvent(asyncError) {
|
|
asyncErrorEventEmitter.emit(ASYNC_ERROR_EVENT, asyncError);
|
|
}
|
|
function errorToString(error) {
|
|
return parseErrorEntries(error).map((entry) => " ".repeat(entry.level) + entry.message).join("\n");
|
|
}
|
|
function getStackTrace() {
|
|
const stack = new Error().stack ?? "";
|
|
const lines = stack.split("\n");
|
|
return lines.slice(2).join("\n");
|
|
}
|
|
function printError(error) {
|
|
const entries = parseErrorEntries(error);
|
|
for (const entry of entries) {
|
|
if (entry.shouldClearAnsiSequence) {
|
|
console.error(`\x1B[0m${entry.message}\x1B[0m`);
|
|
} else {
|
|
console.error(entry.message);
|
|
}
|
|
}
|
|
}
|
|
function registerAsyncErrorEventHandler(handler) {
|
|
asyncErrorEventEmitter.on(ASYNC_ERROR_EVENT, handler);
|
|
return () => asyncErrorEventEmitter.off(ASYNC_ERROR_EVENT, handler);
|
|
}
|
|
function throwExpression(error) {
|
|
throw error;
|
|
}
|
|
function handleAsyncError(asyncError) {
|
|
printError(new Error("An unhandled error occurred executing async operation", { cause: asyncError }));
|
|
}
|
|
function parseErrorEntries(error, level = 0, entries = []) {
|
|
if (error === void 0) {
|
|
return entries;
|
|
}
|
|
if (!(error instanceof Error)) {
|
|
let str = "";
|
|
if (error === null) {
|
|
str = "(null)";
|
|
} else if (typeof error === "string") {
|
|
str = error;
|
|
} else {
|
|
str = JSON.stringify(error);
|
|
}
|
|
entries.push({ level, message: str });
|
|
return entries;
|
|
}
|
|
const title = `${error.name}: ${error.message}`;
|
|
entries.push({ level, message: title, shouldClearAnsiSequence: true });
|
|
if (error.stack) {
|
|
const restStack = error.stack.startsWith(title) ? error.stack.slice(title.length + 1) : error.stack;
|
|
entries.push({ level, message: `Error stack:
|
|
${restStack}` });
|
|
}
|
|
if (error.cause !== void 0) {
|
|
entries.push({ level, message: "Caused by:" });
|
|
parseErrorEntries(error.cause, level + 1, entries);
|
|
}
|
|
return entries;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/RegExp.cjs
|
|
var require_RegExp = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/RegExp.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var RegExp_exports = {};
|
|
__export2(RegExp_exports, {
|
|
escapeRegExp: () => escapeRegExp
|
|
});
|
|
module2.exports = __toCommonJS2(RegExp_exports);
|
|
function escapeRegExp(str) {
|
|
return str.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/ValueProvider.cjs
|
|
var require_ValueProvider = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/ValueProvider.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var ValueProvider_exports = {};
|
|
__export2(ValueProvider_exports, {
|
|
resolveValue: () => resolveValue
|
|
});
|
|
module2.exports = __toCommonJS2(ValueProvider_exports);
|
|
async function resolveValue(provider, ...args) {
|
|
if (isFunction(provider)) {
|
|
return await provider(...args);
|
|
} else {
|
|
return provider;
|
|
}
|
|
}
|
|
function isFunction(value) {
|
|
return typeof value === "function";
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/String.cjs
|
|
var require_String = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/String.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var String_exports = {};
|
|
__export2(String_exports, {
|
|
ensureEndsWith: () => ensureEndsWith,
|
|
ensureStartsWith: () => ensureStartsWith,
|
|
escape: () => escape,
|
|
insertAt: () => insertAt,
|
|
makeValidVariableName: () => makeValidVariableName,
|
|
normalize: () => normalize,
|
|
replace: () => replace,
|
|
replaceAllAsync: () => replaceAllAsync,
|
|
trimEnd: () => trimEnd,
|
|
trimStart: () => trimStart,
|
|
unescape: () => unescape
|
|
});
|
|
module2.exports = __toCommonJS2(String_exports);
|
|
var import_Error = require_Error();
|
|
var import_RegExp = require_RegExp();
|
|
var import_ValueProvider = require_ValueProvider();
|
|
var ESCAPE_MAP = {
|
|
"\n": "\\n",
|
|
"\r": "\\r",
|
|
" ": "\\t",
|
|
"\b": "\\b",
|
|
"\f": "\\f",
|
|
"'": "\\'",
|
|
'"': '\\"',
|
|
"\\": "\\\\"
|
|
};
|
|
var UNESCAPE_MAP = {};
|
|
for (const [key, value] of Object.entries(ESCAPE_MAP)) {
|
|
UNESCAPE_MAP[value] = key;
|
|
}
|
|
function ensureEndsWith(str, suffix) {
|
|
return str.endsWith(suffix) ? str : str + suffix;
|
|
}
|
|
function ensureStartsWith(str, prefix) {
|
|
return str.startsWith(prefix) ? str : prefix + str;
|
|
}
|
|
function escape(str) {
|
|
return replace(str, ESCAPE_MAP);
|
|
}
|
|
function insertAt(str, substring, startIndex, endIndex) {
|
|
endIndex ??= startIndex;
|
|
return str.slice(0, startIndex) + substring + str.slice(endIndex);
|
|
}
|
|
function makeValidVariableName(str) {
|
|
return str.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
}
|
|
function normalize(str) {
|
|
return str.replace(/\u00A0|\u202F/g, " ").normalize("NFC");
|
|
}
|
|
function replace(str, replacementsMap) {
|
|
const regExp = new RegExp(Object.keys(replacementsMap).map((source) => (0, import_RegExp.escapeRegExp)(source)).join("|"), "g");
|
|
return str.replaceAll(regExp, (source) => replacementsMap[source] ?? (0, import_Error.throwExpression)(new Error(`Unexpected replacement source: ${source}`)));
|
|
}
|
|
async function replaceAllAsync(str, searchValue, replacer) {
|
|
const replacementPromises = [];
|
|
str.replaceAll(searchValue, (substring, ...args) => {
|
|
replacementPromises.push((0, import_ValueProvider.resolveValue)(replacer, substring, ...args));
|
|
return substring;
|
|
});
|
|
const replacements = await Promise.all(replacementPromises);
|
|
return str.replaceAll(searchValue, () => replacements.shift() ?? (0, import_Error.throwExpression)(new Error("Unexpected empty replacement")));
|
|
}
|
|
function trimEnd(str, suffix, validate) {
|
|
if (str.endsWith(suffix)) {
|
|
return str.slice(0, -suffix.length);
|
|
}
|
|
if (validate) {
|
|
throw new Error(`String ${str} does not end with suffix ${suffix}`);
|
|
}
|
|
return str;
|
|
}
|
|
function trimStart(str, prefix, validate) {
|
|
if (str.startsWith(prefix)) {
|
|
return str.slice(prefix.length);
|
|
}
|
|
if (validate) {
|
|
throw new Error(`String ${str} does not start with prefix ${prefix}`);
|
|
}
|
|
return str;
|
|
}
|
|
function unescape(str) {
|
|
return replace(str, UNESCAPE_MAP);
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/Path.cjs
|
|
var require_Path = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/Path.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __create2 = Object.create;
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
// file that has been converted to a CommonJS file using a Babel-
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
mod
|
|
));
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Path_exports = {};
|
|
__export2(Path_exports, {
|
|
basename: () => basename,
|
|
delimiter: () => delimiter,
|
|
dirname: () => dirname4,
|
|
extname: () => extname,
|
|
format: () => format,
|
|
getDirname: () => getDirname,
|
|
getFilename: () => getFilename,
|
|
isAbsolute: () => isAbsolute,
|
|
join: () => join2,
|
|
makeFileName: () => makeFileName,
|
|
normalize: () => normalize,
|
|
normalizeIfRelative: () => normalizeIfRelative,
|
|
parse: () => parse,
|
|
posix: () => posix,
|
|
relative: () => relative,
|
|
resolve: () => resolve,
|
|
sep: () => sep,
|
|
toPosixBuffer: () => toPosixBuffer,
|
|
toPosixPath: () => toPosixPath
|
|
});
|
|
module2.exports = __toCommonJS2(Path_exports);
|
|
var import_path_browserify = __toESM2(require_path_browserify(), 1);
|
|
var import_String = require_String();
|
|
var WINDOWS_POSIX_LIKE_PATH_REG_EXP = /[a-zA-Z]:\/[^:]*$/;
|
|
var posix = import_path_browserify.default.posix;
|
|
var delimiter = posix.delimiter;
|
|
var sep = import_path_browserify.default.posix.sep;
|
|
var basename = posix.basename;
|
|
var dirname4 = posix.dirname;
|
|
var extname = posix.extname;
|
|
var format = posix.format;
|
|
function isAbsolute(path2) {
|
|
return posix.isAbsolute(path2) || WINDOWS_POSIX_LIKE_PATH_REG_EXP.exec(path2)?.[0] === path2;
|
|
}
|
|
var join2 = posix.join;
|
|
var normalize = posix.normalize;
|
|
var parse = posix.parse;
|
|
var relative = posix.relative;
|
|
function getDirname(importMetaUrl) {
|
|
return dirname4(getFilename(importMetaUrl));
|
|
}
|
|
function getFilename(importMetaUrl) {
|
|
return resolve(new URL(importMetaUrl).pathname);
|
|
}
|
|
function makeFileName(fileName, extension) {
|
|
return extension ? `${fileName}.${extension}` : fileName;
|
|
}
|
|
function normalizeIfRelative(path2) {
|
|
if (path2.startsWith("/") || path2.includes(":")) {
|
|
return path2;
|
|
}
|
|
return (0, import_String.ensureStartsWith)(path2, "./");
|
|
}
|
|
function resolve(...pathSegments) {
|
|
let path2 = posix.resolve(...pathSegments);
|
|
path2 = toPosixPath(path2);
|
|
const match = WINDOWS_POSIX_LIKE_PATH_REG_EXP.exec(path2);
|
|
return match?.[0] ?? path2;
|
|
}
|
|
function toPosixBuffer(buffer) {
|
|
return Buffer.from(toPosixPath(buffer.toString()));
|
|
}
|
|
function toPosixPath(path2) {
|
|
return path2.replace(/\\/g, "/");
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/FileSystem.cjs
|
|
var require_FileSystem = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/FileSystem.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var FileSystem_exports = {};
|
|
__export2(FileSystem_exports, {
|
|
CANVAS_FILE_EXTENSION: () => CANVAS_FILE_EXTENSION,
|
|
MARKDOWN_FILE_EXTENSION: () => MARKDOWN_FILE_EXTENSION2,
|
|
checkExtension: () => checkExtension,
|
|
getAbstractFile: () => getAbstractFile,
|
|
getAbstractFileOrNull: () => getAbstractFileOrNull,
|
|
getFile: () => getFile,
|
|
getFileOrNull: () => getFileOrNull3,
|
|
getFolder: () => getFolder,
|
|
getFolderOrNull: () => getFolderOrNull,
|
|
getMarkdownFiles: () => getMarkdownFiles,
|
|
getOrCreateFile: () => getOrCreateFile2,
|
|
getOrCreateFolder: () => getOrCreateFolder,
|
|
getPath: () => getPath,
|
|
isAbstractFile: () => isAbstractFile,
|
|
isCanvasFile: () => isCanvasFile,
|
|
isFile: () => isFile,
|
|
isFolder: () => isFolder,
|
|
isMarkdownFile: () => isMarkdownFile2,
|
|
isNote: () => isNote2,
|
|
trimMarkdownExtension: () => trimMarkdownExtension
|
|
});
|
|
module2.exports = __toCommonJS2(FileSystem_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_implementations = require_implementations();
|
|
var import_Path4 = require_Path();
|
|
var import_String = require_String();
|
|
var MARKDOWN_FILE_EXTENSION2 = "md";
|
|
var CANVAS_FILE_EXTENSION = "canvas";
|
|
function checkExtension(pathOrFile, extension) {
|
|
if (pathOrFile === null) {
|
|
return false;
|
|
}
|
|
return (0, import_Path4.extname)(getPath(pathOrFile)).toLowerCase().slice(1) === extension.toLowerCase();
|
|
}
|
|
function getAbstractFile(app, pathOrFile, insensitive) {
|
|
const file = getAbstractFileOrNull(app, pathOrFile, insensitive);
|
|
if (!file) {
|
|
throw new Error(`Abstract file not found: ${pathOrFile}`);
|
|
}
|
|
return file;
|
|
}
|
|
function getAbstractFileOrNull(app, pathOrFile, insensitive) {
|
|
if (pathOrFile === null) {
|
|
return null;
|
|
}
|
|
if (pathOrFile === "." || pathOrFile === "") {
|
|
return app.vault.getRoot();
|
|
}
|
|
if (isAbstractFile(pathOrFile)) {
|
|
return pathOrFile;
|
|
}
|
|
if (insensitive) {
|
|
return app.vault.getAbstractFileByPathInsensitive(pathOrFile);
|
|
}
|
|
return app.vault.getAbstractFileByPath(pathOrFile);
|
|
}
|
|
function getFile(app, pathOrFile, allowNonExisting, insensitive) {
|
|
let file = getFileOrNull3(app, pathOrFile, insensitive);
|
|
if (!file) {
|
|
if (allowNonExisting) {
|
|
file = (0, import_implementations.createTFileInstance)(app.vault, pathOrFile);
|
|
} else {
|
|
throw new Error(`File not found: ${pathOrFile}`);
|
|
}
|
|
}
|
|
return file;
|
|
}
|
|
function getFileOrNull3(app, pathOrFile, insensitive) {
|
|
const file = getAbstractFileOrNull(app, pathOrFile, insensitive);
|
|
if (isFile(file)) {
|
|
return file;
|
|
}
|
|
return null;
|
|
}
|
|
function getFolder(app, pathOrFolder, allowNonExisting, insensitive) {
|
|
let folder = getFolderOrNull(app, pathOrFolder, insensitive);
|
|
if (!folder) {
|
|
if (allowNonExisting) {
|
|
folder = (0, import_implementations.createTFolderInstance)(app.vault, pathOrFolder);
|
|
} else {
|
|
throw new Error(`Folder not found: ${pathOrFolder}`);
|
|
}
|
|
}
|
|
return folder;
|
|
}
|
|
function getFolderOrNull(app, pathOrFolder, insensitive) {
|
|
const folder = getAbstractFileOrNull(app, pathOrFolder, insensitive);
|
|
if (isFolder(folder)) {
|
|
return folder;
|
|
}
|
|
return null;
|
|
}
|
|
function getMarkdownFiles(app, pathOrFolder, isRecursive) {
|
|
const folder = getFolder(app, pathOrFolder);
|
|
let markdownFiles = [];
|
|
if (!isRecursive) {
|
|
markdownFiles = folder.children.filter((file) => isMarkdownFile2(file));
|
|
} else {
|
|
import_obsidian5.Vault.recurseChildren(folder, (abstractFile) => {
|
|
if (isMarkdownFile2(abstractFile)) {
|
|
markdownFiles.push(abstractFile);
|
|
}
|
|
});
|
|
}
|
|
markdownFiles = markdownFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
return markdownFiles;
|
|
}
|
|
async function getOrCreateFile2(app, path) {
|
|
const file = getFileOrNull3(app, path);
|
|
if (file) {
|
|
return file;
|
|
}
|
|
const folderPath = (0, import_implementations.parentFolderPath)(path);
|
|
await getOrCreateFolder(app, folderPath);
|
|
return await app.vault.create(path, "");
|
|
}
|
|
async function getOrCreateFolder(app, path) {
|
|
const folder = getFolderOrNull(app, path);
|
|
if (folder) {
|
|
return folder;
|
|
}
|
|
return await app.vault.createFolder(path);
|
|
}
|
|
function getPath(pathOrFile) {
|
|
return isAbstractFile(pathOrFile) ? pathOrFile.path : pathOrFile;
|
|
}
|
|
function isAbstractFile(file) {
|
|
return file instanceof import_obsidian5.TAbstractFile;
|
|
}
|
|
function isCanvasFile(pathOrFile) {
|
|
return checkExtension(pathOrFile, CANVAS_FILE_EXTENSION);
|
|
}
|
|
function isFile(file) {
|
|
return file instanceof import_obsidian5.TFile;
|
|
}
|
|
function isFolder(file) {
|
|
return file instanceof import_obsidian5.TFolder;
|
|
}
|
|
function isMarkdownFile2(pathOrFile) {
|
|
return checkExtension(pathOrFile, MARKDOWN_FILE_EXTENSION2);
|
|
}
|
|
function isNote2(pathOrFile) {
|
|
return isMarkdownFile2(pathOrFile) || isCanvasFile(pathOrFile);
|
|
}
|
|
function trimMarkdownExtension(file) {
|
|
if (!isMarkdownFile2(file)) {
|
|
return file.path;
|
|
}
|
|
return (0, import_String.trimEnd)(file.path, "." + MARKDOWN_FILE_EXTENSION2);
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettings.cjs
|
|
var require_PluginSettings = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettings.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var PluginSettings_exports = {};
|
|
__export2(PluginSettings_exports, {
|
|
clonePluginSettings: () => clonePluginSettings,
|
|
loadPluginSettings: () => loadPluginSettings
|
|
});
|
|
module2.exports = __toCommonJS2(PluginSettings_exports);
|
|
function clonePluginSettings(defaultPluginSettingsFactory, settings) {
|
|
return loadPluginSettings(defaultPluginSettingsFactory, settings);
|
|
}
|
|
function loadPluginSettings(defaultPluginSettingsFactory, data) {
|
|
const defaultPluginSettings = defaultPluginSettingsFactory();
|
|
if (data && typeof data === "object") {
|
|
const record = data;
|
|
for (const [key, value] of Object.entries(record)) {
|
|
if (key in defaultPluginSettings) {
|
|
defaultPluginSettings[key] = value;
|
|
}
|
|
}
|
|
}
|
|
return defaultPluginSettings;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginBase.cjs
|
|
var require_PluginBase = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginBase.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var PluginBase_exports = {};
|
|
__export2(PluginBase_exports, {
|
|
PluginBase: () => PluginBase2
|
|
});
|
|
module2.exports = __toCommonJS2(PluginBase_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_Error = require_Error();
|
|
var import_Function2 = require_Function();
|
|
var import_PluginSettings = require_PluginSettings();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
var PluginBase2 = class extends import_obsidian5.Plugin {
|
|
/**
|
|
* Gets a copy of the current plugin settings.
|
|
*
|
|
* @returns A copy of the plugin settings.
|
|
*/
|
|
get settingsCopy() {
|
|
return (0, import_PluginSettings.clonePluginSettings)(this.createDefaultPluginSettings.bind(this), this.settings);
|
|
}
|
|
/**
|
|
* Gets the AbortSignal used for aborting long-running operations.
|
|
*
|
|
* @returns The abort signal.
|
|
*/
|
|
get abortSignal() {
|
|
return this._abortSignal;
|
|
}
|
|
/**
|
|
* Gets the plugin settings.
|
|
*
|
|
* @returns The plugin settings.
|
|
*/
|
|
get settings() {
|
|
return this._settings;
|
|
}
|
|
_abortSignal;
|
|
_settings;
|
|
notice;
|
|
/**
|
|
* Called when the plugin is loaded
|
|
*/
|
|
async onload() {
|
|
this.register((0, import_Error.registerAsyncErrorEventHandler)(() => {
|
|
this.showNotice("An unhandled error occurred. Please check the console for more information.");
|
|
}));
|
|
await this.loadSettings();
|
|
const pluginSettingsTab = this.createPluginSettingsTab();
|
|
if (pluginSettingsTab) {
|
|
this.addSettingTab(pluginSettingsTab);
|
|
}
|
|
const abortController = new AbortController();
|
|
this._abortSignal = abortController.signal;
|
|
this.register(() => {
|
|
abortController.abort();
|
|
});
|
|
await this.onloadComplete();
|
|
this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this));
|
|
}
|
|
/**
|
|
* Saves the new plugin settings.
|
|
*
|
|
* @param newSettings - The new settings to save.
|
|
* @returns A promise that resolves when the settings are saved.
|
|
*/
|
|
async saveSettings(newSettings) {
|
|
this._settings = (0, import_PluginSettings.clonePluginSettings)(this.createDefaultPluginSettings.bind(this), newSettings);
|
|
await this.saveData(this.settings);
|
|
}
|
|
/**
|
|
* Called when the layout is ready. This method can be overridden by subclasses to perform actions once
|
|
* the layout is ready.
|
|
*
|
|
* @returns A promise or void indicating the completion of the layout setup.
|
|
*/
|
|
onLayoutReady() {
|
|
(0, import_Function2.noop)();
|
|
}
|
|
/**
|
|
* Called when the plugin loading is complete. This method must be implemented by subclasses to perform
|
|
* any additional setup required after loading is complete.
|
|
*
|
|
* @returns A promise or void indicating the completion of the load process.
|
|
*/
|
|
onloadComplete() {
|
|
(0, import_Function2.noop)();
|
|
}
|
|
/**
|
|
* Parses the provided settings data and returns the parsed `PluginSettings`.
|
|
*
|
|
* @param data - The raw data to be parsed into `PluginSettings`.
|
|
* @returns A promise that resolves to `PluginSettings` or the settings directly.
|
|
*/
|
|
parseSettings(data) {
|
|
return (0, import_PluginSettings.loadPluginSettings)(this.createDefaultPluginSettings.bind(this), data);
|
|
}
|
|
/**
|
|
* Displays a notice message to the user.
|
|
*
|
|
* @param message - The message to display.
|
|
*/
|
|
showNotice(message) {
|
|
if (this.notice) {
|
|
this.notice.hide();
|
|
}
|
|
this.notice = new import_obsidian5.Notice(`${this.manifest.name}
|
|
${message}`);
|
|
}
|
|
/**
|
|
* Loads the plugin settings from the saved data.
|
|
*
|
|
* @returns A promise that resolves when the settings are loaded.
|
|
*/
|
|
async loadSettings() {
|
|
const data = await this.loadData();
|
|
this._settings = await this.parseSettings(data);
|
|
}
|
|
};
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/Async.cjs
|
|
var require_Async = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/Async.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Async_exports = {};
|
|
__export2(Async_exports, {
|
|
addErrorHandler: () => addErrorHandler,
|
|
asyncFilter: () => asyncFilter,
|
|
asyncFlatMap: () => asyncFlatMap,
|
|
asyncMap: () => asyncMap,
|
|
convertAsyncToSync: () => convertAsyncToSync,
|
|
convertSyncToAsync: () => convertSyncToAsync,
|
|
invokeAsyncSafely: () => invokeAsyncSafely,
|
|
marksAsTerminateRetry: () => marksAsTerminateRetry,
|
|
retryWithTimeout: () => retryWithTimeout,
|
|
runWithTimeout: () => runWithTimeout,
|
|
sleep: () => sleep,
|
|
timeout: () => timeout,
|
|
toArray: () => toArray
|
|
});
|
|
module2.exports = __toCommonJS2(Async_exports);
|
|
var import_Error = require_Error();
|
|
async function addErrorHandler(asyncFn) {
|
|
try {
|
|
await asyncFn();
|
|
} catch (asyncError) {
|
|
(0, import_Error.emitAsyncErrorEvent)(asyncError);
|
|
}
|
|
}
|
|
async function asyncFilter(arr, predicate) {
|
|
const predicateResults = await asyncMap(arr, predicate);
|
|
return arr.filter((_, index) => predicateResults[index]);
|
|
}
|
|
async function asyncFlatMap(arr, callback) {
|
|
return (await asyncMap(arr, callback)).flat();
|
|
}
|
|
async function asyncMap(arr, callback) {
|
|
return await Promise.all(arr.map(callback));
|
|
}
|
|
function convertAsyncToSync(asyncFunc) {
|
|
return (...args) => {
|
|
invokeAsyncSafely(() => asyncFunc(...args));
|
|
};
|
|
}
|
|
function convertSyncToAsync(syncFn) {
|
|
return (...args) => Promise.resolve().then(() => syncFn(...args));
|
|
}
|
|
function invokeAsyncSafely(asyncFn) {
|
|
void addErrorHandler(asyncFn);
|
|
}
|
|
function marksAsTerminateRetry(error) {
|
|
return Object.assign(error, { __terminateRetry: true });
|
|
}
|
|
async function retryWithTimeout(fn, retryOptions = {}) {
|
|
const stackTrace = (0, import_Error.getStackTrace)();
|
|
const DEFAULT_RETRY_OPTIONS = {
|
|
retryDelayInMilliseconds: 100,
|
|
shouldRetryOnError: true,
|
|
timeoutInMilliseconds: 5e3
|
|
};
|
|
const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions };
|
|
await runWithTimeout(overriddenOptions.timeoutInMilliseconds, async () => {
|
|
let attempt = 0;
|
|
for (; ; ) {
|
|
attempt++;
|
|
let isSuccess;
|
|
try {
|
|
isSuccess = await fn();
|
|
} catch (error) {
|
|
if (!overriddenOptions.shouldRetryOnError || error.__terminateRetry) {
|
|
throw error;
|
|
}
|
|
(0, import_Error.printError)(error);
|
|
isSuccess = false;
|
|
}
|
|
if (isSuccess) {
|
|
if (attempt > 1) {
|
|
console.debug(`Retry completed successfully after ${attempt.toString()} attempts`);
|
|
}
|
|
return;
|
|
}
|
|
console.debug(`Retry attempt ${attempt.toString()} completed unsuccessfully. Trying again in ${overriddenOptions.retryDelayInMilliseconds.toString()} milliseconds`, {
|
|
fn,
|
|
stackTrace
|
|
});
|
|
await sleep(overriddenOptions.retryDelayInMilliseconds);
|
|
}
|
|
});
|
|
}
|
|
async function runWithTimeout(timeoutInMilliseconds, fn) {
|
|
let timedOut = false;
|
|
let result = null;
|
|
await Promise.race([run(), timeout2()]);
|
|
if (timedOut) {
|
|
console.error(`Timed out in ${timeoutInMilliseconds.toString()} milliseconds`, { fn });
|
|
throw new Error("Timed out");
|
|
}
|
|
return result;
|
|
async function run() {
|
|
result = await fn();
|
|
timedOut = false;
|
|
}
|
|
async function timeout2() {
|
|
await sleep(timeoutInMilliseconds);
|
|
timedOut = true;
|
|
}
|
|
}
|
|
async function sleep(milliseconds) {
|
|
await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
}
|
|
async function timeout(timeoutInMilliseconds) {
|
|
await sleep(timeoutInMilliseconds);
|
|
throw new Error(`Timed out in ${timeoutInMilliseconds.toString()} milliseconds`);
|
|
}
|
|
async function toArray(iter) {
|
|
const arr = [];
|
|
for await (const item of iter) {
|
|
arr.push(item);
|
|
}
|
|
return arr;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/App.cjs
|
|
var require_App = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/App.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var App_exports = {};
|
|
__export2(App_exports, {
|
|
ValueWrapper: () => ValueWrapper,
|
|
getApp: () => getApp,
|
|
getObsidianDevUtilsState: () => getObsidianDevUtilsState
|
|
});
|
|
module2.exports = __toCommonJS2(App_exports);
|
|
var ValueWrapper = class {
|
|
constructor(value) {
|
|
this.value = value;
|
|
}
|
|
};
|
|
function getApp() {
|
|
let canRequire;
|
|
try {
|
|
globalThis.require.resolve("obsidian/app");
|
|
canRequire = true;
|
|
} catch {
|
|
canRequire = false;
|
|
}
|
|
if (canRequire) {
|
|
return globalThis.require("obsidian/app");
|
|
}
|
|
const app = globalThis.app;
|
|
if (app) {
|
|
return app;
|
|
}
|
|
throw new Error("Obsidian app not found");
|
|
}
|
|
function getObsidianDevUtilsState(app, key, defaultValue) {
|
|
const sharedStateWrapper = app;
|
|
const sharedState = sharedStateWrapper.obsidianDevUtilsState ??= {};
|
|
return sharedState[key] ??= new ValueWrapper(defaultValue);
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Logger.cjs
|
|
var require_Logger = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Logger.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Logger_exports = {};
|
|
__export2(Logger_exports, {
|
|
invokeAsyncAndLog: () => invokeAsyncAndLog
|
|
});
|
|
module2.exports = __toCommonJS2(Logger_exports);
|
|
var import_Error = require_Error();
|
|
async function invokeAsyncAndLog(title, fn, stackTrace) {
|
|
const timestampStart = Date.now();
|
|
if (stackTrace === void 0) {
|
|
stackTrace = (0, import_Error.getStackTrace)().split("\n").slice(1).join("\n");
|
|
}
|
|
console.debug(`${title}:start`, {
|
|
fn,
|
|
stackTrace,
|
|
timestampStart
|
|
});
|
|
try {
|
|
await fn();
|
|
const timestampEnd = Date.now();
|
|
console.debug(`${title}:end`, {
|
|
duration: timestampEnd - timestampStart,
|
|
timestampEnd,
|
|
timestampStart
|
|
});
|
|
} catch (error) {
|
|
const timestampEnd = Date.now();
|
|
console.debug(`${title}:error`, {
|
|
duration: timestampEnd - timestampStart,
|
|
error,
|
|
timestampEnd: Date.now(),
|
|
timestampStart
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Queue.cjs
|
|
var require_Queue = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Queue.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Queue_exports = {};
|
|
__export2(Queue_exports, {
|
|
addToQueue: () => addToQueue2,
|
|
addToQueueAndWait: () => addToQueueAndWait,
|
|
flushQueue: () => flushQueue
|
|
});
|
|
module2.exports = __toCommonJS2(Queue_exports);
|
|
var import_Async = require_Async();
|
|
var import_Error = require_Error();
|
|
var import_Function2 = require_Function();
|
|
var import_App = require_App();
|
|
var import_Logger = require_Logger();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
function addToQueue2(app, fn, timeoutInMilliseconds) {
|
|
void addToQueueAndWait(app, fn, timeoutInMilliseconds);
|
|
}
|
|
async function addToQueueAndWait(app, fn, timeoutInMilliseconds) {
|
|
const DEFAULT_TIMEOUT_IN_MILLISECONDS = 6e4;
|
|
timeoutInMilliseconds ??= DEFAULT_TIMEOUT_IN_MILLISECONDS;
|
|
const stackTrace = (0, import_Error.getStackTrace)();
|
|
const queue = getQueue(app).value;
|
|
queue.items.push({ fn, stackTrace, timeoutInMilliseconds });
|
|
queue.promise = queue.promise.then(() => processNextQueueItem(app));
|
|
await queue.promise;
|
|
}
|
|
async function flushQueue(app) {
|
|
await addToQueueAndWait(app, import_Function2.noop);
|
|
}
|
|
function getQueue(app) {
|
|
return (0, import_App.getObsidianDevUtilsState)(app, "queue", { items: [], promise: Promise.resolve() });
|
|
}
|
|
async function processNextQueueItem(app) {
|
|
const queue = getQueue(app).value;
|
|
const item = queue.items[0];
|
|
if (!item) {
|
|
return;
|
|
}
|
|
await (0, import_Async.addErrorHandler)(() => (0, import_Async.runWithTimeout)(item.timeoutInMilliseconds, () => (0, import_Logger.invokeAsyncAndLog)(processNextQueueItem.name, item.fn, item.stackTrace)));
|
|
queue.items.shift();
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/monkey-around/dist/index.cjs
|
|
var require_dist = __commonJS({
|
|
"node_modules/monkey-around/dist/index.cjs"(exports2) {
|
|
"use strict";
|
|
function around(obj, factories) {
|
|
const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key]));
|
|
return removers.length === 1 ? removers[0] : function() {
|
|
removers.forEach((r) => r());
|
|
};
|
|
}
|
|
function around1(obj, method, createWrapper) {
|
|
const inherited = obj[method], hadOwn = obj.hasOwnProperty(method), original = hadOwn ? inherited : function() {
|
|
return Object.getPrototypeOf(obj)[method].apply(this, arguments);
|
|
};
|
|
let current = createWrapper(original);
|
|
if (inherited)
|
|
Object.setPrototypeOf(current, inherited);
|
|
Object.setPrototypeOf(wrapper, current);
|
|
obj[method] = wrapper;
|
|
return remove;
|
|
function wrapper(...args) {
|
|
if (current === original && obj[method] === wrapper)
|
|
remove();
|
|
return current.apply(this, args);
|
|
}
|
|
function remove() {
|
|
if (obj[method] === wrapper) {
|
|
if (hadOwn)
|
|
obj[method] = original;
|
|
else
|
|
delete obj[method];
|
|
}
|
|
if (current === original)
|
|
return;
|
|
current = original;
|
|
Object.setPrototypeOf(wrapper, inherited || Function);
|
|
}
|
|
}
|
|
function dedupe(key, oldFn, newFn) {
|
|
check[key] = key;
|
|
return check;
|
|
function check(...args) {
|
|
return (oldFn[key] === key ? oldFn : newFn).apply(this, args);
|
|
}
|
|
}
|
|
function after(promise, cb) {
|
|
return promise.then(cb, cb);
|
|
}
|
|
function serialize(asyncFunction) {
|
|
let lastRun = Promise.resolve();
|
|
function wrapper(...args) {
|
|
return lastRun = new Promise((res, rej) => {
|
|
after(lastRun, () => {
|
|
asyncFunction.apply(this, args).then(res, rej);
|
|
});
|
|
});
|
|
}
|
|
wrapper.after = function() {
|
|
return lastRun = new Promise((res, rej) => {
|
|
after(lastRun, res);
|
|
});
|
|
};
|
|
return wrapper;
|
|
}
|
|
exports2.after = after;
|
|
exports2.around = around;
|
|
exports2.dedupe = dedupe;
|
|
exports2.serialize = serialize;
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/Object.cjs
|
|
var require_Object = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/Object.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Object_exports = {};
|
|
__export2(Object_exports, {
|
|
assignWithNonEnumerableProperties: () => assignWithNonEnumerableProperties,
|
|
cloneWithNonEnumerableProperties: () => cloneWithNonEnumerableProperties,
|
|
deepEqual: () => deepEqual,
|
|
getNestedPropertyValue: () => getNestedPropertyValue,
|
|
getPrototypeOf: () => getPrototypeOf,
|
|
nameof: () => nameof,
|
|
setNestedPropertyValue: () => setNestedPropertyValue,
|
|
toJson: () => toJson
|
|
});
|
|
module2.exports = __toCommonJS2(Object_exports);
|
|
var import_Error = require_Error();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
function assignWithNonEnumerableProperties(target, ...sources) {
|
|
return _assignWithNonEnumerableProperties(target, ...sources);
|
|
}
|
|
function cloneWithNonEnumerableProperties(obj) {
|
|
return Object.create(getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
|
|
}
|
|
function deepEqual(a, b) {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
|
|
return false;
|
|
}
|
|
const keysA = Object.keys(a);
|
|
const keysB = Object.keys(b);
|
|
if (keysA.length !== keysB.length) {
|
|
return false;
|
|
}
|
|
const aRecord = a;
|
|
const bRecord = b;
|
|
for (const key of keysA) {
|
|
if (!keysB.includes(key) || !deepEqual(aRecord[key], bRecord[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function getNestedPropertyValue(obj, path) {
|
|
let node = obj;
|
|
const keys = path.split(".");
|
|
for (const key of keys) {
|
|
if (node === void 0) {
|
|
return void 0;
|
|
}
|
|
node = node[key];
|
|
}
|
|
return node;
|
|
}
|
|
function getPrototypeOf(instance) {
|
|
if (instance === void 0 || instance === null) {
|
|
return instance;
|
|
}
|
|
return Object.getPrototypeOf(instance);
|
|
}
|
|
function nameof(name) {
|
|
return name;
|
|
}
|
|
function setNestedPropertyValue(obj, path, value) {
|
|
const error = new Error(`Property path ${path} not found`);
|
|
let node = obj;
|
|
const keys = path.split(".");
|
|
for (const key of keys.slice(0, -1)) {
|
|
if (node === void 0) {
|
|
throw error;
|
|
}
|
|
node = node[key];
|
|
}
|
|
const lastKey = keys.at(-1);
|
|
if (node === void 0 || lastKey === void 0) {
|
|
throw error;
|
|
}
|
|
node[lastKey] = value;
|
|
}
|
|
function toJson(value, options = {}) {
|
|
const {
|
|
shouldHandleFunctions = false,
|
|
space = 2
|
|
} = options;
|
|
if (!shouldHandleFunctions) {
|
|
return JSON.stringify(value, null, space);
|
|
}
|
|
const functionTexts = [];
|
|
const replacer = (_, value2) => {
|
|
if (typeof value2 === "function") {
|
|
const index = functionTexts.length;
|
|
functionTexts.push(value2.toString());
|
|
return `__FUNCTION_${index.toString()}`;
|
|
}
|
|
return value2;
|
|
};
|
|
let json = JSON.stringify(value, replacer, space);
|
|
json = json.replaceAll(/"__FUNCTION_(\d+)"/g, (_, indexStr) => functionTexts[parseInt(indexStr)] ?? (0, import_Error.throwExpression)(new Error(`Function with index ${indexStr} not found`)));
|
|
return json;
|
|
}
|
|
function _assignWithNonEnumerableProperties(target, ...sources) {
|
|
for (const source of sources) {
|
|
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
}
|
|
const sourcePrototypes = sources.map((source) => getPrototypeOf(source)).filter((proto) => !!proto);
|
|
if (sourcePrototypes.length > 0) {
|
|
const targetPrototype = _assignWithNonEnumerableProperties({}, getPrototypeOf(target), ...sourcePrototypes);
|
|
Object.setPrototypeOf(target, targetPrototype);
|
|
}
|
|
return target;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/AttachmentPath.cjs
|
|
var require_AttachmentPath = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/AttachmentPath.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var AttachmentPath_exports = {};
|
|
__export2(AttachmentPath_exports, {
|
|
getAttachmentFilePath: () => getAttachmentFilePath2,
|
|
getAttachmentFolderPath: () => getAttachmentFolderPath,
|
|
getAvailablePathForAttachments: () => getAvailablePathForAttachments,
|
|
hasOwnAttachmentFolder: () => hasOwnAttachmentFolder
|
|
});
|
|
module2.exports = __toCommonJS2(AttachmentPath_exports);
|
|
var import_implementations = require_implementations();
|
|
var import_Path4 = require_Path();
|
|
var import_String = require_String();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
async function getAttachmentFilePath2(app, attachmentPathOrFile, notePathOrFile) {
|
|
const attachmentPath = (0, import_FileSystem4.getPath)(attachmentPathOrFile);
|
|
const notePath = (0, import_FileSystem4.getPath)(notePathOrFile);
|
|
const note = (0, import_FileSystem4.getFile)(app, notePath, true);
|
|
const ext = (0, import_Path4.extname)(attachmentPath);
|
|
const fileName = (0, import_Path4.basename)(attachmentPath, ext);
|
|
const internalFn = app.vault.getAvailablePathForAttachments;
|
|
if (internalFn.isExtended) {
|
|
return internalFn(fileName, ext.slice(1), note, true);
|
|
}
|
|
return await getAvailablePathForAttachments(app, fileName, ext.slice(1), note, true);
|
|
}
|
|
async function getAttachmentFolderPath(app, notePathOrFile) {
|
|
return (0, import_implementations.parentFolderPath)(await getAttachmentFilePath2(app, "DUMMY_FILE.pdf", notePathOrFile));
|
|
}
|
|
async function getAvailablePathForAttachments(app, filename, extension, file, skipFolderCreation) {
|
|
let attachmentFolderPath = app.vault.getConfig("attachmentFolderPath");
|
|
const isCurrentFolder = attachmentFolderPath === "." || attachmentFolderPath === "./";
|
|
let relativePath = null;
|
|
if (attachmentFolderPath.startsWith("./")) {
|
|
relativePath = (0, import_String.trimStart)(attachmentFolderPath, "./");
|
|
}
|
|
if (isCurrentFolder) {
|
|
attachmentFolderPath = file ? file.parent?.path ?? "" : "";
|
|
} else if (relativePath) {
|
|
attachmentFolderPath = (file ? file.parent?.getParentPrefix() ?? "" : "") + relativePath;
|
|
}
|
|
attachmentFolderPath = (0, import_String.normalize)(normalizeSlashes(attachmentFolderPath));
|
|
filename = (0, import_String.normalize)(normalizeSlashes(filename));
|
|
let folder = (0, import_FileSystem4.getFolderOrNull)(app, attachmentFolderPath, true);
|
|
if (!folder && relativePath) {
|
|
if (!skipFolderCreation) {
|
|
folder = await app.vault.createFolder(attachmentFolderPath);
|
|
} else {
|
|
folder = (0, import_FileSystem4.getFolder)(app, attachmentFolderPath, true);
|
|
}
|
|
}
|
|
const prefix = folder?.getParentPrefix() ?? "";
|
|
return app.vault.getAvailablePath(prefix + filename, extension);
|
|
}
|
|
async function hasOwnAttachmentFolder(app, path) {
|
|
const attachmentFolderPath = await getAttachmentFolderPath(app, path);
|
|
const dummyAttachmentFolderPath = await getAttachmentFolderPath(app, (0, import_Path4.join)((0, import_Path4.dirname)(path), "DUMMY_FILE.md"));
|
|
return attachmentFolderPath !== dummyAttachmentFolderPath;
|
|
}
|
|
function normalizeSlashes(path) {
|
|
path = path.replace(/([\\/])+/g, "/");
|
|
path = path.replace(/(^\/+|\/+$)/g, "");
|
|
return path || "/";
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/FrontMatter.cjs
|
|
var require_FrontMatter = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/FrontMatter.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var FrontMatter_exports = {};
|
|
__export2(FrontMatter_exports, {
|
|
parseFrontMatter: () => parseFrontMatter,
|
|
setFrontMatter: () => setFrontMatter
|
|
});
|
|
module2.exports = __toCommonJS2(FrontMatter_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_String = require_String();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
function parseFrontMatter(content) {
|
|
const frontMatterInfo = (0, import_obsidian5.getFrontMatterInfo)(content);
|
|
return (0, import_obsidian5.parseYaml)(frontMatterInfo.frontmatter) ?? {};
|
|
}
|
|
function setFrontMatter(content, newFrontMatter) {
|
|
const frontMatterInfo = (0, import_obsidian5.getFrontMatterInfo)(content);
|
|
if (Object.keys(newFrontMatter).length === 0) {
|
|
return content.slice(frontMatterInfo.contentStart);
|
|
}
|
|
const newFrontMatterStr = (0, import_obsidian5.stringifyYaml)(newFrontMatter);
|
|
return frontMatterInfo.exists ? (0, import_String.insertAt)(content, newFrontMatterStr, frontMatterInfo.from, frontMatterInfo.to) : "---\n" + newFrontMatterStr + "---\n" + content;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Reference.cjs
|
|
var require_Reference = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Reference.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Reference_exports = {};
|
|
__export2(Reference_exports, {
|
|
referenceToFileChange: () => referenceToFileChange2,
|
|
sortReferences: () => sortReferences
|
|
});
|
|
module2.exports = __toCommonJS2(Reference_exports);
|
|
var import_implementations = require_implementations();
|
|
function referenceToFileChange2(reference, newContent) {
|
|
if ((0, import_implementations.isReferenceCache)(reference)) {
|
|
return {
|
|
endIndex: reference.position.end.offset,
|
|
newContent,
|
|
oldContent: reference.original,
|
|
startIndex: reference.position.start.offset
|
|
};
|
|
} else if ((0, import_implementations.isFrontmatterLinkCache)(reference)) {
|
|
return {
|
|
frontMatterKey: reference.key,
|
|
newContent,
|
|
oldContent: reference.original
|
|
};
|
|
}
|
|
throw new Error("Unknown link type");
|
|
}
|
|
function sortReferences(references) {
|
|
return references.sort((a, b) => {
|
|
if ((0, import_implementations.isFrontmatterLinkCache)(a) && (0, import_implementations.isFrontmatterLinkCache)(b)) {
|
|
return a.key.localeCompare(b.key);
|
|
}
|
|
if ((0, import_implementations.isReferenceCache)(a) && (0, import_implementations.isReferenceCache)(b)) {
|
|
return a.position.start.offset - b.position.start.offset;
|
|
}
|
|
return (0, import_implementations.isFrontmatterLinkCache)(a) ? 1 : -1;
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/MetadataCache.cjs
|
|
var require_MetadataCache = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/MetadataCache.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var MetadataCache_exports = {};
|
|
__export2(MetadataCache_exports, {
|
|
ensureMetadataCacheReady: () => ensureMetadataCacheReady,
|
|
getAllLinks: () => getAllLinks3,
|
|
getBacklinksForFileOrPath: () => getBacklinksForFileOrPath,
|
|
getBacklinksForFileSafe: () => getBacklinksForFileSafe2,
|
|
getBacklinksMap: () => getBacklinksMap,
|
|
getCacheSafe: () => getCacheSafe3,
|
|
getFrontMatterSafe: () => getFrontMatterSafe,
|
|
registerFile: () => registerFile,
|
|
tempRegisterFileAndRun: () => tempRegisterFileAndRun
|
|
});
|
|
module2.exports = __toCommonJS2(MetadataCache_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_implementations = require_implementations();
|
|
var import_Async = require_Async();
|
|
var import_Function2 = require_Function();
|
|
var import_Object = require_Object();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
var import_FrontMatter = require_FrontMatter();
|
|
var import_Reference2 = require_Reference();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
async function ensureMetadataCacheReady(app) {
|
|
for (const [path, cache] of Object.entries(app.metadataCache.fileCache)) {
|
|
if (!cache.hash) {
|
|
continue;
|
|
}
|
|
if (app.metadataCache.metadataCache[cache.hash]) {
|
|
continue;
|
|
}
|
|
await getCacheSafe3(app, path);
|
|
}
|
|
}
|
|
function getAllLinks3(cache) {
|
|
let links = [];
|
|
if (cache.links) {
|
|
links.push(...cache.links);
|
|
}
|
|
if (cache.embeds) {
|
|
links.push(...cache.embeds);
|
|
}
|
|
if (cache.frontmatterLinks) {
|
|
links.push(...cache.frontmatterLinks);
|
|
}
|
|
(0, import_Reference2.sortReferences)(links);
|
|
links = links.filter((link, index) => {
|
|
if (index === 0) {
|
|
return true;
|
|
}
|
|
const previousLink = links[index - 1];
|
|
if (!previousLink) {
|
|
return true;
|
|
}
|
|
if ((0, import_implementations.isReferenceCache)(link) && (0, import_implementations.isReferenceCache)(previousLink)) {
|
|
return link.position.start.offset !== previousLink.position.start.offset;
|
|
}
|
|
if ((0, import_implementations.isFrontmatterLinkCache)(link) && (0, import_implementations.isFrontmatterLinkCache)(previousLink)) {
|
|
return link.key !== previousLink.key;
|
|
}
|
|
return true;
|
|
});
|
|
return links;
|
|
}
|
|
function getBacklinksForFileOrPath(app, pathOrFile) {
|
|
const file = (0, import_FileSystem4.getFile)(app, pathOrFile, true);
|
|
return tempRegisterFileAndRun(app, file, () => app.metadataCache.getBacklinksForFile(file));
|
|
}
|
|
async function getBacklinksForFileSafe2(app, pathOrFile, retryOptions = {}) {
|
|
const safeOverload = app.metadataCache.getBacklinksForFile.safe;
|
|
if (safeOverload) {
|
|
return safeOverload(pathOrFile);
|
|
}
|
|
const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 };
|
|
const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions };
|
|
let backlinks = null;
|
|
await (0, import_Async.retryWithTimeout)(async () => {
|
|
const file = (0, import_FileSystem4.getFile)(app, pathOrFile);
|
|
await ensureMetadataCacheReady(app);
|
|
backlinks = getBacklinksForFileOrPath(app, file);
|
|
for (const notePath of backlinks.keys()) {
|
|
const note = (0, import_FileSystem4.getFileOrNull)(app, notePath);
|
|
if (!note) {
|
|
return false;
|
|
}
|
|
await saveNote(app, note);
|
|
const content = await app.vault.read(note);
|
|
const frontMatter = (0, import_FrontMatter.parseFrontMatter)(content);
|
|
const links = backlinks.get(notePath);
|
|
if (!links) {
|
|
return false;
|
|
}
|
|
for (const link of links) {
|
|
let actualLink;
|
|
if ((0, import_implementations.isReferenceCache)(link)) {
|
|
actualLink = content.slice(link.position.start.offset, link.position.end.offset);
|
|
} else if ((0, import_implementations.isFrontmatterLinkCache)(link)) {
|
|
const linkValue = (0, import_Object.getNestedPropertyValue)(frontMatter, link.key);
|
|
if (typeof linkValue !== "string") {
|
|
return false;
|
|
}
|
|
actualLink = linkValue;
|
|
} else {
|
|
return true;
|
|
}
|
|
if (actualLink !== link.original) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}, overriddenOptions);
|
|
return backlinks;
|
|
}
|
|
async function getBacklinksMap(app, pathOrFiles, retryOptions = {}) {
|
|
const map = /* @__PURE__ */ new Map();
|
|
for (const pathOrFile of pathOrFiles) {
|
|
const customArrayDict = await getBacklinksForFileSafe2(app, pathOrFile, retryOptions);
|
|
for (const path of customArrayDict.keys()) {
|
|
const mapLinks = map.get(path) ?? [];
|
|
const pathLinks = customArrayDict.get(path) ?? [];
|
|
mapLinks.push(...pathLinks);
|
|
map.set(path, mapLinks);
|
|
}
|
|
}
|
|
return map;
|
|
}
|
|
async function getCacheSafe3(app, fileOrPath, retryOptions = {}) {
|
|
const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 };
|
|
const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions };
|
|
let cache = null;
|
|
await (0, import_Async.retryWithTimeout)(async () => {
|
|
const file = (0, import_FileSystem4.getFileOrNull)(app, fileOrPath);
|
|
if (!file || file.deleted) {
|
|
cache = null;
|
|
return true;
|
|
}
|
|
await saveNote(app, file);
|
|
const fileInfo = app.metadataCache.getFileInfo(file.path);
|
|
const stat = await app.vault.adapter.stat(file.path);
|
|
if (!fileInfo) {
|
|
console.debug(`File cache info for ${file.path} is missing`);
|
|
return false;
|
|
} else if (!stat) {
|
|
console.debug(`File stat for ${file.path} is missing`);
|
|
return false;
|
|
} else if (file.stat.mtime < stat.mtime) {
|
|
app.vault.onChange("modified", file.path, void 0, stat);
|
|
console.debug(`Cached timestamp for ${file.path} is from ${new Date(file.stat.mtime).toString()} which is older than the file system modification timestamp ${new Date(stat.mtime).toString()}`);
|
|
return false;
|
|
} else if (fileInfo.mtime < stat.mtime) {
|
|
console.debug(`File cache info for ${file.path} is from ${new Date(fileInfo.mtime).toString()} which is older than the file modification timestamp ${new Date(stat.mtime).toString()}`);
|
|
return false;
|
|
} else {
|
|
cache = app.metadataCache.getFileCache(file);
|
|
if (!cache) {
|
|
console.debug(`File cache for ${file.path} is missing`);
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}, overriddenOptions);
|
|
return cache;
|
|
}
|
|
async function getFrontMatterSafe(app, pathOrFile) {
|
|
const cache = await getCacheSafe3(app, pathOrFile);
|
|
return cache?.frontmatter ?? {};
|
|
}
|
|
function registerFile(app, file) {
|
|
if (!file.deleted) {
|
|
return import_Function2.noop;
|
|
}
|
|
const deletedPaths = [];
|
|
let deletedFile = file;
|
|
while (deletedFile.deleted) {
|
|
deletedPaths.push(deletedFile.path);
|
|
app.vault.fileMap[deletedFile.path] = deletedFile;
|
|
deletedFile = deletedFile.parent ?? (0, import_FileSystem4.getFolder)(app, (0, import_implementations.parentFolderPath)(deletedFile.path), true);
|
|
}
|
|
if ((0, import_FileSystem4.isFile)(file)) {
|
|
app.metadataCache.uniqueFileLookup.add(file.name.toLowerCase(), file);
|
|
}
|
|
return () => {
|
|
for (const path of deletedPaths) {
|
|
delete app.vault.fileMap[path];
|
|
}
|
|
if ((0, import_FileSystem4.isFile)(file)) {
|
|
app.metadataCache.uniqueFileLookup.remove(file.name.toLowerCase(), file);
|
|
}
|
|
};
|
|
}
|
|
function tempRegisterFileAndRun(app, file, fn) {
|
|
const unregister = registerFile(app, file);
|
|
try {
|
|
return fn();
|
|
} finally {
|
|
unregister();
|
|
}
|
|
}
|
|
async function saveNote(app, pathOrFile) {
|
|
if (!(0, import_FileSystem4.isMarkdownFile)(pathOrFile)) {
|
|
return;
|
|
}
|
|
const path = (0, import_FileSystem4.getPath)(pathOrFile);
|
|
for (const leaf of app.workspace.getLeavesOfType("markdown")) {
|
|
if (leaf.view instanceof import_obsidian5.MarkdownView && leaf.view.file?.path === path) {
|
|
await leaf.view.save();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Vault.cjs
|
|
var require_Vault = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Vault.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Vault_exports = {};
|
|
__export2(Vault_exports, {
|
|
copySafe: () => copySafe2,
|
|
createFolderSafe: () => createFolderSafe3,
|
|
createTempFile: () => createTempFile,
|
|
createTempFolder: () => createTempFolder,
|
|
deleteEmptyFolderHierarchy: () => deleteEmptyFolderHierarchy2,
|
|
deleteSafe: () => deleteSafe,
|
|
getAvailablePath: () => getAvailablePath2,
|
|
getMarkdownFilesSorted: () => getMarkdownFilesSorted2,
|
|
getNoteFilesSorted: () => getNoteFilesSorted,
|
|
getSafeRenamePath: () => getSafeRenamePath,
|
|
isEmptyFolder: () => isEmptyFolder,
|
|
listSafe: () => listSafe2,
|
|
process: () => process2,
|
|
renameSafe: () => renameSafe2
|
|
});
|
|
module2.exports = __toCommonJS2(Vault_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_implementations = require_implementations();
|
|
var import_Async = require_Async();
|
|
var import_Error = require_Error();
|
|
var import_Function2 = require_Function();
|
|
var import_Path4 = require_Path();
|
|
var import_ValueProvider = require_ValueProvider();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
var import_MetadataCache3 = require_MetadataCache();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
async function copySafe2(app, oldPathOrFile, newPath) {
|
|
const file = (0, import_FileSystem4.getFile)(app, oldPathOrFile);
|
|
const newFolderPath = (0, import_implementations.parentFolderPath)(newPath);
|
|
await createFolderSafe3(app, newFolderPath);
|
|
const newAvailablePath = getAvailablePath2(app, newPath);
|
|
try {
|
|
await app.vault.copy(file, newAvailablePath);
|
|
} catch (e) {
|
|
if (!await app.vault.exists(newAvailablePath)) {
|
|
throw e;
|
|
}
|
|
}
|
|
return newAvailablePath;
|
|
}
|
|
async function createFolderSafe3(app, path) {
|
|
if (await app.vault.adapter.exists(path)) {
|
|
return false;
|
|
}
|
|
try {
|
|
await app.vault.createFolder(path);
|
|
return true;
|
|
} catch (e) {
|
|
if (!await app.vault.exists(path)) {
|
|
throw e;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
async function createTempFile(app, path) {
|
|
let file = (0, import_FileSystem4.getFileOrNull)(app, path);
|
|
if (file) {
|
|
return import_Function2.noopAsync;
|
|
}
|
|
const folderCleanup = await createTempFolder(app, (0, import_implementations.parentFolderPath)(path));
|
|
try {
|
|
await app.vault.create(path, "");
|
|
} catch (e) {
|
|
if (!await app.vault.exists(path)) {
|
|
throw e;
|
|
}
|
|
}
|
|
file = (0, import_FileSystem4.getFile)(app, path);
|
|
return async () => {
|
|
if (!file.deleted) {
|
|
await app.fileManager.trashFile(file);
|
|
}
|
|
await folderCleanup();
|
|
};
|
|
}
|
|
async function createTempFolder(app, path) {
|
|
let folder = (0, import_FileSystem4.getFolderOrNull)(app, path);
|
|
if (folder) {
|
|
return import_Function2.noopAsync;
|
|
}
|
|
const dirPath = (0, import_implementations.parentFolderPath)(path);
|
|
await createTempFolder(app, dirPath);
|
|
const folderCleanup = await createTempFolder(app, (0, import_implementations.parentFolderPath)(path));
|
|
await createFolderSafe3(app, path);
|
|
folder = (0, import_FileSystem4.getFolder)(app, path);
|
|
return async () => {
|
|
if (!folder.deleted) {
|
|
await app.fileManager.trashFile(folder);
|
|
}
|
|
await folderCleanup();
|
|
};
|
|
}
|
|
async function deleteEmptyFolderHierarchy2(app, pathOrFolder) {
|
|
let folder = (0, import_FileSystem4.getFolderOrNull)(app, pathOrFolder);
|
|
while (folder) {
|
|
if (!await isEmptyFolder(app, folder)) {
|
|
return;
|
|
}
|
|
const parent = folder.parent;
|
|
await deleteSafe(app, folder.path);
|
|
folder = parent;
|
|
}
|
|
}
|
|
async function deleteSafe(app, pathOrFile, deletedNotePath, shouldReportUsedAttachments, shouldDeleteEmptyFolders) {
|
|
const file = (0, import_FileSystem4.getAbstractFileOrNull)(app, pathOrFile);
|
|
if (!file) {
|
|
return false;
|
|
}
|
|
let canDelete = (0, import_FileSystem4.isFile)(file) || (shouldDeleteEmptyFolders ?? true);
|
|
if ((0, import_FileSystem4.isFile)(file)) {
|
|
const backlinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, file);
|
|
if (deletedNotePath) {
|
|
backlinks.clear(deletedNotePath);
|
|
}
|
|
if (backlinks.count() !== 0) {
|
|
if (shouldReportUsedAttachments) {
|
|
new import_obsidian5.Notice(`Attachment ${file.path} is still used by other notes. It will not be deleted.`);
|
|
}
|
|
canDelete = false;
|
|
}
|
|
} else if ((0, import_FileSystem4.isFolder)(file)) {
|
|
const listedFiles = await listSafe2(app, file);
|
|
for (const child of [...listedFiles.files, ...listedFiles.folders]) {
|
|
canDelete &&= await deleteSafe(app, child, deletedNotePath, shouldReportUsedAttachments);
|
|
}
|
|
canDelete &&= await isEmptyFolder(app, file);
|
|
}
|
|
if (canDelete) {
|
|
try {
|
|
await app.fileManager.trashFile(file);
|
|
} catch (e) {
|
|
if (await app.vault.exists(file.path)) {
|
|
(0, import_Error.printError)(new Error(`Failed to delete ${file.path}`, { cause: e }));
|
|
canDelete = false;
|
|
}
|
|
}
|
|
}
|
|
return canDelete;
|
|
}
|
|
function getAvailablePath2(app, path) {
|
|
const ext = (0, import_Path4.extname)(path);
|
|
return app.vault.getAvailablePath((0, import_Path4.join)((0, import_Path4.dirname)(path), (0, import_Path4.basename)(path, ext)), ext.slice(1));
|
|
}
|
|
function getMarkdownFilesSorted2(app) {
|
|
return app.vault.getMarkdownFiles().sort((a, b) => a.path.localeCompare(b.path));
|
|
}
|
|
function getNoteFilesSorted(app) {
|
|
return app.vault.getAllLoadedFiles().filter((file) => (0, import_FileSystem4.isFile)(file) && (0, import_FileSystem4.isNote)(file)).sort((a, b) => a.path.localeCompare(b.path));
|
|
}
|
|
function getSafeRenamePath(app, oldPathOrFile, newPath) {
|
|
const oldPath = (0, import_FileSystem4.getPath)(oldPathOrFile);
|
|
if (app.vault.adapter.insensitive) {
|
|
let folderPath = (0, import_Path4.dirname)(newPath);
|
|
let nonExistingPath = (0, import_Path4.basename)(newPath);
|
|
let folder = null;
|
|
for (; ; ) {
|
|
folder = (0, import_FileSystem4.getFolderOrNull)(app, folderPath, true);
|
|
if (folder) {
|
|
break;
|
|
}
|
|
nonExistingPath = (0, import_Path4.join)((0, import_Path4.basename)(folderPath), nonExistingPath);
|
|
folderPath = (0, import_Path4.dirname)(folderPath);
|
|
}
|
|
newPath = (0, import_Path4.join)(folder.getParentPrefix(), nonExistingPath);
|
|
}
|
|
if (oldPath.toLowerCase() === newPath.toLowerCase()) {
|
|
return newPath;
|
|
}
|
|
return getAvailablePath2(app, newPath);
|
|
}
|
|
async function isEmptyFolder(app, pathOrFolder) {
|
|
const listedFiles = await listSafe2(app, (0, import_FileSystem4.getPath)(pathOrFolder));
|
|
return listedFiles.files.length === 0 && listedFiles.folders.length === 0;
|
|
}
|
|
async function listSafe2(app, pathOrFolder) {
|
|
const path = (0, import_FileSystem4.getPath)(pathOrFolder);
|
|
const EMPTY = { files: [], folders: [] };
|
|
if ((await app.vault.adapter.stat(path))?.type !== "folder") {
|
|
return EMPTY;
|
|
}
|
|
try {
|
|
return await app.vault.adapter.list(path);
|
|
} catch (e) {
|
|
if (await app.vault.exists(path)) {
|
|
throw e;
|
|
}
|
|
return EMPTY;
|
|
}
|
|
}
|
|
async function process2(app, pathOrFile, newContentProvider, retryOptions = {}) {
|
|
const file = (0, import_FileSystem4.getFile)(app, pathOrFile);
|
|
const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 };
|
|
const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions };
|
|
await (0, import_Async.retryWithTimeout)(async () => {
|
|
if (file.deleted) {
|
|
throw (0, import_Async.marksAsTerminateRetry)(new Error(`File ${file.path} is deleted`));
|
|
}
|
|
const oldContent = await app.vault.read(file);
|
|
const newContent = await (0, import_ValueProvider.resolveValue)(newContentProvider, oldContent);
|
|
if (newContent === null) {
|
|
return false;
|
|
}
|
|
let success = true;
|
|
await app.vault.process(file, (content) => {
|
|
if (content !== oldContent) {
|
|
console.warn("Content has changed since it was read. Retrying...", {
|
|
actualContent: content,
|
|
expectedContent: oldContent,
|
|
path: file.path
|
|
});
|
|
success = false;
|
|
return content;
|
|
}
|
|
return newContent;
|
|
});
|
|
return success;
|
|
}, overriddenOptions);
|
|
}
|
|
async function renameSafe2(app, oldPathOrFile, newPath) {
|
|
const oldFile = (0, import_FileSystem4.getFile)(app, oldPathOrFile, false, true);
|
|
const newAvailablePath = getSafeRenamePath(app, oldPathOrFile, newPath);
|
|
if (oldFile.path.toLowerCase() === newAvailablePath.toLowerCase()) {
|
|
if (oldFile.path !== newPath) {
|
|
await app.vault.rename(oldFile, newAvailablePath);
|
|
}
|
|
return newAvailablePath;
|
|
}
|
|
const newFolderPath = (0, import_implementations.parentFolderPath)(newAvailablePath);
|
|
await createFolderSafe3(app, newFolderPath);
|
|
try {
|
|
await app.vault.rename(oldFile, newAvailablePath);
|
|
} catch (e) {
|
|
if (!await app.vault.exists(newAvailablePath) || await app.vault.exists(oldFile.path)) {
|
|
throw e;
|
|
}
|
|
}
|
|
return newAvailablePath;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/FileChange.cjs
|
|
var require_FileChange = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/FileChange.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var FileChange_exports = {};
|
|
__export2(FileChange_exports, {
|
|
applyFileChanges: () => applyFileChanges2,
|
|
isContentChange: () => isContentChange,
|
|
isFrontmatterChange: () => isFrontmatterChange
|
|
});
|
|
module2.exports = __toCommonJS2(FileChange_exports);
|
|
var import_Object = require_Object();
|
|
var import_ValueProvider = require_ValueProvider();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
var import_FrontMatter = require_FrontMatter();
|
|
var import_Vault3 = require_Vault();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
async function applyFileChanges2(app, pathOrFile, changesProvider, retryOptions = {}) {
|
|
const DEFAULT_RETRY_OPTIONS = { timeoutInMilliseconds: 6e4 };
|
|
const overriddenOptions = { ...DEFAULT_RETRY_OPTIONS, ...retryOptions };
|
|
await (0, import_Vault3.process)(app, pathOrFile, async (content) => {
|
|
let changes = await (0, import_ValueProvider.resolveValue)(changesProvider);
|
|
const frontMatter = (0, import_FrontMatter.parseFrontMatter)(content);
|
|
for (const change of changes) {
|
|
if (isContentChange(change)) {
|
|
const actualContent = content.slice(change.startIndex, change.endIndex);
|
|
if (actualContent !== change.oldContent) {
|
|
console.warn("Content mismatch", {
|
|
actualContent,
|
|
endIndex: change.endIndex,
|
|
expectedContent: change.oldContent,
|
|
path: (0, import_FileSystem4.getPath)(pathOrFile),
|
|
startIndex: change.startIndex
|
|
});
|
|
return null;
|
|
}
|
|
} else if (isFrontmatterChange(change)) {
|
|
const actualContent = (0, import_Object.getNestedPropertyValue)(frontMatter, change.frontMatterKey);
|
|
if (actualContent !== change.oldContent) {
|
|
console.warn("Content mismatch", {
|
|
actualContent,
|
|
expectedContent: change.oldContent,
|
|
frontMatterKey: change.frontMatterKey,
|
|
path: (0, import_FileSystem4.getPath)(pathOrFile)
|
|
});
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
changes.sort((a, b) => {
|
|
if (isContentChange(a) && isContentChange(b)) {
|
|
return a.startIndex - b.startIndex;
|
|
}
|
|
if (isFrontmatterChange(a) && isFrontmatterChange(b)) {
|
|
return a.frontMatterKey.localeCompare(b.frontMatterKey);
|
|
}
|
|
return isContentChange(a) ? -1 : 1;
|
|
});
|
|
changes = changes.filter((change, index) => {
|
|
if (change.oldContent === change.newContent) {
|
|
return false;
|
|
}
|
|
if (index === 0) {
|
|
return true;
|
|
}
|
|
return !(0, import_Object.deepEqual)(change, changes[index - 1]);
|
|
});
|
|
for (let i = 1; i < changes.length; i++) {
|
|
const change = changes[i];
|
|
if (!change) {
|
|
continue;
|
|
}
|
|
const previousChange = changes[i - 1];
|
|
if (!previousChange) {
|
|
continue;
|
|
}
|
|
if (isContentChange(previousChange) && isContentChange(change) && previousChange.endIndex && change.startIndex && previousChange.endIndex > change.startIndex) {
|
|
console.warn("Overlapping changes", {
|
|
change,
|
|
previousChange
|
|
});
|
|
return null;
|
|
}
|
|
}
|
|
let newContent = "";
|
|
let lastIndex = 0;
|
|
let frontMatterChanged = false;
|
|
for (const change of changes) {
|
|
if (isContentChange(change)) {
|
|
newContent += content.slice(lastIndex, change.startIndex);
|
|
newContent += change.newContent;
|
|
lastIndex = change.endIndex;
|
|
} else if (isFrontmatterChange(change)) {
|
|
(0, import_Object.setNestedPropertyValue)(frontMatter, change.frontMatterKey, change.newContent);
|
|
frontMatterChanged = true;
|
|
}
|
|
}
|
|
newContent += content.slice(lastIndex);
|
|
if (frontMatterChanged) {
|
|
newContent = (0, import_FrontMatter.setFrontMatter)(newContent, frontMatter);
|
|
}
|
|
return newContent;
|
|
}, overriddenOptions);
|
|
}
|
|
function isContentChange(fileChange) {
|
|
return fileChange.startIndex !== void 0;
|
|
}
|
|
function isFrontmatterChange(fileChange) {
|
|
return fileChange.frontMatterKey !== void 0;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/ObsidianSettings.cjs
|
|
var require_ObsidianSettings = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/ObsidianSettings.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var ObsidianSettings_exports = {};
|
|
__export2(ObsidianSettings_exports, {
|
|
shouldUseRelativeLinks: () => shouldUseRelativeLinks,
|
|
shouldUseWikilinks: () => shouldUseWikilinks
|
|
});
|
|
module2.exports = __toCommonJS2(ObsidianSettings_exports);
|
|
function shouldUseRelativeLinks(app) {
|
|
return app.vault.getConfig("newLinkFormat") === "relative";
|
|
}
|
|
function shouldUseWikilinks(app) {
|
|
return !app.vault.getConfig("useMarkdownLinks");
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Link.cjs
|
|
var require_Link = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Link.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var Link_exports = {};
|
|
__export2(Link_exports, {
|
|
convertLink: () => convertLink,
|
|
editBacklinks: () => editBacklinks,
|
|
editLinks: () => editLinks,
|
|
extractLinkFile: () => extractLinkFile3,
|
|
generateMarkdownLink: () => generateMarkdownLink2,
|
|
shouldResetAlias: () => shouldResetAlias,
|
|
splitSubpath: () => splitSubpath3,
|
|
testAngleBrackets: () => testAngleBrackets,
|
|
testEmbed: () => testEmbed2,
|
|
testLeadingDot: () => testLeadingDot,
|
|
testWikilink: () => testWikilink2,
|
|
updateLink: () => updateLink,
|
|
updateLinksInFile: () => updateLinksInFile2
|
|
});
|
|
module2.exports = __toCommonJS2(Link_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_Object = require_Object();
|
|
var import_Path4 = require_Path();
|
|
var import_String = require_String();
|
|
var import_FileChange2 = require_FileChange();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
var import_MetadataCache3 = require_MetadataCache();
|
|
var import_ObsidianSettings = require_ObsidianSettings();
|
|
var import_Reference2 = require_Reference();
|
|
var SPECIAL_LINK_SYMBOLS_REGEXP = /[\\\x00\x08\x0B\x0C\x0E-\x1F ]/g;
|
|
var SPECIAL_MARKDOWN_LINK_SYMBOLS_REGEX = /[\\[\]<>_*~=`$]/g;
|
|
function convertLink(options) {
|
|
return updateLink({
|
|
app: options.app,
|
|
forceMarkdownLinks: options.forceMarkdownLinks,
|
|
link: options.link,
|
|
oldPathOrFile: options.oldPathOrFile,
|
|
pathOrFile: extractLinkFile3(options.app, options.link, options.sourcePathOrFile),
|
|
renameMap: options.renameMap,
|
|
shouldUpdateFilenameAlias: options.shouldUpdateFilenameAlias,
|
|
sourcePathOrFile: options.sourcePathOrFile
|
|
});
|
|
}
|
|
async function editBacklinks(app, pathOrFile, linkConverter, retryOptions = {}) {
|
|
const backlinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, pathOrFile, retryOptions);
|
|
for (const backlinkNotePath of backlinks.keys()) {
|
|
const currentLinks = backlinks.get(backlinkNotePath) ?? [];
|
|
const linkJsons = new Set(currentLinks.map((link) => (0, import_Object.toJson)(link)));
|
|
await editLinks(app, backlinkNotePath, (link) => {
|
|
const linkJson = (0, import_Object.toJson)(link);
|
|
if (!linkJsons.has(linkJson)) {
|
|
return;
|
|
}
|
|
return linkConverter(link);
|
|
}, retryOptions);
|
|
}
|
|
}
|
|
async function editLinks(app, pathOrFile, linkConverter, retryOptions = {}) {
|
|
await (0, import_FileChange2.applyFileChanges)(app, pathOrFile, async () => {
|
|
const cache = await (0, import_MetadataCache3.getCacheSafe)(app, pathOrFile);
|
|
if (!cache) {
|
|
return [];
|
|
}
|
|
const changes = [];
|
|
for (const link of (0, import_MetadataCache3.getAllLinks)(cache)) {
|
|
const newContent = await linkConverter(link);
|
|
if (newContent === void 0) {
|
|
continue;
|
|
}
|
|
changes.push((0, import_Reference2.referenceToFileChange)(link, newContent));
|
|
}
|
|
return changes;
|
|
}, retryOptions);
|
|
}
|
|
function extractLinkFile3(app, link, notePathOrFile) {
|
|
const { linkPath } = splitSubpath3(link.link);
|
|
return app.metadataCache.getFirstLinkpathDest(linkPath, (0, import_FileSystem4.getPath)(notePathOrFile));
|
|
}
|
|
function generateMarkdownLink2(options) {
|
|
const { app } = options;
|
|
const configurableDefaultOptionsFn = app.fileManager.generateMarkdownLink.defaultOptionsFn ?? (() => ({}));
|
|
const configurableDefaultOptions = configurableDefaultOptionsFn();
|
|
const DEFAULT_OPTIONS = {
|
|
allowEmptyEmbedAlias: true
|
|
};
|
|
options = { ...DEFAULT_OPTIONS, ...configurableDefaultOptions, ...options };
|
|
const file = (0, import_FileSystem4.getFile)(app, options.pathOrFile, options.allowNonExistingFile);
|
|
return (0, import_MetadataCache3.tempRegisterFileAndRun)(app, file, () => {
|
|
const sourcePath = (0, import_FileSystem4.getPath)(options.sourcePathOrFile);
|
|
const subpath = options.subpath ?? "";
|
|
let alias = options.alias ?? "";
|
|
const isEmbed = options.isEmbed ?? (options.originalLink ? testEmbed2(options.originalLink) : void 0) ?? !(0, import_FileSystem4.isMarkdownFile)(file);
|
|
const isWikilink = options.isWikilink ?? (options.originalLink ? testWikilink2(options.originalLink) : void 0) ?? (0, import_ObsidianSettings.shouldUseWikilinks)(app);
|
|
const forceRelativePath = options.forceRelativePath ?? (0, import_ObsidianSettings.shouldUseRelativeLinks)(app);
|
|
const useLeadingDot = options.useLeadingDot ?? (options.originalLink ? testLeadingDot(options.originalLink) : void 0) ?? false;
|
|
const useAngleBrackets = options.useAngleBrackets ?? (options.originalLink ? testAngleBrackets(options.originalLink) : void 0) ?? false;
|
|
let linkText = file.path === sourcePath && subpath ? subpath : forceRelativePath ? (0, import_Path4.relative)((0, import_Path4.dirname)(sourcePath), isWikilink ? (0, import_FileSystem4.trimMarkdownExtension)(file) : file.path) + subpath : app.metadataCache.fileToLinktext(file, sourcePath, isWikilink) + subpath;
|
|
if (forceRelativePath && useLeadingDot && !linkText.startsWith(".") && !linkText.startsWith("#")) {
|
|
linkText = "./" + linkText;
|
|
}
|
|
const embedPrefix = isEmbed ? "!" : "";
|
|
if (!isWikilink) {
|
|
if (useAngleBrackets) {
|
|
linkText = `<${linkText}>`;
|
|
} else {
|
|
linkText = linkText.replace(SPECIAL_LINK_SYMBOLS_REGEXP, function(specialLinkSymbol) {
|
|
return encodeURIComponent(specialLinkSymbol);
|
|
});
|
|
}
|
|
if (!alias && (!isEmbed || !options.allowEmptyEmbedAlias)) {
|
|
alias = !options.includeAttachmentExtensionToEmbedAlias || (0, import_FileSystem4.isMarkdownFile)(file) ? file.basename : file.name;
|
|
}
|
|
alias = alias.replace(SPECIAL_MARKDOWN_LINK_SYMBOLS_REGEX, "\\$&");
|
|
return `${embedPrefix}[${alias}](${linkText})`;
|
|
} else {
|
|
if (alias && alias.toLowerCase() === linkText.toLowerCase()) {
|
|
linkText = alias;
|
|
alias = "";
|
|
}
|
|
const aliasPart = alias ? `|${alias}` : "";
|
|
return `${embedPrefix}[[${linkText}${aliasPart}]]`;
|
|
}
|
|
});
|
|
}
|
|
function shouldResetAlias(options) {
|
|
const {
|
|
app,
|
|
displayText,
|
|
isWikilink,
|
|
otherPathOrFiles,
|
|
pathOrFile,
|
|
sourcePathOrFile
|
|
} = options;
|
|
if (isWikilink === false) {
|
|
return false;
|
|
}
|
|
const file = (0, import_FileSystem4.getFile)(app, pathOrFile);
|
|
if (!displayText) {
|
|
return true;
|
|
}
|
|
const sourcePath = (0, import_FileSystem4.getPath)(sourcePathOrFile);
|
|
const sourceDir = (0, import_Path4.dirname)(sourcePath);
|
|
const aliasesToReset = /* @__PURE__ */ new Set();
|
|
for (const pathOrFile2 of [file.path, ...otherPathOrFiles]) {
|
|
if (!pathOrFile2) {
|
|
continue;
|
|
}
|
|
const path = (0, import_FileSystem4.getPath)(pathOrFile2);
|
|
aliasesToReset.add(path);
|
|
aliasesToReset.add((0, import_Path4.basename)(path));
|
|
aliasesToReset.add((0, import_Path4.relative)(sourceDir, path));
|
|
}
|
|
aliasesToReset.add(app.metadataCache.fileToLinktext(file, sourcePath, false));
|
|
const cleanDisplayText = (0, import_obsidian5.normalizePath)(displayText.split(" > ")[0] ?? "").replace(/^\.\//, "").toLowerCase();
|
|
for (const alias of aliasesToReset) {
|
|
if (alias.toLowerCase() === cleanDisplayText) {
|
|
return true;
|
|
}
|
|
const dir = (0, import_Path4.dirname)(alias);
|
|
const base = (0, import_Path4.basename)(alias, (0, import_Path4.extname)(alias));
|
|
if ((0, import_Path4.join)(dir, base).toLowerCase() === cleanDisplayText) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function splitSubpath3(link) {
|
|
const parsed = (0, import_obsidian5.parseLinktext)((0, import_String.normalize)(link));
|
|
return {
|
|
linkPath: parsed.path,
|
|
subpath: parsed.subpath
|
|
};
|
|
}
|
|
function testAngleBrackets(link) {
|
|
return link.includes("](<");
|
|
}
|
|
function testEmbed2(link) {
|
|
return link.startsWith("![");
|
|
}
|
|
function testLeadingDot(link) {
|
|
return link.includes("[[./") || link.includes("](./") || link.includes("](<./");
|
|
}
|
|
function testWikilink2(link) {
|
|
return link.includes("[[");
|
|
}
|
|
function updateLink(options) {
|
|
const {
|
|
app,
|
|
forceMarkdownLinks,
|
|
link,
|
|
oldPathOrFile,
|
|
pathOrFile,
|
|
renameMap,
|
|
shouldUpdateFilenameAlias,
|
|
sourcePathOrFile
|
|
} = options;
|
|
if (!pathOrFile) {
|
|
return link.original;
|
|
}
|
|
let file = (0, import_FileSystem4.getFile)(app, pathOrFile);
|
|
const oldPath = (0, import_FileSystem4.getPath)(oldPathOrFile ?? sourcePathOrFile);
|
|
const isWikilink = testWikilink2(link.original) && forceMarkdownLinks !== true;
|
|
const { subpath } = splitSubpath3(link.link);
|
|
const newPath = renameMap?.get(file.path);
|
|
let alias = shouldResetAlias({
|
|
app,
|
|
displayText: link.displayText,
|
|
isWikilink,
|
|
otherPathOrFiles: [oldPath, newPath],
|
|
pathOrFile,
|
|
sourcePathOrFile
|
|
}) ? void 0 : link.displayText;
|
|
if (shouldUpdateFilenameAlias ?? true) {
|
|
if (alias?.toLowerCase() === (0, import_Path4.basename)(oldPath, (0, import_Path4.extname)(oldPath)).toLowerCase()) {
|
|
alias = file.basename;
|
|
} else if (alias?.toLowerCase() === (0, import_Path4.basename)(oldPath).toLowerCase()) {
|
|
alias = file.name;
|
|
}
|
|
}
|
|
if (newPath) {
|
|
file = (0, import_FileSystem4.getFile)(app, newPath, true);
|
|
}
|
|
const newLink = generateMarkdownLink2({
|
|
alias,
|
|
app,
|
|
isWikilink: forceMarkdownLinks ? false : void 0,
|
|
originalLink: link.original,
|
|
pathOrFile: file,
|
|
sourcePathOrFile,
|
|
subpath
|
|
});
|
|
return newLink;
|
|
}
|
|
async function updateLinksInFile2(options) {
|
|
const {
|
|
app,
|
|
embedOnlyLinks,
|
|
forceMarkdownLinks,
|
|
oldPathOrFile,
|
|
pathOrFile,
|
|
renameMap,
|
|
shouldUpdateFilenameAlias
|
|
} = options;
|
|
await editLinks(app, pathOrFile, (link) => {
|
|
const isEmbedLink = testEmbed2(link.original);
|
|
if (embedOnlyLinks !== void 0 && embedOnlyLinks !== isEmbedLink) {
|
|
return;
|
|
}
|
|
return convertLink({
|
|
app,
|
|
forceMarkdownLinks,
|
|
link,
|
|
oldPathOrFile,
|
|
renameMap,
|
|
shouldUpdateFilenameAlias,
|
|
sourcePathOrFile: pathOrFile
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/RenameDeleteHandler.cjs
|
|
var require_RenameDeleteHandler = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/RenameDeleteHandler.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var RenameDeleteHandler_exports = {};
|
|
__export2(RenameDeleteHandler_exports, {
|
|
registerRenameDeleteHandlers: () => registerRenameDeleteHandlers2
|
|
});
|
|
module2.exports = __toCommonJS2(RenameDeleteHandler_exports);
|
|
var import_monkey_around = require_dist();
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_Error = require_Error();
|
|
var import_Function2 = require_Function();
|
|
var import_Object = require_Object();
|
|
var import_Path4 = require_Path();
|
|
var import_App = require_App();
|
|
var import_AttachmentPath2 = require_AttachmentPath();
|
|
var import_FileSystem4 = require_FileSystem();
|
|
var import_Link3 = require_Link();
|
|
var import_MetadataCache3 = require_MetadataCache();
|
|
var import_Queue2 = require_Queue();
|
|
var import_Vault3 = require_Vault();
|
|
var __process2 = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
var deletedMetadataCacheMap = /* @__PURE__ */ new Map();
|
|
var handledRenames = /* @__PURE__ */ new Set();
|
|
function registerRenameDeleteHandlers2(plugin, settingsBuilder) {
|
|
const renameDeleteHandlersMap = getRenameDeleteHandlersMap(plugin.app);
|
|
const pluginId = plugin.manifest.id;
|
|
renameDeleteHandlersMap.set(pluginId, settingsBuilder);
|
|
logRegisteredHandlers(plugin.app);
|
|
plugin.register(() => {
|
|
renameDeleteHandlersMap.delete(pluginId);
|
|
logRegisteredHandlers(plugin.app);
|
|
});
|
|
const app = plugin.app;
|
|
plugin.registerEvent(
|
|
app.vault.on("delete", (file) => {
|
|
if (!shouldInvokeHandler(app, pluginId)) {
|
|
return;
|
|
}
|
|
const path = file.path;
|
|
(0, import_Queue2.addToQueue)(app, () => handleDelete(app, path));
|
|
})
|
|
);
|
|
plugin.registerEvent(
|
|
app.vault.on("rename", (file, oldPath) => {
|
|
if (!shouldInvokeHandler(app, pluginId)) {
|
|
return;
|
|
}
|
|
if (!(0, import_FileSystem4.isFile)(file)) {
|
|
return;
|
|
}
|
|
const newPath = file.path;
|
|
handleRename(app, oldPath, newPath);
|
|
})
|
|
);
|
|
plugin.registerEvent(
|
|
app.metadataCache.on("deleted", (file, prevCache) => {
|
|
handleMetadataDeleted(app, file, prevCache);
|
|
})
|
|
);
|
|
}
|
|
async function fillRenameMap(app, oldPath, newPath, renameMap) {
|
|
renameMap.set(oldPath, newPath);
|
|
if (!(0, import_FileSystem4.isNote)(oldPath)) {
|
|
return;
|
|
}
|
|
const settings = getSettings(app);
|
|
const oldAttachmentFolderPath = await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, oldPath);
|
|
const newAttachmentFolderPath = settings.shouldRenameAttachmentFolder ? await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, newPath) : oldAttachmentFolderPath;
|
|
const oldAttachmentFolder = (0, import_FileSystem4.getFolderOrNull)(app, oldAttachmentFolderPath);
|
|
if (!oldAttachmentFolder) {
|
|
return;
|
|
}
|
|
if (oldAttachmentFolderPath === newAttachmentFolderPath && !settings.shouldRenameAttachmentFiles) {
|
|
return;
|
|
}
|
|
const oldAttachmentFiles = [];
|
|
if (!await (0, import_AttachmentPath2.hasOwnAttachmentFolder)(app, oldPath)) {
|
|
const oldCache = await (0, import_MetadataCache3.getCacheSafe)(app, oldPath);
|
|
if (!oldCache) {
|
|
return;
|
|
}
|
|
for (const oldLink of (0, import_MetadataCache3.getAllLinks)(oldCache)) {
|
|
const oldAttachmentFile = (0, import_Link3.extractLinkFile)(app, oldLink, oldPath);
|
|
if (!oldAttachmentFile) {
|
|
continue;
|
|
}
|
|
if (oldAttachmentFile.path.startsWith(oldAttachmentFolderPath)) {
|
|
const oldAttachmentBacklinks = await (0, import_MetadataCache3.getBacklinksForFileSafe)(app, oldAttachmentFile);
|
|
if (oldAttachmentBacklinks.keys().length === 1) {
|
|
oldAttachmentFiles.push(oldAttachmentFile);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
import_obsidian5.Vault.recurseChildren(oldAttachmentFolder, (oldAttachmentFile) => {
|
|
if ((0, import_FileSystem4.isFile)(oldAttachmentFile)) {
|
|
oldAttachmentFiles.push(oldAttachmentFile);
|
|
}
|
|
});
|
|
}
|
|
const oldBasename = (0, import_Path4.basename)(oldPath, (0, import_Path4.extname)(oldPath));
|
|
const newBasename = (0, import_Path4.basename)(newPath, (0, import_Path4.extname)(newPath));
|
|
for (const oldAttachmentFile of oldAttachmentFiles) {
|
|
if ((0, import_FileSystem4.isNote)(oldAttachmentFile)) {
|
|
continue;
|
|
}
|
|
const relativePath = (0, import_Path4.relative)(oldAttachmentFolderPath, oldAttachmentFile.path);
|
|
const newDir = (0, import_Path4.join)(newAttachmentFolderPath, (0, import_Path4.dirname)(relativePath));
|
|
const newChildBasename = settings.shouldRenameAttachmentFiles ? oldAttachmentFile.basename.replaceAll(oldBasename, newBasename) : oldAttachmentFile.basename;
|
|
let newChildPath = (0, import_Path4.join)(newDir, (0, import_Path4.makeFileName)(newChildBasename, oldAttachmentFile.extension));
|
|
if (oldAttachmentFile.path === newChildPath) {
|
|
continue;
|
|
}
|
|
if (settings.shouldDeleteConflictingAttachments) {
|
|
const newChildFile = (0, import_FileSystem4.getFileOrNull)(app, newChildPath);
|
|
if (newChildFile) {
|
|
await app.fileManager.trashFile(newChildFile);
|
|
}
|
|
} else {
|
|
newChildPath = app.vault.getAvailablePath((0, import_Path4.join)(newDir, newChildBasename), oldAttachmentFile.extension);
|
|
}
|
|
renameMap.set(oldAttachmentFile.path, newChildPath);
|
|
}
|
|
}
|
|
function getRenameDeleteHandlersMap(app) {
|
|
return (0, import_App.getObsidianDevUtilsState)(app, "renameDeleteHandlersMap", /* @__PURE__ */ new Map()).value;
|
|
}
|
|
function getSettings(app) {
|
|
const renameDeleteHandlersMap = getRenameDeleteHandlersMap(app);
|
|
const settingsBuilders = Array.from(renameDeleteHandlersMap.values()).reverse();
|
|
const settings = {};
|
|
for (const settingsBuilder of settingsBuilders) {
|
|
const newSettings = settingsBuilder();
|
|
for (const [key, value] of Object.entries(newSettings)) {
|
|
settings[key] ||= value;
|
|
}
|
|
}
|
|
return settings;
|
|
}
|
|
async function handleDelete(app, path) {
|
|
console.debug(`Handle Delete ${path}`);
|
|
if (!(0, import_FileSystem4.isNote)(path)) {
|
|
return;
|
|
}
|
|
const settings = getSettings(app);
|
|
if (!settings.shouldDeleteOrphanAttachments) {
|
|
return;
|
|
}
|
|
const cache = deletedMetadataCacheMap.get(path);
|
|
deletedMetadataCacheMap.delete(path);
|
|
if (cache) {
|
|
const links = (0, import_MetadataCache3.getAllLinks)(cache);
|
|
for (const link of links) {
|
|
const attachmentFile = (0, import_Link3.extractLinkFile)(app, link, path);
|
|
if (!attachmentFile) {
|
|
continue;
|
|
}
|
|
if ((0, import_FileSystem4.isNote)(attachmentFile)) {
|
|
continue;
|
|
}
|
|
await (0, import_Vault3.deleteSafe)(app, attachmentFile, path, settings.shouldDeleteEmptyFolders);
|
|
}
|
|
}
|
|
const attachmentFolderPath = await (0, import_AttachmentPath2.getAttachmentFolderPath)(app, path);
|
|
const attachmentFolder = (0, import_FileSystem4.getFolderOrNull)(app, attachmentFolderPath);
|
|
if (!attachmentFolder) {
|
|
return;
|
|
}
|
|
if (!await (0, import_AttachmentPath2.hasOwnAttachmentFolder)(app, path)) {
|
|
return;
|
|
}
|
|
await (0, import_Vault3.deleteSafe)(app, attachmentFolder, path, false, settings.shouldDeleteEmptyFolders);
|
|
}
|
|
function handleMetadataDeleted(app, file, prevCache) {
|
|
const settings = getSettings(app);
|
|
if (!settings.shouldDeleteOrphanAttachments) {
|
|
return;
|
|
}
|
|
if ((0, import_FileSystem4.isMarkdownFile)(file) && prevCache) {
|
|
deletedMetadataCacheMap.set(file.path, prevCache);
|
|
}
|
|
}
|
|
function handleRename(app, oldPath, newPath) {
|
|
const key = makeKey(oldPath, newPath);
|
|
console.debug(`Handle Rename ${key}`);
|
|
if (handledRenames.has(key)) {
|
|
handledRenames.delete(key);
|
|
return;
|
|
}
|
|
const backlinks = (0, import_MetadataCache3.getBacklinksForFileOrPath)(app, oldPath);
|
|
(0, import_Queue2.addToQueue)(app, () => handleRenameAsync(app, oldPath, newPath, backlinks));
|
|
}
|
|
async function handleRenameAsync(app, oldPath, newPath, backlinks) {
|
|
if (app.vault.adapter.insensitive && oldPath.toLowerCase() === newPath.toLowerCase()) {
|
|
const tempPath = (0, import_Path4.join)((0, import_Path4.dirname)(newPath), "__temp__" + (0, import_Path4.basename)(newPath));
|
|
await renameHandled(app, newPath, tempPath);
|
|
await handleRenameAsync(app, oldPath, tempPath, backlinks);
|
|
await app.vault.rename((0, import_FileSystem4.getFile)(app, tempPath), newPath);
|
|
return;
|
|
}
|
|
const restoreUpdateAllLinks = (0, import_monkey_around.around)(app.fileManager, {
|
|
updateAllLinks: () => import_Function2.noopAsync
|
|
});
|
|
try {
|
|
const renameMap = /* @__PURE__ */ new Map();
|
|
await fillRenameMap(app, oldPath, newPath, renameMap);
|
|
const backlinksMap = /* @__PURE__ */ new Map();
|
|
initBacklinksMap(backlinks.data, renameMap, backlinksMap, oldPath);
|
|
for (const attachmentOldPath of renameMap.keys()) {
|
|
if (attachmentOldPath === oldPath) {
|
|
continue;
|
|
}
|
|
const currentBacklinksMap = await (0, import_MetadataCache3.getBacklinksMap)(app, [attachmentOldPath]);
|
|
initBacklinksMap(currentBacklinksMap, renameMap, backlinksMap, attachmentOldPath);
|
|
}
|
|
const parentFolders = /* @__PURE__ */ new Set();
|
|
for (const [oldRelatedPath, newRelatedPath] of renameMap.entries()) {
|
|
if (oldRelatedPath === oldPath) {
|
|
continue;
|
|
}
|
|
const fixedNewRelatedPath = await renameHandled(app, oldRelatedPath, newRelatedPath);
|
|
renameMap.set(oldRelatedPath, fixedNewRelatedPath);
|
|
parentFolders.add((0, import_Path4.dirname)(oldRelatedPath));
|
|
}
|
|
const settings = getSettings(app);
|
|
if (settings.shouldDeleteEmptyFolders) {
|
|
for (const parentFolder of parentFolders) {
|
|
await (0, import_Vault3.deleteEmptyFolderHierarchy)(app, parentFolder);
|
|
}
|
|
}
|
|
for (const [newBacklinkPath, linkJsonToPathMap] of backlinksMap.entries()) {
|
|
await (0, import_Link3.editLinks)(app, newBacklinkPath, (link) => {
|
|
const oldRelatedPath = linkJsonToPathMap.get((0, import_Object.toJson)(link));
|
|
if (!oldRelatedPath) {
|
|
return;
|
|
}
|
|
const newRelatedPath = renameMap.get(oldRelatedPath);
|
|
if (!newRelatedPath) {
|
|
return;
|
|
}
|
|
return (0, import_Link3.updateLink)({
|
|
app,
|
|
link,
|
|
oldPathOrFile: oldRelatedPath,
|
|
pathOrFile: newRelatedPath,
|
|
renameMap,
|
|
shouldUpdateFilenameAlias: settings.shouldUpdateFilenameAliases,
|
|
sourcePathOrFile: newBacklinkPath
|
|
});
|
|
});
|
|
}
|
|
if ((0, import_FileSystem4.isCanvasFile)(newPath)) {
|
|
await (0, import_Vault3.process)(app, newPath, (content) => {
|
|
let canvasData;
|
|
try {
|
|
canvasData = JSON.parse(content);
|
|
} catch (e) {
|
|
(0, import_Error.printError)(new Error(`Failed to parse canvas data for ${newPath}`, { cause: e }));
|
|
return content;
|
|
}
|
|
for (const node of canvasData.nodes) {
|
|
if (node.type !== "file") {
|
|
continue;
|
|
}
|
|
const newPath2 = renameMap.get(node.file);
|
|
if (!newPath2) {
|
|
continue;
|
|
}
|
|
node.file = newPath2;
|
|
}
|
|
return (0, import_Object.toJson)(canvasData);
|
|
});
|
|
} else if ((0, import_FileSystem4.isMarkdownFile)(newPath)) {
|
|
await (0, import_Link3.updateLinksInFile)({
|
|
app,
|
|
oldPathOrFile: oldPath,
|
|
pathOrFile: newPath,
|
|
renameMap,
|
|
shouldUpdateFilenameAlias: settings.shouldUpdateFilenameAliases
|
|
});
|
|
}
|
|
} finally {
|
|
restoreUpdateAllLinks();
|
|
const orphanKeys = Array.from(handledRenames);
|
|
(0, import_Queue2.addToQueue)(app, () => {
|
|
for (const key of orphanKeys) {
|
|
handledRenames.delete(key);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function initBacklinksMap(currentBacklinksMap, renameMap, backlinksMap, path) {
|
|
for (const [backlinkPath, links] of currentBacklinksMap.entries()) {
|
|
const newBacklinkPath = renameMap.get(backlinkPath) ?? backlinkPath;
|
|
const linkJsonToPathMap = backlinksMap.get(newBacklinkPath) ?? /* @__PURE__ */ new Map();
|
|
backlinksMap.set(newBacklinkPath, linkJsonToPathMap);
|
|
for (const link of links) {
|
|
linkJsonToPathMap.set((0, import_Object.toJson)(link), path);
|
|
}
|
|
}
|
|
}
|
|
function logRegisteredHandlers(app) {
|
|
const renameDeleteHandlersMap = getRenameDeleteHandlersMap(app);
|
|
console.debug(`Plugins with registered rename/delete handlers: ${Array.from(renameDeleteHandlersMap.keys()).join(", ")}`);
|
|
}
|
|
function makeKey(oldPath, newPath) {
|
|
return `${oldPath} -> ${newPath}`;
|
|
}
|
|
async function renameHandled(app, oldPath, newPath) {
|
|
newPath = (0, import_Vault3.getSafeRenamePath)(app, oldPath, newPath);
|
|
if (oldPath === newPath) {
|
|
return newPath;
|
|
}
|
|
const key = makeKey(oldPath, newPath);
|
|
handledRenames.add(key);
|
|
newPath = await (0, import_Vault3.renameSafe)(app, oldPath, newPath);
|
|
return newPath;
|
|
}
|
|
function shouldInvokeHandler(app, pluginId) {
|
|
const renameDeleteHandlerPluginIds = getRenameDeleteHandlersMap(app);
|
|
const mainPluginId = Array.from(renameDeleteHandlerPluginIds.keys())[0];
|
|
if (mainPluginId !== pluginId) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettingsTabBase.cjs
|
|
var require_PluginSettingsTabBase = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/PluginSettingsTabBase.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var PluginSettingsTabBase_exports = {};
|
|
__export2(PluginSettingsTabBase_exports, {
|
|
PluginSettingsTabBase: () => PluginSettingsTabBase2
|
|
});
|
|
module2.exports = __toCommonJS2(PluginSettingsTabBase_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_PluginBase2 = require_PluginBase();
|
|
var PluginSettingsTabBase2 = class extends import_obsidian5.PluginSettingTab {
|
|
constructor(plugin) {
|
|
super(plugin.app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
};
|
|
}
|
|
});
|
|
|
|
// node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/ValueComponent.cjs
|
|
var require_ValueComponent = __commonJS({
|
|
"node_modules/obsidian-dev-utils/dist/lib/obsidian/Plugin/ValueComponent.cjs"(exports2, module2) {
|
|
(function patchRequireEsmDefault() {
|
|
const __require = require;
|
|
require = Object.assign((id) => {
|
|
const module3 = __require(id);
|
|
return module3.__esModule && module3.default ? module3.default : module3;
|
|
}, __require);
|
|
})();
|
|
var __defProp2 = Object.defineProperty;
|
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
var __export2 = (target, all) => {
|
|
for (var name in all)
|
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps2 = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames2(from))
|
|
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
var ValueComponent_exports = {};
|
|
__export2(ValueComponent_exports, {
|
|
extend: () => extend2
|
|
});
|
|
module2.exports = __toCommonJS2(ValueComponent_exports);
|
|
var import_obsidian5 = require("obsidian");
|
|
var import_Object = require_Object();
|
|
var ValueComponentEx = class {
|
|
constructor(valueComponent) {
|
|
this.valueComponent = valueComponent;
|
|
}
|
|
/**
|
|
* Returns the ValueComponent with extended functionality.
|
|
*/
|
|
asExtended() {
|
|
return (0, import_Object.assignWithNonEnumerableProperties)({}, this.valueComponent, this);
|
|
}
|
|
/**
|
|
* Binds the ValueComponent to a property in the plugin settings.
|
|
*
|
|
* @typeParam Plugin - The type of the plugin that extends `PluginBase`.
|
|
* @typeParam Property - The key of the plugin setting that the component is bound to.
|
|
* @typeParam PluginSettings - The type of the plugin settings object.
|
|
* @param plugin - The plugin.
|
|
* @param property - The property key in `PluginSettings` to bind to the UI component.
|
|
* @param options - Configuration options.
|
|
* @returns The `ValueComponent` instance that was bound to the property.
|
|
*/
|
|
bind(plugin, property, options) {
|
|
const DEFAULT_OPTIONS = {
|
|
autoSave: true,
|
|
componentToPluginSettingsValueConverter: (value) => value,
|
|
pluginSettingsToComponentValueConverter: (value) => value
|
|
};
|
|
const optionsExt = { ...DEFAULT_OPTIONS, ...options };
|
|
const pluginExt = plugin;
|
|
const pluginSettingsFn = () => optionsExt.pluginSettings ?? pluginExt.settingsCopy;
|
|
const validate = (uiValue) => {
|
|
if (!optionsExt.valueValidator) {
|
|
return true;
|
|
}
|
|
uiValue ??= this.valueComponent.getValue();
|
|
const errorMessage = optionsExt.valueValidator(uiValue);
|
|
const validatorElement2 = getValidatorElement(this.valueComponent);
|
|
if (validatorElement2) {
|
|
validatorElement2.setCustomValidity(errorMessage ?? "");
|
|
validatorElement2.reportValidity();
|
|
}
|
|
return !errorMessage;
|
|
};
|
|
this.valueComponent.setValue(optionsExt.pluginSettingsToComponentValueConverter(pluginSettingsFn()[property])).onChange(async (uiValue) => {
|
|
if (!validate(uiValue)) {
|
|
return;
|
|
}
|
|
const pluginSettings = pluginSettingsFn();
|
|
pluginSettings[property] = optionsExt.componentToPluginSettingsValueConverter(uiValue);
|
|
if (optionsExt.autoSave) {
|
|
await pluginExt.saveSettings(pluginSettings);
|
|
}
|
|
await optionsExt.onChanged?.();
|
|
});
|
|
validate();
|
|
const validatorElement = getValidatorElement(this.valueComponent);
|
|
if (validatorElement) {
|
|
validatorElement.addEventListener("focus", () => validate());
|
|
validatorElement.addEventListener("blur", () => validate());
|
|
}
|
|
return this.asExtended();
|
|
}
|
|
};
|
|
function extend2(valueComponent) {
|
|
return new ValueComponentEx(valueComponent).asExtended();
|
|
}
|
|
function getValidatorElement(valueComponent) {
|
|
if (valueComponent instanceof import_obsidian5.DropdownComponent) {
|
|
return valueComponent.selectEl;
|
|
}
|
|
if (valueComponent instanceof import_obsidian5.SliderComponent) {
|
|
return valueComponent.sliderEl;
|
|
}
|
|
if (valueComponent instanceof import_obsidian5.TextAreaComponent) {
|
|
return valueComponent.inputEl;
|
|
}
|
|
if (valueComponent instanceof import_obsidian5.TextComponent) {
|
|
return valueComponent.inputEl;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
});
|
|
|
|
// src/main.ts
|
|
var main_exports = {};
|
|
__export(main_exports, {
|
|
default: () => main_default
|
|
});
|
|
module.exports = __toCommonJS(main_exports);
|
|
|
|
// src/ConsistentAttachmentsAndLinksPlugin.ts
|
|
var import_obsidian4 = require("obsidian");
|
|
var import_Function = __toESM(require_Function(), 1);
|
|
var import_FileSystem3 = __toESM(require_FileSystem(), 1);
|
|
var import_PluginBase = __toESM(require_PluginBase(), 1);
|
|
var import_Queue = __toESM(require_Queue(), 1);
|
|
var import_RenameDeleteHandler = __toESM(require_RenameDeleteHandler(), 1);
|
|
var import_Vault2 = __toESM(require_Vault(), 1);
|
|
var import_Path3 = __toESM(require_Path(), 1);
|
|
|
|
// src/ConsistentAttachmentsAndLinksPluginSettings.ts
|
|
var ConsistentAttachmentsAndLinksPluginSettings = class {
|
|
autoCollectAttachments = false;
|
|
changeNoteBacklinksAlt = true;
|
|
consistencyReportFile = "consistency-report.md";
|
|
deleteAttachmentsWithNote = true;
|
|
deleteEmptyFolders = true;
|
|
deleteExistFilesWhenMoveNote = true;
|
|
ignoreFiles = ["consistency\\-report\\.md"];
|
|
ignoreFolders = [".git/", ".obsidian/"];
|
|
moveAttachmentsWithNote = true;
|
|
showWarning = true;
|
|
updateLinks = true;
|
|
getIgnoreFilesRegex() {
|
|
return this.ignoreFiles.map((file) => RegExp(file));
|
|
}
|
|
};
|
|
|
|
// src/ConsistentAttachmentsAndLinksPluginSettingsTab.ts
|
|
var import_obsidian = require("obsidian");
|
|
var import_PluginSettingsTabBase = __toESM(require_PluginSettingsTabBase(), 1);
|
|
var import_ValueComponent = __toESM(require_ValueComponent(), 1);
|
|
var ConsistentAttachmentsAndLinksPluginSettingsTab = class extends import_PluginSettingsTabBase.PluginSettingsTabBase {
|
|
display() {
|
|
this.containerEl.empty();
|
|
new import_obsidian.Setting(this.containerEl).setName("Move Attachments with Note").setDesc("Automatically move attachments when a note is relocated. This includes attachments located in the same folder or any of its subfolders.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "moveAttachmentsWithNote"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Delete Unused Attachments with Note").setDesc("Automatically remove attachments that are no longer referenced in other notes when the note is deleted.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteAttachmentsWithNote"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Update Links").setDesc("Automatically update links to attachments and other notes when moving notes or attachments.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "updateLinks"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Delete Empty Folders").setDesc("Automatically remove empty folders after moving notes with attachments.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteEmptyFolders"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Delete Duplicate Attachments on Note Move").setDesc("Automatically delete attachments when moving a note if a file with the same name exists in the destination folder. If disabled, the file will be renamed and moved.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "deleteExistFilesWhenMoveNote"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Update Backlink Text on Note Rename").setDesc("When a note is renamed, its linked references are automatically updated. If this option is enabled, the text of backlinks to this note will also be modified.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "changeNoteBacklinksAlt"));
|
|
new import_obsidian.Setting(this.containerEl).setName("Ignore Folders").setDesc("Specify a list of folders to ignore. Enter each folder on a new line.").addTextArea(
|
|
(textArea) => (0, import_ValueComponent.extend)(textArea).bind(this.plugin, "ignoreFolders", {
|
|
componentToPluginSettingsValueConverter: (value) => value.trim().split("\n").map((value2) => this.getNormalizedPath(value2) + "/"),
|
|
pluginSettingsToComponentValueConverter: (value) => value.join("\n")
|
|
}).setPlaceholder("Example: .git, .obsidian")
|
|
);
|
|
new import_obsidian.Setting(this.containerEl).setName("Ignore Files").setDesc("Specify a list of files to ignore. Enter each file on a new line.").addTextArea(
|
|
(textArea) => (0, import_ValueComponent.extend)(textArea).bind(this.plugin, "ignoreFiles", {
|
|
componentToPluginSettingsValueConverter: (value) => value.trim().split("\n"),
|
|
pluginSettingsToComponentValueConverter: (value) => value.join("\n")
|
|
}).setPlaceholder("Example: consistent-report.md")
|
|
);
|
|
new import_obsidian.Setting(this.containerEl).setName("Consistency Report Filename").setDesc("Specify the name of the file for the consistency report.").addText(
|
|
(text) => (0, import_ValueComponent.extend)(text).bind(this.plugin, "consistencyReportFile").setPlaceholder("Example: consistency-report.md")
|
|
);
|
|
new import_obsidian.Setting(this.containerEl).setName("Auto Collect Attachments").setDesc("Automatically collect attachments when the note is edited.").addToggle((toggle) => (0, import_ValueComponent.extend)(toggle).bind(this.plugin, "autoCollectAttachments"));
|
|
}
|
|
getNormalizedPath(path) {
|
|
return path.length == 0 ? path : (0, import_obsidian.normalizePath)(path);
|
|
}
|
|
};
|
|
|
|
// src/files-handler.ts
|
|
var import_obsidian3 = require("obsidian");
|
|
var import_AttachmentPath = __toESM(require_AttachmentPath(), 1);
|
|
var import_FileSystem2 = __toESM(require_FileSystem(), 1);
|
|
var import_Link2 = __toESM(require_Link(), 1);
|
|
var import_MetadataCache2 = __toESM(require_MetadataCache(), 1);
|
|
var import_Vault = __toESM(require_Vault(), 1);
|
|
var import_Path2 = __toESM(require_Path(), 1);
|
|
|
|
// src/links-handler.ts
|
|
var import_obsidian2 = require("obsidian");
|
|
var import_FileChange = __toESM(require_FileChange(), 1);
|
|
var import_FileSystem = __toESM(require_FileSystem(), 1);
|
|
var import_Link = __toESM(require_Link(), 1);
|
|
var import_MetadataCache = __toESM(require_MetadataCache(), 1);
|
|
var import_Reference = __toESM(require_Reference(), 1);
|
|
var import_Path = __toESM(require_Path(), 1);
|
|
var ConsistencyCheckResult = class extends Map {
|
|
constructor(title) {
|
|
super();
|
|
this.title = title;
|
|
}
|
|
add(notePath, link) {
|
|
if (!this.has(notePath)) {
|
|
this.set(notePath, []);
|
|
}
|
|
const arr = this.get(notePath);
|
|
if (arr) {
|
|
arr.push(link);
|
|
}
|
|
}
|
|
toString(app, reportPath) {
|
|
if (this.size > 0) {
|
|
let str = `# ${this.title} (${this.size.toString()} files)
|
|
`;
|
|
for (const notePath of this.keys()) {
|
|
const note = (0, import_FileSystem.getFileOrNull)(app, notePath);
|
|
if (!note) {
|
|
continue;
|
|
}
|
|
const linkStr = (0, import_Link.generateMarkdownLink)({
|
|
app,
|
|
pathOrFile: note,
|
|
sourcePathOrFile: reportPath
|
|
});
|
|
str += `${linkStr}:
|
|
`;
|
|
for (const link of this.get(notePath) ?? []) {
|
|
str += `- (line ${(link.position.start.line + 1).toString()}): \`${link.link}\`
|
|
`;
|
|
}
|
|
str += "\n\n";
|
|
}
|
|
return str;
|
|
} else {
|
|
return `# ${this.title}
|
|
No problems found
|
|
|
|
`;
|
|
}
|
|
}
|
|
};
|
|
var LinksHandler = class {
|
|
constructor(app, consoleLogPrefix = "", ignoreFolders = [], ignoreFilesRegex = []) {
|
|
this.app = app;
|
|
this.consoleLogPrefix = consoleLogPrefix;
|
|
this.ignoreFolders = ignoreFolders;
|
|
this.ignoreFilesRegex = ignoreFilesRegex;
|
|
}
|
|
async checkConsistency(note, badLinks, badEmbeds, wikiLinks, wikiEmbeds) {
|
|
if (this.isPathIgnored(note.path)) {
|
|
return;
|
|
}
|
|
const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note.path);
|
|
if (!cache) {
|
|
return;
|
|
}
|
|
const links = cache.links ?? [];
|
|
const embeds = cache.embeds ?? [];
|
|
for (const link of links) {
|
|
if (!await this.isValidLink(link, note.path)) {
|
|
badLinks.add(note.path, link);
|
|
}
|
|
if ((0, import_Link.testWikilink)(link.original)) {
|
|
wikiLinks.add(note.path, link);
|
|
}
|
|
}
|
|
for (const embed of embeds) {
|
|
if (!await this.isValidLink(embed, note.path)) {
|
|
badEmbeds.add(note.path, embed);
|
|
}
|
|
if ((0, import_Link.testWikilink)(embed.original)) {
|
|
wikiEmbeds.add(note.path, embed);
|
|
}
|
|
}
|
|
}
|
|
async convertAllNoteEmbedsPathsToRelative(notePath) {
|
|
return this.convertAllNoteRefPathsToRelative(notePath, true);
|
|
}
|
|
async convertAllNoteLinksPathsToRelative(notePath) {
|
|
return this.convertAllNoteRefPathsToRelative(notePath, false);
|
|
}
|
|
async getCachedNotesThatHaveLinkToFile(filePath) {
|
|
const file = (0, import_FileSystem.getFileOrNull)(this.app, filePath);
|
|
if (!file) {
|
|
return [];
|
|
}
|
|
const backlinks = await (0, import_MetadataCache.getBacklinksForFileSafe)(this.app, file);
|
|
return backlinks.keys();
|
|
}
|
|
getFullPathForLink(link, owningNotePath) {
|
|
({ linkPath: link } = (0, import_Link.splitSubpath)(link));
|
|
const parentFolder = (0, import_Path.dirname)(owningNotePath);
|
|
const fullPath = (0, import_Path.join)(parentFolder, link);
|
|
return fullPath;
|
|
}
|
|
async replaceAllNoteWikilinksWithMarkdownLinks(notePath, embedOnlyLinks) {
|
|
if (this.isPathIgnored(notePath)) {
|
|
return 0;
|
|
}
|
|
const noteFile = (0, import_FileSystem.getFileOrNull)(this.app, notePath);
|
|
if (!noteFile) {
|
|
console.warn(this.consoleLogPrefix + "can't update wikilinks in note, file not found: " + notePath);
|
|
return 0;
|
|
}
|
|
const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, noteFile);
|
|
if (!cache) {
|
|
return 0;
|
|
}
|
|
const links = (embedOnlyLinks ? cache.embeds : cache.links) ?? [];
|
|
const result = links.filter((link) => (0, import_Link.testWikilink)(link.original)).length;
|
|
await (0, import_Link.updateLinksInFile)({
|
|
app: this.app,
|
|
embedOnlyLinks,
|
|
forceMarkdownLinks: true,
|
|
oldPathOrFile: noteFile.path,
|
|
pathOrFile: noteFile,
|
|
renameMap: /* @__PURE__ */ new Map()
|
|
});
|
|
return result;
|
|
}
|
|
async updateChangedPathsInNote(notePath, changedLinks) {
|
|
if (this.isPathIgnored(notePath)) {
|
|
return;
|
|
}
|
|
const note = (0, import_FileSystem.getFileOrNull)(this.app, notePath);
|
|
if (!note) {
|
|
console.warn(this.consoleLogPrefix + "can't update links in note, file not found: " + notePath);
|
|
return;
|
|
}
|
|
const pathChangeMap = /* @__PURE__ */ new Map();
|
|
for (const change of changedLinks) {
|
|
pathChangeMap.set(change.oldPath, change.newPath);
|
|
}
|
|
await this.updateLinks(note, note.path, pathChangeMap);
|
|
}
|
|
async convertAllNoteRefPathsToRelative(notePath, isEmbed) {
|
|
if (this.isPathIgnored(notePath)) {
|
|
return [];
|
|
}
|
|
const note = (0, import_FileSystem.getFileOrNull)(this.app, notePath);
|
|
if (!note) {
|
|
return [];
|
|
}
|
|
const changedRefs = [];
|
|
await (0, import_FileChange.applyFileChanges)(this.app, note, async () => {
|
|
const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note);
|
|
if (!cache) {
|
|
return [];
|
|
}
|
|
const refs = (isEmbed ? cache.embeds : cache.links) ?? [];
|
|
const changes = [];
|
|
for (const ref of refs) {
|
|
const change = {
|
|
endIndex: ref.position.end.offset,
|
|
newContent: this.convertLink({
|
|
forceRelativePath: true,
|
|
link: ref,
|
|
note,
|
|
oldNotePath: notePath
|
|
}),
|
|
oldContent: ref.original,
|
|
startIndex: ref.position.start.offset
|
|
};
|
|
changes.push(change);
|
|
changedRefs.push({ newLink: change.newContent, old: ref });
|
|
}
|
|
return changes;
|
|
});
|
|
return changedRefs;
|
|
}
|
|
convertLink({
|
|
forceRelativePath,
|
|
link,
|
|
note,
|
|
oldNotePath,
|
|
pathChangeMap
|
|
}) {
|
|
const { linkPath, subpath } = (0, import_Link.splitSubpath)(link.link);
|
|
const oldLinkPath = (0, import_Link.extractLinkFile)(this.app, link, oldNotePath)?.path ?? (0, import_Path.join)((0, import_Path.dirname)(oldNotePath), linkPath);
|
|
const newLinkPath = pathChangeMap ? pathChangeMap.get(oldLinkPath) : (0, import_Link.extractLinkFile)(this.app, link, note.path)?.path ?? (0, import_Path.join)((0, import_Path.dirname)(note.path), linkPath);
|
|
if (!newLinkPath) {
|
|
return link.original;
|
|
}
|
|
const newLinkedNote = (0, import_FileSystem.getFileOrNull)(this.app, oldLinkPath) ?? (0, import_FileSystem.getFileOrNull)(this.app, newLinkPath);
|
|
if (!newLinkedNote) {
|
|
return link.original;
|
|
}
|
|
return (0, import_Link.generateMarkdownLink)({
|
|
alias: link.displayText,
|
|
app: this.app,
|
|
forceRelativePath,
|
|
originalLink: link.original,
|
|
pathOrFile: newLinkedNote,
|
|
sourcePathOrFile: note.path,
|
|
subpath
|
|
});
|
|
}
|
|
isPathIgnored(path) {
|
|
if (path.startsWith("./")) {
|
|
path = path.slice(2);
|
|
}
|
|
for (const folder of this.ignoreFolders) {
|
|
if (path.startsWith(folder)) {
|
|
return true;
|
|
}
|
|
}
|
|
for (const fileRegex of this.ignoreFilesRegex) {
|
|
if (fileRegex.test(path)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async isValidLink(link, notePath) {
|
|
const { linkPath, subpath } = (0, import_Link.splitSubpath)(link.link);
|
|
let fullLinkPath;
|
|
if (!linkPath) {
|
|
fullLinkPath = notePath;
|
|
} else if (linkPath.startsWith("/")) {
|
|
fullLinkPath = (0, import_obsidian2.normalizePath)(linkPath);
|
|
} else {
|
|
fullLinkPath = (0, import_Path.join)((0, import_Path.dirname)(notePath), linkPath);
|
|
}
|
|
const file = (0, import_FileSystem.getFileOrNull)(this.app, fullLinkPath);
|
|
if (!file) {
|
|
return false;
|
|
}
|
|
if (!subpath) {
|
|
return true;
|
|
}
|
|
const ext = file.extension.toLocaleLowerCase();
|
|
if (ext === "pdf") {
|
|
return subpath.startsWith("#page=");
|
|
}
|
|
if (ext !== import_FileSystem.MARKDOWN_FILE_EXTENSION) {
|
|
return false;
|
|
}
|
|
const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, file);
|
|
if (!cache) {
|
|
return false;
|
|
}
|
|
if (subpath.startsWith("#^")) {
|
|
return Object.keys(cache.blocks ?? {}).includes(subpath.slice(2));
|
|
} else {
|
|
return (cache.headings ?? []).map((h) => h.heading.replaceAll("#", " ")).includes(subpath.slice(1));
|
|
}
|
|
}
|
|
async updateLinks(note, oldNotePath, pathChangeMap) {
|
|
await (0, import_FileChange.applyFileChanges)(this.app, note, async () => {
|
|
const cache = await (0, import_MetadataCache.getCacheSafe)(this.app, note);
|
|
if (!cache) {
|
|
return [];
|
|
}
|
|
const links = (0, import_MetadataCache.getAllLinks)(cache);
|
|
return links.map((link) => (0, import_Reference.referenceToFileChange)(link, this.convertLink({
|
|
link,
|
|
note,
|
|
oldNotePath,
|
|
pathChangeMap
|
|
})));
|
|
});
|
|
}
|
|
};
|
|
|
|
// src/files-handler.ts
|
|
var FilesHandler = class {
|
|
constructor(app, lh, consoleLogPrefix = "", ignoreFolders = [], ignoreFilesRegex = [], shouldDeleteEmptyFolders = false) {
|
|
this.app = app;
|
|
this.lh = lh;
|
|
this.consoleLogPrefix = consoleLogPrefix;
|
|
this.ignoreFolders = ignoreFolders;
|
|
this.ignoreFilesRegex = ignoreFilesRegex;
|
|
this.shouldDeleteEmptyFolders = shouldDeleteEmptyFolders;
|
|
}
|
|
async collectAttachmentsForCachedNote(notePath, deleteExistFiles, deleteEmptyFolders) {
|
|
if (this.isPathIgnored(notePath)) {
|
|
return { movedAttachments: [], renamedFiles: [] };
|
|
}
|
|
const result = {
|
|
movedAttachments: [],
|
|
renamedFiles: []
|
|
};
|
|
const cache = await (0, import_MetadataCache2.getCacheSafe)(this.app, notePath);
|
|
if (!cache) {
|
|
return result;
|
|
}
|
|
for (const link of (0, import_MetadataCache2.getAllLinks)(cache)) {
|
|
const { linkPath } = (0, import_Link2.splitSubpath)(link.link);
|
|
if (!linkPath) {
|
|
continue;
|
|
}
|
|
const fullPathLink = this.lh.getFullPathForLink(linkPath, notePath);
|
|
if (result.movedAttachments.findIndex((x) => x.oldPath == fullPathLink) != -1) {
|
|
continue;
|
|
}
|
|
const file = (0, import_Link2.extractLinkFile)(this.app, link, notePath);
|
|
if (!file) {
|
|
const type = (0, import_Link2.testEmbed)(link.original) ? "embed" : "link";
|
|
console.warn(`${this.consoleLogPrefix}${notePath} has bad ${type} (file does not exist): ${linkPath}`);
|
|
continue;
|
|
}
|
|
if (!this.isAttachment(file)) {
|
|
continue;
|
|
}
|
|
const newPath = await (0, import_AttachmentPath.getAttachmentFilePath)(this.app, file.path, notePath);
|
|
if ((0, import_Path2.dirname)(newPath) === (0, import_Path2.dirname)(file.path)) {
|
|
continue;
|
|
}
|
|
const res = await this.moveAttachment(file, newPath, [notePath], deleteExistFiles, deleteEmptyFolders);
|
|
result.movedAttachments = result.movedAttachments.concat(res.movedAttachments);
|
|
result.renamedFiles = result.renamedFiles.concat(res.renamedFiles);
|
|
}
|
|
return result;
|
|
}
|
|
async deleteEmptyFolders(dirName) {
|
|
if (this.isPathIgnored(dirName)) {
|
|
return;
|
|
}
|
|
if (dirName.startsWith("./")) {
|
|
dirName = dirName.slice(2);
|
|
}
|
|
let list = await (0, import_Vault.listSafe)(this.app, dirName);
|
|
for (const folder of list.folders) {
|
|
await this.deleteEmptyFolders(folder);
|
|
}
|
|
list = await (0, import_Vault.listSafe)(this.app, dirName);
|
|
if (list.files.length == 0 && list.folders.length == 0) {
|
|
console.log(this.consoleLogPrefix + "delete empty folder: \n " + dirName);
|
|
if (await this.app.vault.exists(dirName)) {
|
|
try {
|
|
await this.app.vault.adapter.rmdir(dirName, false);
|
|
} catch (e) {
|
|
if (await this.app.vault.adapter.exists(dirName)) {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
async createFolderForAttachmentFromPath(filePath) {
|
|
await (0, import_Vault.createFolderSafe)(this.app, (0, import_Path2.dirname)(filePath));
|
|
}
|
|
async deleteFile(file, deleteEmptyFolders) {
|
|
await this.app.fileManager.trashFile(file);
|
|
if (deleteEmptyFolders) {
|
|
let dir = file.parent;
|
|
while (dir && dir.children.length === 0) {
|
|
await this.app.fileManager.trashFile(dir);
|
|
dir = dir.parent;
|
|
}
|
|
}
|
|
}
|
|
isAttachment(file) {
|
|
return !(0, import_FileSystem2.isNote)(file);
|
|
}
|
|
isPathIgnored(path) {
|
|
if (path.startsWith("./")) {
|
|
path = path.slice(2);
|
|
}
|
|
for (const folder of this.ignoreFolders) {
|
|
if (path.startsWith(folder)) {
|
|
return true;
|
|
}
|
|
}
|
|
for (const fileRegex of this.ignoreFilesRegex) {
|
|
const testResult = fileRegex.test(path);
|
|
if (testResult) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async moveAttachment(file, newLinkPath, parentNotePaths, deleteExistFiles, deleteEmptyFolders) {
|
|
const path = file.path;
|
|
const result = {
|
|
movedAttachments: [],
|
|
renamedFiles: []
|
|
};
|
|
if (this.isPathIgnored(path)) {
|
|
return result;
|
|
}
|
|
if (!this.isAttachment(file)) {
|
|
return result;
|
|
}
|
|
if (path == newLinkPath) {
|
|
console.warn(this.consoleLogPrefix + "Can't move file. Source and destination path the same.");
|
|
return result;
|
|
}
|
|
await this.createFolderForAttachmentFromPath(newLinkPath);
|
|
const linkedNotes = await this.lh.getCachedNotesThatHaveLinkToFile(path);
|
|
for (const notePath of parentNotePaths) {
|
|
linkedNotes.remove(notePath);
|
|
}
|
|
if (path !== file.path) {
|
|
console.warn(this.consoleLogPrefix + "File was moved already");
|
|
return await this.moveAttachment(file, newLinkPath, parentNotePaths, deleteExistFiles, deleteEmptyFolders);
|
|
}
|
|
const oldFolder = file.parent;
|
|
if (linkedNotes.length == 0) {
|
|
const existFile = (0, import_FileSystem2.getFileOrNull)(this.app, newLinkPath);
|
|
if (!existFile) {
|
|
console.log(this.consoleLogPrefix + "move file [from, to]: \n " + path + "\n " + newLinkPath);
|
|
result.movedAttachments.push({ newPath: newLinkPath, oldPath: path });
|
|
await (0, import_Vault.renameSafe)(this.app, file, newLinkPath);
|
|
} else {
|
|
if (deleteExistFiles) {
|
|
console.log(this.consoleLogPrefix + "delete file: \n " + path);
|
|
result.movedAttachments.push({ newPath: newLinkPath, oldPath: path });
|
|
await this.deleteFile(file, deleteEmptyFolders);
|
|
} else {
|
|
const newFileCopyName = (0, import_Vault.getAvailablePath)(this.app, newLinkPath);
|
|
console.log(this.consoleLogPrefix + "copy file with new name [from, to]: \n " + path + "\n " + newFileCopyName);
|
|
result.movedAttachments.push({ newPath: newFileCopyName, oldPath: path });
|
|
await (0, import_Vault.renameSafe)(this.app, file, newFileCopyName);
|
|
result.renamedFiles.push({ newPath: newFileCopyName, oldPath: newLinkPath });
|
|
}
|
|
}
|
|
} else {
|
|
const existFile = (0, import_FileSystem2.getFileOrNull)(this.app, newLinkPath);
|
|
if (!existFile) {
|
|
console.log(this.consoleLogPrefix + "copy file [from, to]: \n " + path + "\n " + newLinkPath);
|
|
result.movedAttachments.push({ newPath: newLinkPath, oldPath: path });
|
|
await (0, import_Vault.renameSafe)(this.app, file, newLinkPath);
|
|
await (0, import_Vault.copySafe)(this.app, file, path);
|
|
} else if (!deleteExistFiles) {
|
|
const newFileCopyName = (0, import_Vault.getAvailablePath)(this.app, newLinkPath);
|
|
console.log(this.consoleLogPrefix + "copy file with new name [from, to]: \n " + path + "\n " + newFileCopyName);
|
|
result.movedAttachments.push({ newPath: newFileCopyName, oldPath: file.path });
|
|
await (0, import_Vault.renameSafe)(this.app, file, newFileCopyName);
|
|
await (0, import_Vault.copySafe)(this.app, file, path);
|
|
result.renamedFiles.push({ newPath: newFileCopyName, oldPath: newLinkPath });
|
|
}
|
|
}
|
|
if (this.shouldDeleteEmptyFolders) {
|
|
await (0, import_Vault.deleteEmptyFolderHierarchy)(this.app, oldFolder);
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
// src/ConsistentAttachmentsAndLinksPlugin.ts
|
|
var __process = globalThis["process"] ?? {
|
|
"cwd": () => "/",
|
|
"env": {},
|
|
"platform": "android"
|
|
};
|
|
var ConsistentAttachmentsAndLinksPlugin = class extends import_PluginBase.PluginBase {
|
|
deletedNoteCache = /* @__PURE__ */ new Map();
|
|
fh;
|
|
lh;
|
|
async saveSettings(newSettings) {
|
|
await super.saveSettings(newSettings);
|
|
this.lh = new LinksHandler(
|
|
this.app,
|
|
"Consistent Attachments and Links: ",
|
|
this.settings.ignoreFolders,
|
|
this.settings.getIgnoreFilesRegex()
|
|
);
|
|
this.fh = new FilesHandler(
|
|
this.app,
|
|
this.lh,
|
|
"Consistent Attachments and Links: ",
|
|
this.settings.ignoreFolders,
|
|
this.settings.getIgnoreFilesRegex()
|
|
);
|
|
}
|
|
createDefaultPluginSettings() {
|
|
return new ConsistentAttachmentsAndLinksPluginSettings();
|
|
}
|
|
createPluginSettingsTab() {
|
|
return new ConsistentAttachmentsAndLinksPluginSettingsTab(this);
|
|
}
|
|
onloadComplete() {
|
|
if (this.settings.showWarning) {
|
|
const notice = new import_obsidian4.Notice(createFragment((f) => {
|
|
f.appendText("Starting from ");
|
|
appendCodeBlock(f, "v3.0.0");
|
|
f.appendText(", the plugin ");
|
|
appendCodeBlock(f, "Consistent Attachments and Links");
|
|
f.appendText(" has setting ");
|
|
appendCodeBlock(f, "Attachment Subfolder");
|
|
f.appendText(" removed. This is a BREAKING CHANGE.");
|
|
f.appendChild(createEl("br"));
|
|
f.appendChild(createEl("a", { href: "https://github.com/dy-sh/obsidian-consistent-attachments-and-links?tab=readme-ov-file#attachment-subfolder-setting", text: "Read more" }));
|
|
}), 0);
|
|
notice.noticeEl.onClickEvent((ev) => {
|
|
(0, import_Queue.addToQueue)(this.app, async () => {
|
|
if (ev.target instanceof HTMLAnchorElement) {
|
|
window.open(ev.target.href, "_blank");
|
|
}
|
|
this.settings.showWarning = false;
|
|
await this.saveSettings(this.settings);
|
|
});
|
|
});
|
|
}
|
|
this.registerEvent(
|
|
this.app.metadataCache.on("deleted", (file, prevCache) => {
|
|
if (prevCache) {
|
|
this.handleDeletedMetadata(file, prevCache);
|
|
}
|
|
})
|
|
);
|
|
(0, import_RenameDeleteHandler.registerRenameDeleteHandlers)(this, () => {
|
|
const settings = {
|
|
shouldDeleteConflictingAttachments: this.settings.deleteExistFilesWhenMoveNote,
|
|
shouldDeleteEmptyFolders: this.settings.deleteEmptyFolders,
|
|
shouldDeleteOrphanAttachments: this.settings.deleteAttachmentsWithNote,
|
|
shouldRenameAttachmentFolder: this.settings.moveAttachmentsWithNote,
|
|
shouldUpdateFilenameAliases: this.settings.changeNoteBacklinksAlt,
|
|
shouldUpdateLinks: this.settings.updateLinks
|
|
};
|
|
return settings;
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.collectAllAttachments(),
|
|
id: "collect-all-attachments",
|
|
name: "Collect All Attachments"
|
|
});
|
|
this.addCommand({
|
|
checkCallback: this.collectAttachmentsCurrentNote.bind(this),
|
|
id: "collect-attachments-current-note",
|
|
name: "Collect Attachments in Current Note"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.deleteEmptyFolders(),
|
|
id: "delete-empty-folders",
|
|
name: "Delete Empty Folders"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.convertAllLinkPathsToRelative(),
|
|
id: "convert-all-link-paths-to-relative",
|
|
name: "Convert All Link Paths to Relative"
|
|
});
|
|
this.addCommand({
|
|
checkCallback: this.convertAllLinkPathsToRelativeCurrentNote.bind(this),
|
|
id: "convert-all-link-paths-to-relative-current-note",
|
|
name: "Convert All Link Paths to Relative in Current Note"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.convertAllEmbedsPathsToRelative(),
|
|
id: "convert-all-embed-paths-to-relative",
|
|
name: "Convert All Embed Paths to Relative"
|
|
});
|
|
this.addCommand({
|
|
checkCallback: this.convertAllEmbedsPathsToRelativeCurrentNote.bind(this),
|
|
id: "convert-all-embed-paths-to-relative-current-note",
|
|
name: "Convert All Embed Paths to Relative in Current Note"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.replaceAllWikilinksWithMarkdownLinks(),
|
|
id: "replace-all-wikilinks-with-markdown-links",
|
|
name: "Replace All Wiki Links with Markdown Links"
|
|
});
|
|
this.addCommand({
|
|
checkCallback: this.replaceAllWikilinksWithMarkdownLinksCurrentNote.bind(this),
|
|
id: "replace-all-wikilinks-with-markdown-links-current-note",
|
|
name: "Replace All Wiki Links with Markdown Links in Current Note"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.replaceAllWikiEmbedsWithMarkdownEmbeds(),
|
|
id: "replace-all-wiki-embeds-with-markdown-embeds",
|
|
name: "Replace All Wiki Embeds with Markdown Embeds"
|
|
});
|
|
this.addCommand({
|
|
checkCallback: this.replaceAllWikiEmbedsWithMarkdownEmbedsCurrentNote.bind(this),
|
|
id: "replace-all-wiki-embeds-with-markdown-embeds-current-note",
|
|
name: "Replace All Wiki Embeds with Markdown Embeds in Current Note"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.reorganizeVault(),
|
|
id: "reorganize-vault",
|
|
name: "Reorganize Vault"
|
|
});
|
|
this.addCommand({
|
|
callback: () => this.checkConsistency(),
|
|
id: "check-consistency",
|
|
name: "Check Vault consistency"
|
|
});
|
|
this.registerEvent(this.app.metadataCache.on("changed", (file) => {
|
|
(0, import_Queue.addToQueue)(this.app, () => this.handleMetadataCacheChanged(file));
|
|
}));
|
|
this.lh = new LinksHandler(
|
|
this.app,
|
|
"Consistent Attachments and Links: ",
|
|
this.settings.ignoreFolders,
|
|
this.settings.getIgnoreFilesRegex()
|
|
);
|
|
this.fh = new FilesHandler(
|
|
this.app,
|
|
this.lh,
|
|
"Consistent Attachments and Links: ",
|
|
this.settings.ignoreFolders,
|
|
this.settings.getIgnoreFilesRegex(),
|
|
this.settings.deleteEmptyFolders
|
|
);
|
|
}
|
|
async checkConsistency() {
|
|
await this.saveAllOpenNotes();
|
|
const badLinks = new ConsistencyCheckResult("Bad links");
|
|
const badEmbeds = new ConsistencyCheckResult("Bad embeds");
|
|
const wikiLinks = new ConsistencyCheckResult("Wiki links");
|
|
const wikiEmbeds = new ConsistencyCheckResult("Wiki embeds");
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note2 of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Checking note # ${i.toString()} / ${notes.length.toString()} - ${note2.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
await this.lh.checkConsistency(note2, badLinks, badEmbeds, wikiLinks, wikiEmbeds);
|
|
}
|
|
notice.hide();
|
|
const notePath = this.settings.consistencyReportFile;
|
|
const text = badLinks.toString(this.app, notePath) + badEmbeds.toString(this.app, notePath) + wikiLinks.toString(this.app, notePath) + wikiEmbeds.toString(this.app, notePath);
|
|
await (0, import_Vault2.createFolderSafe)(this.app, (0, import_Path3.dirname)(notePath));
|
|
const note = await (0, import_FileSystem3.getOrCreateFile)(this.app, notePath);
|
|
await this.app.vault.modify(note, text);
|
|
let fileOpened = false;
|
|
this.app.workspace.iterateAllLeaves((leaf) => {
|
|
if (leaf.getDisplayText() != "" && notePath.startsWith(leaf.getDisplayText())) {
|
|
fileOpened = true;
|
|
}
|
|
});
|
|
if (!fileOpened) {
|
|
await this.app.workspace.openLinkText(notePath, "/", false);
|
|
}
|
|
}
|
|
async collectAllAttachments() {
|
|
let movedAttachmentsCount = 0;
|
|
let processedNotesCount = 0;
|
|
await this.saveAllOpenNotes();
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Collecting attachments # ${i.toString()} / ${notes.length.toString()} - ${note.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
if (this.isPathIgnored(note.path)) {
|
|
continue;
|
|
}
|
|
const result = await this.fh.collectAttachmentsForCachedNote(
|
|
note.path,
|
|
this.settings.deleteExistFilesWhenMoveNote,
|
|
this.settings.deleteEmptyFolders
|
|
);
|
|
if (result.movedAttachments.length > 0) {
|
|
await this.lh.updateChangedPathsInNote(note.path, result.movedAttachments);
|
|
movedAttachmentsCount += result.movedAttachments.length;
|
|
processedNotesCount++;
|
|
}
|
|
}
|
|
notice.hide();
|
|
if (movedAttachmentsCount == 0) {
|
|
new import_obsidian4.Notice("No files found that need to be moved");
|
|
} else {
|
|
new import_obsidian4.Notice(`Moved ${movedAttachmentsCount.toString()} attachment${movedAttachmentsCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
async collectAttachments(note, isVerbose = true) {
|
|
if (this.isPathIgnored(note.path)) {
|
|
new import_obsidian4.Notice("Note path is ignored");
|
|
return;
|
|
}
|
|
await this.saveAllOpenNotes();
|
|
const result = await this.fh.collectAttachmentsForCachedNote(
|
|
note.path,
|
|
this.settings.deleteExistFilesWhenMoveNote,
|
|
this.settings.deleteEmptyFolders
|
|
);
|
|
if (result.movedAttachments.length > 0) {
|
|
await this.lh.updateChangedPathsInNote(note.path, result.movedAttachments);
|
|
}
|
|
if (result.movedAttachments.length == 0) {
|
|
if (isVerbose) {
|
|
new import_obsidian4.Notice("No files found that need to be moved");
|
|
}
|
|
} else {
|
|
new import_obsidian4.Notice(`Moved ${result.movedAttachments.length.toString()} attachment${result.movedAttachments.length > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
collectAttachmentsCurrentNote(checking) {
|
|
const note = this.app.workspace.getActiveFile();
|
|
if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) {
|
|
return false;
|
|
}
|
|
if (!checking) {
|
|
(0, import_Queue.addToQueue)(this.app, () => this.collectAttachments(note));
|
|
}
|
|
return true;
|
|
}
|
|
async convertAllEmbedsPathsToRelative() {
|
|
await this.saveAllOpenNotes();
|
|
let changedEmbedCount = 0;
|
|
let processedNotesCount = 0;
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Converting embed paths to relative # ${i.toString()} / ${notes.length.toString()} - ${note.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
if (this.isPathIgnored(note.path)) {
|
|
continue;
|
|
}
|
|
const result = await this.lh.convertAllNoteEmbedsPathsToRelative(note.path);
|
|
if (result.length > 0) {
|
|
changedEmbedCount += result.length;
|
|
processedNotesCount++;
|
|
}
|
|
}
|
|
notice.hide();
|
|
if (changedEmbedCount == 0) {
|
|
new import_obsidian4.Notice("No embeds found that need to be converted");
|
|
} else {
|
|
new import_obsidian4.Notice(`Converted ${changedEmbedCount.toString()} embed${changedEmbedCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
convertAllEmbedsPathsToRelativeCurrentNote(checking) {
|
|
const note = this.app.workspace.getActiveFile();
|
|
if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) {
|
|
return false;
|
|
}
|
|
if (!checking) {
|
|
(0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.convertAllNoteEmbedsPathsToRelative(note.path)));
|
|
}
|
|
return true;
|
|
}
|
|
async convertAllLinkPathsToRelative() {
|
|
await this.saveAllOpenNotes();
|
|
let changedLinksCount = 0;
|
|
let processedNotesCount = 0;
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Converting link paths to relative # ${i.toString()} / ${notes.length.toString()} - ${note.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
if (this.isPathIgnored(note.path)) {
|
|
continue;
|
|
}
|
|
const result = await this.lh.convertAllNoteLinksPathsToRelative(note.path);
|
|
if (result.length > 0) {
|
|
changedLinksCount += result.length;
|
|
processedNotesCount++;
|
|
}
|
|
}
|
|
notice.hide();
|
|
if (changedLinksCount == 0) {
|
|
new import_obsidian4.Notice("No links found that need to be converted");
|
|
} else {
|
|
new import_obsidian4.Notice(`Converted ${changedLinksCount.toString()} link${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
convertAllLinkPathsToRelativeCurrentNote(checking) {
|
|
const note = this.app.workspace.getActiveFile();
|
|
if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) {
|
|
return false;
|
|
}
|
|
if (!checking) {
|
|
(0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.convertAllNoteLinksPathsToRelative(note.path)));
|
|
}
|
|
return true;
|
|
}
|
|
async deleteEmptyFolders() {
|
|
await this.fh.deleteEmptyFolders("/");
|
|
}
|
|
handleDeletedMetadata(file, prevCache) {
|
|
if (!this.settings.deleteAttachmentsWithNote || this.isPathIgnored(file.path) || !(0, import_FileSystem3.isMarkdownFile)(file)) {
|
|
return;
|
|
}
|
|
this.deletedNoteCache.set(file.path, prevCache);
|
|
}
|
|
async handleMetadataCacheChanged(file) {
|
|
if (!this.settings.autoCollectAttachments) {
|
|
return;
|
|
}
|
|
const suggestionContainer = document.querySelector(".suggestion-container");
|
|
if (suggestionContainer && suggestionContainer.style.display !== "none") {
|
|
return;
|
|
}
|
|
await this.collectAttachments(file, false);
|
|
}
|
|
isPathIgnored(path) {
|
|
if (path.startsWith("./")) {
|
|
path = path.slice(2);
|
|
}
|
|
for (const folder of this.settings.ignoreFolders) {
|
|
if (path.startsWith(folder)) {
|
|
return true;
|
|
}
|
|
}
|
|
for (const fileRegex of this.settings.getIgnoreFilesRegex()) {
|
|
if (fileRegex.test(path)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async reorganizeVault() {
|
|
await this.saveAllOpenNotes();
|
|
await this.replaceAllWikilinksWithMarkdownLinks();
|
|
await this.replaceAllWikiEmbedsWithMarkdownEmbeds();
|
|
await this.convertAllEmbedsPathsToRelative();
|
|
await this.convertAllLinkPathsToRelative();
|
|
await this.collectAllAttachments();
|
|
await this.deleteEmptyFolders();
|
|
new import_obsidian4.Notice("Reorganization of the vault completed");
|
|
}
|
|
async replaceAllWikiEmbedsWithMarkdownEmbeds() {
|
|
await this.saveAllOpenNotes();
|
|
let changedLinksCount = 0;
|
|
let processedNotesCount = 0;
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Replacing wiki embeds with markdown embeds # ${i.toString()} / ${notes.length.toString()} - ${note.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
if (this.isPathIgnored(note.path)) {
|
|
continue;
|
|
}
|
|
const result = await this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, true);
|
|
changedLinksCount += result;
|
|
processedNotesCount++;
|
|
}
|
|
notice.hide();
|
|
if (changedLinksCount == 0) {
|
|
new import_obsidian4.Notice("No wiki embeds found that need to be replaced");
|
|
} else {
|
|
new import_obsidian4.Notice(`Replaced ${changedLinksCount.toString()} wiki embed${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
replaceAllWikiEmbedsWithMarkdownEmbedsCurrentNote(checking) {
|
|
const note = this.app.workspace.getActiveFile();
|
|
if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) {
|
|
return false;
|
|
}
|
|
if (!checking) {
|
|
(0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, true)));
|
|
}
|
|
return true;
|
|
}
|
|
async replaceAllWikilinksWithMarkdownLinks() {
|
|
await this.saveAllOpenNotes();
|
|
let changedLinksCount = 0;
|
|
let processedNotesCount = 0;
|
|
const notes = (0, import_Vault2.getMarkdownFilesSorted)(this.app);
|
|
let i = 0;
|
|
const notice = new import_obsidian4.Notice("", 0);
|
|
for (const note of notes) {
|
|
if (this.abortSignal.aborted) {
|
|
notice.hide();
|
|
return;
|
|
}
|
|
i++;
|
|
const message = `Replacing wikilinks with markdown links # ${i.toString()} / ${notes.length.toString()} - ${note.path}`;
|
|
notice.setMessage(message);
|
|
console.debug(message);
|
|
if (this.isPathIgnored(note.path)) {
|
|
continue;
|
|
}
|
|
const result = await this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, false);
|
|
changedLinksCount += result;
|
|
processedNotesCount++;
|
|
}
|
|
notice.hide();
|
|
if (changedLinksCount == 0) {
|
|
new import_obsidian4.Notice("No wiki links found that need to be replaced");
|
|
} else {
|
|
new import_obsidian4.Notice(`Replaced ${changedLinksCount.toString()} wikilink${changedLinksCount > 1 ? "s" : ""} from ${processedNotesCount.toString()} note${processedNotesCount > 1 ? "s" : ""}`);
|
|
}
|
|
}
|
|
replaceAllWikilinksWithMarkdownLinksCurrentNote(checking) {
|
|
const note = this.app.workspace.getActiveFile();
|
|
if (!note || !(0, import_FileSystem3.isMarkdownFile)(note)) {
|
|
return false;
|
|
}
|
|
if (!checking) {
|
|
(0, import_Queue.addToQueue)(this.app, (0, import_Function.omitAsyncReturnType)(() => this.lh.replaceAllNoteWikilinksWithMarkdownLinks(note.path, false)));
|
|
}
|
|
return true;
|
|
}
|
|
async saveAllOpenNotes() {
|
|
for (const leaf of this.app.workspace.getLeavesOfType("markdown")) {
|
|
if (leaf.view instanceof import_obsidian4.MarkdownView) {
|
|
await leaf.view.save();
|
|
}
|
|
}
|
|
}
|
|
};
|
|
function appendCodeBlock(fragment, text) {
|
|
fragment.appendChild(createSpan({ cls: "markdown-rendered code" }, (span) => {
|
|
span.style.fontWeight = "bold";
|
|
span.appendChild(createEl("code", { text }));
|
|
}));
|
|
}
|
|
|
|
// src/main.ts
|
|
var main_default = ConsistentAttachmentsAndLinksPlugin;
|
|
|
|
/* nosourcemap */ |