(
path: string | undefined,
options: ResolveDeepnoteFileOptions = {}
)
| 83 | * @throws FileResolutionError if no .deepnote file found or file is invalid |
| 84 | */ |
| 85 | export async function resolvePathToDeepnoteFile( |
| 86 | path: string | undefined, |
| 87 | options: ResolveDeepnoteFileOptions = {} |
| 88 | ): Promise<ResolvedFile> { |
| 89 | // If no path provided, search current directory |
| 90 | if (!path) { |
| 91 | debug('No path provided, searching current directory for .deepnote files') |
| 92 | return findDeepnoteFileInDirectory(process.cwd(), options) |
| 93 | } |
| 94 | |
| 95 | const absolutePath = resolve(process.cwd(), path) |
| 96 | debug(`Resolved path: ${absolutePath}`) |
| 97 | |
| 98 | const fileStat = await stat(absolutePath).catch((err: unknown) => { |
| 99 | const code = (err as NodeJS.ErrnoException | undefined)?.code |
| 100 | // Only treat ENOENT/ENOTDIR as "not found", rethrow other errors (permission denied, I/O failures) |
| 101 | if (code === 'ENOENT' || code === 'ENOTDIR') return null |
| 102 | throw err |
| 103 | }) |
| 104 | if (!fileStat) { |
| 105 | const suggestion = await suggestSimilarFiles(path) |
| 106 | throw new FileResolutionError(`File not found: ${absolutePath}${suggestion}`) |
| 107 | } |
| 108 | |
| 109 | // If it's a directory, find first .deepnote file in it |
| 110 | if (fileStat.isDirectory()) { |
| 111 | debug(`Path is a directory, searching for .deepnote files in: ${absolutePath}`) |
| 112 | return findDeepnoteFileInDirectory(absolutePath, options) |
| 113 | } |
| 114 | |
| 115 | const ext = extname(absolutePath).toLowerCase() |
| 116 | if (ext !== '.deepnote') { |
| 117 | const hint = getSupportedFileHint(ext) |
| 118 | throw new FileResolutionError(`Unsupported file type: ${ext || '(no extension)'}\n\n${hint}`) |
| 119 | } |
| 120 | |
| 121 | return { absolutePath } |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * Find the first .deepnote file in a directory (sorted alphabetically). |
no test coverage detected