// src/plugin/files/folder.ts import { TAbstractFile } from './abstract-file' /** * Represents a folder in the vault. */ export class TFolder extends TAbstractFile { /** Child files and folders */ children: TAbstractFile[] = [] /** * Whether this folder is the root folder. * Set during construction based on name='' and parent=null. * Using a flag avoids stringly-typed checks in isRoot(). * Uses ES private field to avoid leaking into .d.ts. */ readonly #isRoot: boolean /** * @internal * Constructor is not part of the public API. Use Vault methods to create folders. */ protected constructor(name: string, parent: TFolder | null) { super(name, parent) // The root folder is the one with empty name AND no parent. // This flag is set once at construction and never changes. this.#isRoot = name === '' && parent === null } /** Returns true if this is the root folder */ isRoot(): boolean { return this.#isRoot } } /** * Internal subclass to access protected constructor. * Hoisted outside the factory to avoid recreation on every call. * @internal */ class TFolderFactory extends TFolder { constructor(name: string, parent: TFolder | null) { super(name, parent) } } /** * Internal factory function to create TFolder instances. * This is NOT part of the public Obsidian API. Use Vault.createFolder() for plugin code. * * Exists to allow internal Reams code (services, tests) to create TFolder instances * while keeping the constructor protected to match Obsidian's public API contract. * * @internal - Not exported from the 'obsidian' module. */ export function createTFolder(name: string, parent: TFolder | null): TFolder { // TFolderFactory extends TFolder, so instanceof TFolder will work. // We don't use Object.setPrototypeOf because it breaks ES private field access. return new TFolderFactory(name, parent) }