(input: string, options: { rejectHiddenSegments?: boolean } = {})
| 48 | } |
| 49 | |
| 50 | export function normalizeMarkdownRelPath(input: string, options: { rejectHiddenSegments?: boolean } = {}): string | null { |
| 51 | const trimmed = input.trim(); |
| 52 | if (!trimmed || trimmed.includes('\0') || path.isAbsolute(trimmed)) return null; |
| 53 | |
| 54 | const parts = trimmed.split(/[\\/]+/).map((part) => part.trim()).filter(Boolean); |
| 55 | if (parts.length === 0) return null; |
| 56 | if (parts.some((part) => part === '.' || part === '..' || part.startsWith('.'))) return null; |
| 57 | if (options.rejectHiddenSegments && parts.some((part) => part.startsWith('_'))) return null; |
| 58 | |
| 59 | const last = parts[parts.length - 1]; |
| 60 | if (!/\.(md|markdown)$/i.test(last)) parts[parts.length - 1] = `${last}.md`; |
| 61 | return parts.join('/'); |
| 62 | } |
| 63 | |
| 64 | export function resolveMarkdownPath(rootDir: string, target: string): string | null { |
| 65 | const root = path.resolve(rootDir); |
no outgoing calls
no test coverage detected