| import { accessSync, constants } from "node:fs"; |
| import { access } from "node:fs/promises"; |
| import { normalizePath, resolvePath } from "../../utils/paths.ts"; |
|
|
| const NARROW_NO_BREAK_SPACE = "\u202F"; |
|
|
| function tryMacOSScreenshotPath(filePath: string): string { |
| return filePath.replace(/ (AM|PM)\./gi, `${NARROW_NO_BREAK_SPACE}$1.`); |
| } |
|
|
| function tryNFDVariant(filePath: string): string { |
| |
| return filePath.normalize("NFD"); |
| } |
|
|
| function tryCurlyQuoteVariant(filePath: string): string { |
| |
| |
| return filePath.replace(/'/g, "\u2019"); |
| } |
|
|
| function fileExists(filePath: string): boolean { |
| try { |
| accessSync(filePath, constants.F_OK); |
| return true; |
| } catch { |
| return false; |
| } |
| } |
|
|
| export async function pathExists(filePath: string): Promise<boolean> { |
| try { |
| await access(filePath, constants.F_OK); |
| return true; |
| } catch { |
| return false; |
| } |
| } |
|
|
| export function expandPath(filePath: string): string { |
| return normalizePath(filePath, { normalizeUnicodeSpaces: true, stripAtPrefix: true }); |
| } |
|
|
| |
| |
| |
| |
| export function resolveToCwd(filePath: string, cwd: string): string { |
| return resolvePath(filePath, cwd, { normalizeUnicodeSpaces: true, stripAtPrefix: true }); |
| } |
|
|
| export function resolveReadPath(filePath: string, cwd: string): string { |
| const resolved = resolveToCwd(filePath, cwd); |
|
|
| if (fileExists(resolved)) { |
| return resolved; |
| } |
|
|
| |
| const amPmVariant = tryMacOSScreenshotPath(resolved); |
| if (amPmVariant !== resolved && fileExists(amPmVariant)) { |
| return amPmVariant; |
| } |
|
|
| |
| const nfdVariant = tryNFDVariant(resolved); |
| if (nfdVariant !== resolved && fileExists(nfdVariant)) { |
| return nfdVariant; |
| } |
|
|
| |
| const curlyVariant = tryCurlyQuoteVariant(resolved); |
| if (curlyVariant !== resolved && fileExists(curlyVariant)) { |
| return curlyVariant; |
| } |
|
|
| |
| const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant); |
| if (nfdCurlyVariant !== resolved && fileExists(nfdCurlyVariant)) { |
| return nfdCurlyVariant; |
| } |
|
|
| return resolved; |
| } |
|
|
| export async function resolveReadPathAsync(filePath: string, cwd: string): Promise<string> { |
| const resolved = resolveToCwd(filePath, cwd); |
|
|
| if (await pathExists(resolved)) { |
| return resolved; |
| } |
|
|
| |
| const amPmVariant = tryMacOSScreenshotPath(resolved); |
| if (amPmVariant !== resolved && (await pathExists(amPmVariant))) { |
| return amPmVariant; |
| } |
|
|
| |
| const nfdVariant = tryNFDVariant(resolved); |
| if (nfdVariant !== resolved && (await pathExists(nfdVariant))) { |
| return nfdVariant; |
| } |
|
|
| |
| const curlyVariant = tryCurlyQuoteVariant(resolved); |
| if (curlyVariant !== resolved && (await pathExists(curlyVariant))) { |
| return curlyVariant; |
| } |
|
|
| |
| const nfdCurlyVariant = tryCurlyQuoteVariant(nfdVariant); |
| if (nfdCurlyVariant !== resolved && (await pathExists(nfdCurlyVariant))) { |
| return nfdCurlyVariant; |
| } |
|
|
| return resolved; |
| } |
|
|