mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
fix(obsidian): implement recursive directory scanning for nested folders
The Obsidian Local REST API /vault/ endpoint returns folder entries with
trailing slashes (e.g., "01 Projects/"). The previous code filtered these
out, only keeping .md files, which meant nested files were never discovered.
Changes:
- Add scanDirectory() function to recursively scan folders
- Detect folders by trailing "/" character
- Recursively query each folder with /vault/{foldername}/
- Build full paths as we traverse (e.g., "State/Province/City.md")
- Remove search endpoint attempt (not needed)
- Add timing logs to measure performance
This now correctly discovers ALL markdown files in the vault, regardless
of how deeply nested they are in folders.
Fixes nested folder display issue.
This commit is contained in:
parent
3d30e2481e
commit
996b653421
1 changed files with 40 additions and 49 deletions
|
|
@ -61,6 +61,39 @@ const ObsidianBridge = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively scan a directory and all subdirectories for .md files
|
||||||
|
async function scanDirectory(path = "") {
|
||||||
|
const response = await fetch(`${config.apiUrl}/vault/${encodeURIComponent(path)}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${config.apiKey}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to fetch directory ${path}: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
const entries = data.files || [];
|
||||||
|
const mdFiles = [];
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const fullPath = path ? `${path}${entry}` : entry;
|
||||||
|
|
||||||
|
if (entry.endsWith("/")) {
|
||||||
|
// It's a directory - recurse into it
|
||||||
|
DEBUG && console.log(`Scanning directory: ${fullPath}`);
|
||||||
|
const subFiles = await scanDirectory(fullPath);
|
||||||
|
mdFiles.push(...subFiles);
|
||||||
|
} else if (entry.endsWith(".md")) {
|
||||||
|
// It's a markdown file - add it
|
||||||
|
mdFiles.push(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mdFiles;
|
||||||
|
}
|
||||||
|
|
||||||
// Get all markdown files from vault (recursively)
|
// Get all markdown files from vault (recursively)
|
||||||
async function getVaultFiles() {
|
async function getVaultFiles() {
|
||||||
if (!config.enabled) {
|
if (!config.enabled) {
|
||||||
|
|
@ -68,62 +101,20 @@ const ObsidianBridge = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try using the search endpoint to get all .md files recursively
|
TIME && console.time("getVaultFiles");
|
||||||
// The /search/ endpoint with an empty query or wildcard should return all files
|
|
||||||
const searchResponse = await fetch(`${config.apiUrl}/search/?query=.md`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${config.apiKey}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (searchResponse.ok) {
|
// Recursively scan all directories
|
||||||
const searchData = await searchResponse.json();
|
const mdFiles = await scanDirectory("");
|
||||||
INFO && console.log("Using search endpoint, found:", searchData);
|
|
||||||
|
|
||||||
// Extract file paths from search results
|
INFO && console.log(`getVaultFiles: Found ${mdFiles.length} markdown files (recursive scan)`);
|
||||||
// The format might be different, check what we get
|
|
||||||
const files = searchData.files || searchData.results || searchData;
|
|
||||||
|
|
||||||
if (Array.isArray(files)) {
|
|
||||||
const mdFiles = files
|
|
||||||
.filter(f => {
|
|
||||||
const path = typeof f === 'string' ? f : f.path || f.filename;
|
|
||||||
return path && path.endsWith(".md");
|
|
||||||
})
|
|
||||||
.map(f => typeof f === 'string' ? f : f.path || f.filename);
|
|
||||||
|
|
||||||
INFO && console.log(`getVaultFiles (search): Found ${mdFiles.length} markdown files`);
|
|
||||||
DEBUG && console.log("Sample files:", mdFiles.slice(0, 10));
|
|
||||||
|
|
||||||
return mdFiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to /vault/ endpoint if search doesn't work
|
|
||||||
INFO && console.log("Search endpoint failed, falling back to /vault/");
|
|
||||||
const response = await fetch(`${config.apiUrl}/vault/`, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${config.apiKey}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to fetch vault files: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
const files = data.files || [];
|
|
||||||
|
|
||||||
// Filter to only .md files
|
|
||||||
const mdFiles = files.filter(f => f.endsWith(".md"));
|
|
||||||
|
|
||||||
INFO && console.log(`getVaultFiles (vault): Found ${files.length} total files, ${mdFiles.length} markdown files`);
|
|
||||||
DEBUG && console.log("Sample files:", mdFiles.slice(0, 10));
|
DEBUG && console.log("Sample files:", mdFiles.slice(0, 10));
|
||||||
WARN && console.warn("Note: /vault/ endpoint may only return root-level files. Nested folders may not be visible.");
|
|
||||||
|
TIME && console.timeEnd("getVaultFiles");
|
||||||
|
|
||||||
return mdFiles;
|
return mdFiles;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ERROR && console.error("Failed to get vault files:", error);
|
ERROR && console.error("Failed to get vault files:", error);
|
||||||
|
TIME && console.timeEnd("getVaultFiles");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue