( baseUrl: string, accessToken: string, folderPath?: string, retryOptions?: Parameters<typeof secureFetchWithRetry>[2], depth = 0 )
| 83 | const MAX_RECURSION_DEPTH = 20 |
| 84 | |
| 85 | async function listVaultFiles( |
| 86 | baseUrl: string, |
| 87 | accessToken: string, |
| 88 | folderPath?: string, |
| 89 | retryOptions?: Parameters<typeof secureFetchWithRetry>[2], |
| 90 | depth = 0 |
| 91 | ): Promise<string[]> { |
| 92 | if (depth > MAX_RECURSION_DEPTH) { |
| 93 | logger.warn('Max directory depth reached, skipping further recursion', { folderPath }) |
| 94 | return [] |
| 95 | } |
| 96 | |
| 97 | const rootPath = folderPath || '' |
| 98 | const entries = await listDirectory(baseUrl, accessToken, rootPath, retryOptions) |
| 99 | |
| 100 | const mdFiles: string[] = [] |
| 101 | const subDirs: string[] = [] |
| 102 | |
| 103 | for (const entry of entries) { |
| 104 | if (entry.endsWith('/')) { |
| 105 | const fullDir = rootPath ? `${rootPath}/${entry.slice(0, -1)}` : entry.slice(0, -1) |
| 106 | subDirs.push(fullDir) |
| 107 | } else if (entry.endsWith('.md')) { |
| 108 | const fullPath = rootPath ? `${rootPath}/${entry}` : entry |
| 109 | mdFiles.push(fullPath) |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | for (const dir of subDirs) { |
| 114 | try { |
| 115 | const nested = await listVaultFiles(baseUrl, accessToken, dir, retryOptions, depth + 1) |
| 116 | mdFiles.push(...nested) |
| 117 | } catch (error) { |
| 118 | logger.warn('Failed to list subdirectory', { |
| 119 | dir, |
| 120 | error: toError(error).message, |
| 121 | }) |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | return mdFiles |
| 126 | } |
| 127 | |
| 128 | /** |
| 129 | * Fetches a single note as structured JSON with content, frontmatter, stats, and tags. |
no test coverage detected