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/smart-embed-model/node_modules/base64-js/index.js
var require_base64_js = __commonJS({
"node_modules/smart-embed-model/node_modules/base64-js/index.js"(exports2) {
"use strict";
exports2.byteLength = byteLength;
exports2.toByteArray = toByteArray;
exports2.fromByteArray = fromByteArray;
var lookup = [];
var revLookup = [];
var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (i = 0, len = code.length; i < len; ++i) {
lookup[i] = code[i];
revLookup[code.charCodeAt(i)] = i;
}
var i;
var len;
revLookup["-".charCodeAt(0)] = 62;
revLookup["_".charCodeAt(0)] = 63;
function getLens(b64) {
var len2 = b64.length;
if (len2 % 4 > 0) {
throw new Error("Invalid string. Length must be a multiple of 4");
}
var validLen = b64.indexOf("=");
if (validLen === -1) validLen = len2;
var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
return [validLen, placeHoldersLen];
}
function byteLength(b64) {
var lens = getLens(b64);
var validLen = lens[0];
var placeHoldersLen = lens[1];
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function _byteLength(b64, validLen, placeHoldersLen) {
return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
}
function toByteArray(b64) {
var tmp;
var lens = getLens(b64);
var validLen = lens[0];
var placeHoldersLen = lens[1];
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen));
var curByte = 0;
var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen;
var i2;
for (i2 = 0; i2 < len2; i2 += 4) {
tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)];
arr[curByte++] = tmp >> 16 & 255;
arr[curByte++] = tmp >> 8 & 255;
arr[curByte++] = tmp & 255;
}
if (placeHoldersLen === 2) {
tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4;
arr[curByte++] = tmp & 255;
}
if (placeHoldersLen === 1) {
tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2;
arr[curByte++] = tmp >> 8 & 255;
arr[curByte++] = tmp & 255;
}
return arr;
}
function tripletToBase64(num) {
return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
}
function encodeChunk(uint8, start, end) {
var tmp;
var output = [];
for (var i2 = start; i2 < end; i2 += 3) {
tmp = (uint8[i2] << 16 & 16711680) + (uint8[i2 + 1] << 8 & 65280) + (uint8[i2 + 2] & 255);
output.push(tripletToBase64(tmp));
}
return output.join("");
}
function fromByteArray(uint8) {
var tmp;
var len2 = uint8.length;
var extraBytes = len2 % 3;
var parts = [];
var maxChunkLength = 16383;
for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) {
parts.push(encodeChunk(uint8, i2, i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength));
}
if (extraBytes === 1) {
tmp = uint8[len2 - 1];
parts.push(
lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "=="
);
} else if (extraBytes === 2) {
tmp = (uint8[len2 - 2] << 8) + uint8[len2 - 1];
parts.push(
lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="
);
}
return parts.join("");
}
}
});
// src/index.js
var src_exports = {};
__export(src_exports, {
default: () => SmartConnectionsPlugin
});
module.exports = __toCommonJS(src_exports);
var import_obsidian23 = __toESM(require("obsidian"), 1);
// node_modules/obsidian-smart-env/smart_env.js
var import_obsidian6 = require("obsidian");
// node_modules/obsidian-smart-env/node_modules/smart-environment/components/settings.js
async function build_html(scope, opts = {}) {
const env_settings_html = Object.entries(scope.settings_config).map(([setting_key, setting_config]) => {
if (!setting_config.setting) setting_config.setting = setting_key;
return this.render_setting_html(setting_config);
}).join("\n");
const env_collections_containers_html = Object.entries(scope.collections).map(([collection_key, collection]) => {
return `
`;
}).join("\n");
const html = `
${env_settings_html}
${env_collections_containers_html}
`;
return html;
}
async function render(scope, opts = {}) {
const html = await build_html.call(this, scope, opts);
const frag = this.create_doc_fragment(html);
return await post_process.call(this, scope, frag, opts);
}
async function post_process(scope, frag, opts = {}) {
await this.render_setting_components(frag, { scope });
const env_collections_containers = frag.querySelectorAll("[data-smart-settings]");
for (const env_collections_container of env_collections_containers) {
const collection_key = env_collections_container.dataset.smartSettings;
const collection = scope[collection_key];
await collection.render_settings(env_collections_container);
}
return frag;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/node_modules/smart-settings/smart_settings.js
var SmartSettings = class {
/**
* Creates an instance of SmartEnvSettings.
* @param {Object} main - The main object to contain the instance (smart_settings) and getter (settings)
* @param {Object} [opts={}] - Configuration options.
*/
constructor(main, opts = {}) {
this.main = main;
this.opts = opts;
this._fs = null;
this._settings = {};
this._saved = false;
this.save_timeout = null;
}
static async create(main, opts = {}) {
const smart_settings = new this(main, opts);
await smart_settings.load();
main.smart_settings = smart_settings;
Object.defineProperty(main, "settings", {
get() {
return smart_settings.settings;
},
set(settings) {
smart_settings.settings = settings;
}
});
return smart_settings;
}
static create_sync(main, opts = {}) {
const smart_settings = new this(main, opts);
smart_settings.load_sync();
main.smart_settings = smart_settings;
Object.defineProperty(main, "settings", {
get() {
return smart_settings.settings;
},
set(settings) {
smart_settings.settings = settings;
}
});
return smart_settings;
}
/**
* Gets the current settings, wrapped with an observer to handle changes.
* @returns {Proxy} A proxy object that observes changes to the settings.
*/
get settings() {
return observe_object(this._settings, (property, value, target) => {
if (this.save_timeout) clearTimeout(this.save_timeout);
this.save_timeout = setTimeout(() => {
this.save(this._settings);
this.save_timeout = null;
}, 1e3);
});
}
/**
* Sets the current settings.
* @param {Object} settings - The new settings to apply.
*/
set settings(settings) {
this._settings = settings;
}
async save(settings = this._settings) {
if (typeof this.opts.save === "function") await this.opts.save(settings);
else await this.main.save_settings(settings);
}
async load() {
if (typeof this.opts.load === "function") this._settings = await this.opts.load();
else this._settings = await this.main.load_settings();
}
load_sync() {
if (typeof this.opts.load === "function") this._settings = this.opts.load();
else this._settings = this.main.load_settings();
}
};
function observe_object(obj, on_change) {
function create_proxy(target) {
return new Proxy(target, {
set(target2, property, value) {
if (target2[property] !== value) {
target2[property] = value;
on_change(property, value, target2);
}
if (typeof value === "object" && value !== null) {
target2[property] = create_proxy(value);
}
return true;
},
get(target2, property) {
const result = target2[property];
if (typeof result === "object" && result !== null) {
return create_proxy(result);
}
return result;
},
deleteProperty(target2, property) {
if (property in target2) {
delete target2[property];
on_change(property, void 0, target2);
}
return true;
}
});
}
return create_proxy(obj);
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/is_plain_object.js
function is_plain_object(o) {
if (o === null) return false;
if (typeof o !== "object") return false;
if (Array.isArray(o)) return false;
if (o instanceof Function) return false;
if (o instanceof Date) return false;
return Object.getPrototypeOf(o) === Object.prototype;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/deep_merge.js
function deep_merge(target, source) {
for (const key in source) {
if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
if (is_plain_object(source[key]) && is_plain_object(target[key])) {
deep_merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/camel_case_to_snake_case.js
function camel_case_to_snake_case(str) {
const result = str.replace(/([A-Z])/g, (match) => `_${match.toLowerCase()}`).replace(/^_/, "").replace(/2$/, "");
return result;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/normalize_opts.js
function normalize_opts(opts) {
if (!opts.collections) opts.collections = {};
if (!opts.modules) opts.modules = {};
if (!opts.items) opts.items = {};
Object.entries(opts.collections).forEach(([key, val]) => {
if (typeof val === "function") {
opts.collections[key] = { class: val };
}
const new_key = camel_case_to_snake_case(key);
if (new_key !== key) {
opts.collections[new_key] = opts.collections[key];
delete opts.collections[key];
}
if (!opts.collections[new_key].collection_key) opts.collections[new_key].collection_key = new_key;
if (val.item_type) {
opts.items[camel_case_to_snake_case(val.item_type.name)] = {
class: val.item_type
};
}
});
Object.entries(opts.modules).forEach(([key, val]) => {
if (typeof val === "function") {
opts.modules[key] = { class: val };
}
const new_key = camel_case_to_snake_case(key);
if (new_key !== key) {
opts.modules[new_key] = opts.modules[key];
delete opts.modules[key];
}
});
if (!opts.item_types) opts.item_types = {};
if (!opts.items) opts.items = {};
Object.entries(opts.item_types).forEach(([key, val]) => {
if (typeof val === "function") {
const new_key = camel_case_to_snake_case(key);
opts.items[new_key] = {
class: val,
actions: {},
...opts.items[new_key] || {}
};
}
});
return opts;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/deep_clone_config.js
function is_plain_object2(value) {
if (!value || typeof value !== "object") return false;
const proto = Object.getPrototypeOf(value);
return proto === Object.prototype || proto === null;
}
function deep_clone_config(input) {
if (Array.isArray(input)) {
return input.map((item) => deep_clone_config(item));
}
if (is_plain_object2(input)) {
const output = {};
for (const [k, v] of Object.entries(input)) {
output[k] = deep_clone_config(v);
}
return output;
}
return input;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/deep_merge_no_overwrite.js
function deep_merge_no_overwrite(target, source, path = []) {
if (!is_plain_object(target) || !is_plain_object(source)) {
return target;
}
if (path.includes(source)) {
return target;
}
path.push(source);
for (const key of Object.keys(source)) {
if (!Object.prototype.hasOwnProperty.call(source, key)) {
continue;
}
const val = source[key];
if (Array.isArray(target[key]) && Array.isArray(val)) {
target[key].push(...val);
} else if (is_plain_object(val)) {
if (!is_plain_object(target[key])) {
target[key] = {};
}
deep_merge_no_overwrite(target[key], val, [...path]);
} else if (!Object.prototype.hasOwnProperty.call(target, key)) {
target[key] = val;
}
}
return target;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/utils/merge_env_config.js
function merge_env_config(target, incoming) {
for (const [key, value] of Object.entries(incoming)) {
if (typeof value === "object" && value !== null) {
if (Array.isArray(value)) {
target[key] = [...target[key] || [], ...value];
} else {
if (!target[key]) target[key] = {};
deep_merge_no_overwrite(target[key], value);
}
} else {
if (target[key] !== void 0) {
console.warn(
`SmartEnv: Overwriting existing property ${key} in smart_env_config`,
{ old: target[key], new: value }
);
}
target[key] = value;
}
}
return target;
}
// node_modules/obsidian-smart-env/node_modules/smart-environment/smart_env.js
var SmartEnv = class {
/**
* @type {number} version - Bump this number when shipping a new version of SmartEnv.
* If a newer version is loaded into a runtime that already has an older environment,
* an automatic reload of all existing mains will occur.
*/
static version = 2.139101;
scope_name = "smart_env";
static global_ref = get_global_ref();
global_ref = this.constructor.global_ref;
constructor(opts = {}) {
this.state = "init";
this._components = {};
this.collections = {};
this.load_timeout = null;
if (opts.primary_main_key) this.primary_main_key = opts.primary_main_key;
}
/**
* Returns the config object for the SmartEnv instance.
* @returns {Object} The config object.
*/
get config() {
if (!this._config) {
this._config = {};
const sorted_configs = Object.entries(this.smart_env_configs).sort(([main_key, { main, opts }]) => {
if (!this.primary_main_key) return 0;
if (main_key === this.primary_main_key) return -1;
return 0;
});
for (const [main_key, { main, opts }] of sorted_configs) {
if (!main) {
console.warn(`SmartEnv: '${main_key}' has been unloaded, skipping inclusion in smart_env`);
delete this.smart_env_configs[main_key];
continue;
}
merge_env_config(
this._config,
deep_clone_config(
normalize_opts(opts)
)
);
}
}
return this._config;
}
get env_start_wait_time() {
if (typeof this.config.env_start_wait_time === "number") return this.config.env_start_wait_time;
return 5e3;
}
static get global_env() {
return this.global_ref.smart_env;
}
static set global_env(env) {
this.global_ref.smart_env = env;
}
static get mains() {
return Object.keys(this.global_ref.smart_env_configs || {});
}
get mains() {
return Object.keys(this.global_ref.smart_env_configs || {});
}
static get should_reload() {
if (!this.global_env) return true;
if (this.global_env.state === "loaded") return true;
if (typeof this.global_env?.constructor?.version === "undefined") return true;
if (this.global_env.constructor.version < this.version) {
console.warn(
"SmartEnv: Reloading environment because of version mismatch",
`${this.version} > ${this.global_env.constructor.version}`
);
return true;
}
return false;
}
static get smart_env_configs() {
if (!this.global_ref.smart_env_configs) this.global_ref.smart_env_configs = {};
return this.global_ref.smart_env_configs;
}
get smart_env_configs() {
if (!this.global_ref.smart_env_configs) this.global_ref.smart_env_configs = {};
return this.global_ref.smart_env_configs;
}
/**
* Waits for either a specific main to be registered in the environment,
* or (if `opts.main` is not specified) waits for environment collections to load.
* @param {object} opts
* @param {object} [opts.main] - if set, the function waits until that main is found.
* @returns {Promise} Resolves with the environment instance
*/
static wait_for(opts = {}) {
return new Promise((resolve) => {
if (opts.main) {
const interval = setInterval(() => {
if (this.global_env && this.global_env[opts.main]) {
clearInterval(interval);
resolve(this.global_env);
}
}, 1e3);
} else {
const interval = setInterval(() => {
if (this.global_env && this.global_env.state === "loaded") {
clearInterval(interval);
resolve(this.global_env);
}
}, 100);
}
});
}
/**
* Creates or updates a SmartEnv instance.
* - If a global environment exists and is an older version or lacks 'init_main', it is replaced.
* @param {Object} main - The main object to be added to the SmartEnv instance.
* @param {Object} [main_env_opts={}] - Options for configuring the SmartEnv instance.
* @returns {SmartEnv} The SmartEnv instance.
* @throws {TypeError} If an invalid main object is provided.
* @throws {Error} If there's an error creating or updating the SmartEnv instance.
*/
static async create(main, main_env_opts = null) {
if (!main || typeof main !== "object") {
throw new TypeError("SmartEnv: Invalid main object provided");
}
if (!main_env_opts) {
if (!main.smart_env_config) {
throw new Error("SmartEnv: No main_env_opts or main.smart_env_config provided");
}
main_env_opts = main.smart_env_config;
}
this.add_main(main, main_env_opts);
if (this.should_reload) {
const opts = {};
if (this.global_env && this.version > (this.global_env.constructor?.version || 0)) {
opts.primary_main_key = camel_case_to_snake_case(main.constructor.name);
}
if (this.global_env?.load_timeout) clearTimeout(this.global_env.load_timeout);
this.global_env = new this(opts);
if (!window.all_envs) window.all_envs = [];
window.all_envs.push(this.global_env);
}
clearTimeout(this.global_env.load_timeout);
this.global_env.load_timeout = setTimeout(async () => {
await this.global_env.load();
this.global_env.load_timeout = null;
}, this.global_env.env_start_wait_time);
return this.global_env;
}
static add_main(main, main_env_opts = null) {
if (this.global_env?._config) this.global_env._config = null;
const main_key = camel_case_to_snake_case(main.constructor.name);
this.smart_env_configs[main_key] = { main, opts: main_env_opts };
this.create_env_getter(main);
}
/**
* Creates a dynamic environment getter on any instance object.
* The returned 'env' property will yield the global `smart_env`.
* @param {Object} instance_to_receive_getter
*/
static create_env_getter(instance_to_receive_getter) {
Object.defineProperty(instance_to_receive_getter, "env", {
get: () => this.global_env
});
}
create_env_getter(instance_to_receive_getter) {
this.constructor.create_env_getter(instance_to_receive_getter);
}
async load() {
await this.fs.load_files();
if (!this.settings) await SmartSettings.create(this);
await this.init_collections();
for (const [main_key, { main, opts }] of Object.entries(this.smart_env_configs)) {
this[main_key] = main;
await this.ready_to_load_collections(main);
}
await this.load_collections();
this.state = "loaded";
}
/**
* Initializes collection classes if they have an 'init' function.
* @param {Object} [config=this.config]
*/
async init_collections(config = this.config) {
for (const key of Object.keys(config.collections || {})) {
const _class = config.collections[key]?.class;
if (!_class) continue;
if (_class.default_settings) {
deep_merge_no_overwrite(
this.settings,
{
[key]: _class.default_settings
}
);
}
if (typeof _class.init !== "function") continue;
await _class.init(this, { ...config.collections[key] });
this.collections[key] = "init";
}
}
/**
* Hook for main classes that optionally implement `ready_to_load_collections()`.
* @param {Object} main
*/
async ready_to_load_collections(main) {
if (typeof main?.ready_to_load_collections === "function") {
await main.ready_to_load_collections();
}
return true;
}
/**
* Loads any available collections, processing their load queues.
* @param {Object} [collections=this.collections] - Key-value map of collection instances.
*/
async load_collections(collections = this.collections) {
for (const key of Object.keys(collections || {})) {
if (typeof this[key]?.process_load_queue === "function") {
if (this.state === "init" && this[key].opts?.prevent_load_on_init === true) continue;
await this[key].process_load_queue();
}
this.collections[key] = "loaded";
}
}
/**
* Removes a main from the window.smart_env_configs to exclude it on reload
* @param {Class} main
* @param {Object|null} [unload_config=null]
*/
static unload_main(main) {
const main_key = camel_case_to_snake_case(main.constructor.name);
this.smart_env_configs[main_key] = null;
delete this.smart_env_configs[main_key];
}
unload_main(main) {
this.constructor.unload_main(main);
}
/**
* Triggers a save event in all known collections.
*/
save() {
for (const key of Object.keys(this.collections)) {
this[key].process_save_queue?.();
}
}
/**
* Initialize a module from the configured `this.opts.modules`.
* @param {string} module_key
* @param {object} opts
* @returns {object|null} instance of the requested module or null if not found
*/
init_module(module_key, opts = {}) {
const module_config = this.opts.modules[module_key];
if (!module_config) {
return console.warn(`SmartEnv: module ${module_key} not found`);
}
opts = {
...{ ...module_config, class: null },
...opts
};
return new module_config.class(opts);
}
get notices() {
if (!this._notices) {
const SmartNoticesClass = this.config.modules.smart_notices.class;
this._notices = new SmartNoticesClass(this, {
adapter: this.config.modules.smart_notices.adapter
});
}
return this._notices;
}
/**
* Exposes a settings template function from environment opts or defaults.
* @returns {Function}
*/
get settings_template() {
return this.opts.components?.smart_env?.settings || render;
}
/**
* Renders settings UI into a container, using the environment's `settings_template`.
* @param {HTMLElement} [container=this.settings_container]
*/
async render_settings(container = this.settings_container) {
if (!this.settings_container || container !== this.settings_container) {
this.settings_container = container;
}
if (!container) {
throw new Error("Container is required");
}
const frag = await this.render_component("settings", this, {});
container.innerHTML = "";
container.appendChild(frag);
return frag;
}
/**
* Renders a named component using an optional scope and options.
* @param {string} component_key
* @param {Object} scope
* @param {Object} [opts]
* @returns {Promise}
*/
async render_component(component_key, scope, opts = {}) {
const component_renderer = this.get_component(component_key, scope);
if (!component_renderer) {
console.warn(`SmartEnv: component ${component_key} not found for scope ${scope.constructor.name}`);
return this.smart_view.create_doc_fragment(`
Component Not Found
The component ${component_key} was not found for scope ${scope.constructor.name}.
`);
}
const frag = await component_renderer(scope, opts);
return frag;
}
/**
* Retrieves or creates a memoized component renderer function.
* @param {string} component_key
* @param {Object} scope
* @returns {Function|undefined}
*/
get_component(component_key, scope) {
const scope_name = scope.collection_key ?? scope.scope_name;
const _cache_key = scope_name ? `${scope_name}-${component_key}` : component_key;
if (!this._components[_cache_key]) {
try {
if (this.opts.components[scope_name]?.[component_key]) {
this._components[_cache_key] = this.opts.components[scope_name][component_key].bind(
this.init_module("smart_view")
);
} else if (this.opts.components[component_key]) {
this._components[_cache_key] = this.opts.components[component_key].bind(
this.init_module("smart_view")
);
} else {
console.warn(
`SmartEnv: component ${component_key} not found for scope ${scope_name}`
);
}
} catch (e) {
console.error("Error getting component", e);
console.log(
`scope_name: ${scope_name}; component_key: ${component_key}; this.opts.components: ${Object.keys(
this.opts.components || {}
).join(", ")}; this.opts.components[scope_name]: ${Object.keys(
this.opts.components[scope_name] || {}
).join(", ")}`
);
}
}
return this._components[_cache_key];
}
/**
* Lazily instantiate the module 'smart_view'.
* @returns {object}
*/
get smart_view() {
if (!this._smart_view) {
this._smart_view = this.init_module("smart_view");
}
return this._smart_view;
}
/**
* A built-in settings schema for this environment.
* @returns {Object}
*/
get settings_config() {
return {
is_obsidian_vault: {
name: "Obsidian Vault",
description: "Toggle on if this is an Obsidian vault.",
type: "toggle",
default: false
},
file_exclusions: {
name: "File Exclusions",
description: "Comma-separated list of files to exclude.",
type: "text",
default: "",
callback: "update_exclusions"
},
folder_exclusions: {
name: "Folder Exclusions",
description: "Comma-separated list of folders to exclude.",
type: "text",
default: "",
callback: "update_exclusions"
},
excluded_headings: {
name: "Excluded Headings",
description: "Comma-separated list of headings to exclude.",
type: "text",
default: ""
}
};
}
get global_prop() {
return this.opts.global_prop ?? "smart_env";
}
get item_types() {
return this.opts.item_types;
}
get fs_module_config() {
return this.opts.modules.smart_fs;
}
get fs() {
if (!this.smart_fs) {
this.smart_fs = new this.fs_module_config.class(this, {
adapter: this.fs_module_config.adapter,
fs_path: this.opts.env_path || ""
});
}
return this.smart_fs;
}
get env_data_dir() {
const env_settings_files = this.fs.file_paths?.filter((path) => path.endsWith("smart_env.json")) || [];
let env_data_dir = ".smart-env";
if (env_settings_files.length > 0) {
if (env_settings_files.length > 1) {
const env_data_dir_counts = env_settings_files.map((path) => {
const dir = path.split("/").slice(-2, -1)[0];
return {
dir,
count: this.fs.file_paths.filter((p) => p.includes(dir)).length
};
});
env_data_dir = env_data_dir_counts.reduce(
(max, dirObj) => dirObj.count > max.count ? dirObj : max,
env_data_dir_counts[0]
).dir;
} else {
env_data_dir = env_settings_files[0].split("/").slice(-2, -1)[0];
}
}
return env_data_dir;
}
get data_fs() {
if (!this._fs) {
this._fs = new this.fs_module_config.class(this, {
adapter: this.fs_module_config.adapter,
fs_path: this.data_fs_path
});
}
return this._fs;
}
get data_fs_path() {
if (!this._data_fs_path) {
this._data_fs_path = (this.opts.env_path + (this.opts.env_path ? this.opts.env_path.includes("\\") ? "\\" : "/" : "") + this.env_data_dir).replace(/\\\\/g, "\\").replace(/\/\//g, "/");
}
return this._data_fs_path;
}
/**
* Saves the current settings to the file system.
* @param {Object|null} [settings=null] - Optional settings to override the current settings before saving.
* @returns {Promise}
*/
async save_settings(settings) {
this._saved = false;
if (!await this.data_fs.exists("")) {
await this.data_fs.mkdir("");
}
await this.data_fs.write("smart_env.json", JSON.stringify(settings, null, 2));
this._saved = true;
}
/**
* Loads settings from the file system, merging with any `default_settings` or `smart_env_settings`.
* @returns {Promise