refactor: switch to factory style and merge PR #324 getEnabledFolderNote + version

This commit is contained in:
Moy 2026-07-03 19:21:45 +08:00
parent 8ab19c0083
commit e7c7019d20
2 changed files with 77 additions and 30 deletions

View file

@ -1,12 +1,45 @@
import { TFile, TFolder } from 'obsidian';
import type FolderNotesPlugin from './main';
import { getFolderNote, turnIntoFolderNote } from './functions/folderNoteFunctions';
import { getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions';
const API_VERSION = '1.0.0';
export interface ConvertNoteToFolderNoteOptions {
skipConfirmation?: boolean;
}
/**
* Public API exposed by the folder-notes plugin on its instance as `plugin.api`.
*
* External plugins can access it via:
* app.plugins.plugins['folder-notes']?.api
*
* The API is available after folder-notes has finished onload (settings loaded).
*/
export interface FolderNotesApi {
/** Semver-ish version string for feature detection. */
version: string;
/**
* Returns the folder note TFile for the given folder path only if the
* folder's note is enabled i.e., the folder is not detached and not
* excluded with `disableFolderNote`. Matches the plugin's own UI
* gating (the rules that decide whether `.has-folder-note` gets
* applied in the file explorer).
*
* Returns null if:
* - the folder does not exist or has no folder note
* - the folder is detached
* - the folder is excluded with disableFolderNote
*/
getEnabledFolderNote(folderPath: string): TFile | null;
/**
* Converts an existing note into the folder note for its parent folder.
* Throws FolderNotesApiPathError if the path does not point to a note
* inside a non-root folder.
*/
convertNoteToFolderNote(notePath: string, options?: ConvertNoteToFolderNoteOptions): Promise<void>;
}
@ -20,32 +53,46 @@ export class FolderNotesApiPathError extends Error {
}
}
export class FolderNotesPublicApi implements FolderNotesApi {
constructor(private readonly plugin: FolderNotesPlugin) {}
async convertNoteToFolderNote(
notePath: string,
options: ConvertNoteToFolderNoteOptions = {},
): Promise<void> {
const file = this.plugin.app.vault.getAbstractFileByPath(notePath);
if (!(file instanceof TFile)) {
throw new FolderNotesApiPathError(`No note exists at path: ${notePath}`, notePath);
}
const folder = file.parent;
if (!(folder instanceof TFolder) || folder.path === '' || folder.path === '/') {
throw new FolderNotesApiPathError(`Note must be inside a folder: ${notePath}`, notePath);
}
const folderNote = getFolderNote(this.plugin, folder.path);
if (folderNote === file) return;
await turnIntoFolderNote(
this.plugin,
file,
folder,
folderNote,
options.skipConfirmation ?? true,
);
}
export function getApi(plugin: FolderNotesPlugin): FolderNotesApi {
return {
version: API_VERSION,
getEnabledFolderNote: (folderPath) => getEnabledFolderNote(plugin, folderPath),
convertNoteToFolderNote: (notePath, options) => convertNoteToFolderNote(plugin, notePath, options),
};
}
function getEnabledFolderNote(plugin: FolderNotesPlugin, folderPath: string): TFile | null {
const note = getFolderNote(plugin, folderPath);
if (!note) return null;
if (getDetachedFolder(plugin, folderPath)) return null;
const excluded = getExcludedFolder(plugin, folderPath, true);
if (excluded?.disableFolderNote) return null;
return note;
}
async function convertNoteToFolderNote(
plugin: FolderNotesPlugin,
notePath: string,
options: ConvertNoteToFolderNoteOptions = {},
): Promise<void> {
const file = plugin.app.vault.getAbstractFileByPath(notePath);
if (!(file instanceof TFile)) {
throw new FolderNotesApiPathError(`No note exists at path: ${notePath}`, notePath);
}
const folder = file.parent;
if (!(folder instanceof TFolder) || folder.path === '' || folder.path === '/') {
throw new FolderNotesApiPathError(`Note must be inside a folder: ${notePath}`, notePath);
}
const folderNote = getFolderNote(plugin, folder.path);
if (folderNote === file) return;
await turnIntoFolderNote(
plugin,
file,
folder,
folderNote,
options.skipConfirmation ?? true,
);
}

View file

@ -36,7 +36,7 @@ import { registerOverviewCommands } from './obsidian-folder-overview/src/Command
import { updateOverviewView, updateViewDropdown } from './obsidian-folder-overview/src/main';
import { FvIndexDB } from './obsidian-folder-overview/src/utils/IndexDB';
import { updateAllOverviews } from './obsidian-folder-overview/src/utils/functions';
import { FolderNotesPublicApi, type FolderNotesApi } from './api';
import { getApi, type FolderNotesApi } from './api';
interface FileExplorerPluginLike extends Plugin {
revealInFolder: (file: TAbstractFile) => void;
@ -97,7 +97,7 @@ export default class FolderNotesPlugin extends Plugin {
this.settingsTab = new SettingsTab(this.app, this);
this.addSettingTab(this.settingsTab);
await this.saveSettings();
this.api = new FolderNotesPublicApi(this);
this.api = getApi(this);
this.fvIndexDB = new FvIndexDB(this);
// Add CSS Classes