UNPKG

@synstack/path

Version:
1 lines 11.1 kB
{"version":3,"sources":["../src/path.index.ts","../src/path.bundle.ts","../src/path.lib.ts"],"sourcesContent":["export * as path from \"./path.bundle.ts\";\nexport * from \"./path.lib.ts\";\n","export {\n addMissingExtension,\n dirname,\n ensureFileExtension,\n fileExtension,\n filename,\n filenameWithoutExtension,\n importUrlToAbsolutePath,\n isAbsolute,\n isInPath,\n join,\n mimeType,\n relative,\n removeRelativeIndicator,\n resolve,\n} from \"./path.lib.ts\";\n","import mime from \"mime-types\";\nimport * as fsPath from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Type representing an absolute file system path.\n * Used for type safety when working with paths.\n */\nexport type AbsolutePath = string & { ABSOLUTE_PATH: true };\n\n/**\n * Type representing a relative file system path.\n * Used for type safety when working with paths.\n */\nexport type RelativePath = string & { RELATIVE_PATH: true };\n\n/**\n * Type representing any kind of file system path (absolute or relative).\n */\nexport type AnyPath = string;\n\n/**\n * Exception thrown when a path operation is attempted outside the current working directory.\n */\nexport class PathNotInCwdException extends Error {\n constructor(path: string, cwd: string) {\n super(`Path ${path} is not in cwd ${cwd}`);\n }\n}\n\n/**\n * Resolves a sequence of paths or path segments into an absolute path.\n *\n * @param paths - One or more path segments to resolve\n * @returns An absolute path string\n *\n * ```typescript\n * const absolutePath = resolve(\"/base\", \"subdir\", \"file.txt\");\n * console.log(absolutePath); // \"/base/subdir/file.txt\"\n * ```\n */\nexport function resolve(...paths: Array<AnyPath>) {\n return fsPath.resolve(...paths) as AbsolutePath;\n}\n\n/**\n * Determines if the given path is absolute.\n *\n * @param path - The path to check\n * @returns True if the path is absolute, false otherwise\n *\n * ```typescript\n * console.log(isAbsolute(\"/absolute/path\")); // true\n * console.log(isAbsolute(\"relative/path\")); // false\n * ```\n */\nexport function isAbsolute(path: AnyPath): path is AbsolutePath {\n return fsPath.isAbsolute(path);\n}\n\n/**\n * Returns the directory name of a path.\n * The result is always an absolute path.\n *\n * @param path - The path to get the directory name from\n * @returns The absolute path of the directory containing the path\n *\n * ```typescript\n * const dir = dirname(\"/path/to/file.txt\");\n * console.log(dir); // \"/path/to\"\n * ```\n */\nexport function dirname(path: AnyPath): AbsolutePath {\n return fsPath.dirname(resolve(path)) as AbsolutePath;\n}\n\n/**\n * Checks if a path is contained within a base path.\n *\n * @param basePath - The base path to check against\n * @param path - The path to check\n * @returns True if the path is within the base path, false otherwise\n *\n * ```typescript\n * console.log(isInPath(\"/base\", \"/base/subdir\")); // true\n * console.log(isInPath(\"/base\", \"/other\")); // false\n * ```\n */\nexport function isInPath(basePath: AnyPath, path: AnyPath): boolean {\n const resolvedBasePath = resolve(basePath);\n const resolvedPath = resolve(path);\n return resolvedPath.startsWith(resolvedBasePath);\n}\n\n/**\n * Creates a relative path from one location to another.\n *\n * @param basePath - The base path to create the relative path from\n * @param path - The target path to create the relative path to\n * @returns A relative path from basePath to path\n *\n * ```typescript\n * const rel = relative(\"/base/dir\", \"/base/dir/subdir/file.txt\");\n * console.log(rel); // \"subdir/file.txt\"\n * ```\n */\nexport function relative(basePath: AnyPath, path: AnyPath): RelativePath {\n return removeRelativeIndicator(\n fsPath.relative(basePath, path),\n ) as RelativePath;\n}\n\n/**\n * Adds a file extension to a path if it's not already present.\n *\n * @param path - The path to add the extension to\n * @param ext - The extension to add (without the leading dot)\n * @returns The path with the extension added\n *\n * ```typescript\n * const withExt = addMissingExtension(\"/path/to/file\", \"txt\");\n * console.log(withExt); // \"/path/to/file.txt\"\n *\n * const alreadyHasExt = addMissingExtension(\"/path/to/file.txt\", \"txt\");\n * console.log(alreadyHasExt); // \"/path/to/file.txt\"\n * ```\n */\nexport function addMissingExtension(\n path: AbsolutePath,\n ext: string,\n): AbsolutePath;\nexport function addMissingExtension(\n path: RelativePath,\n ext: string,\n): RelativePath;\nexport function addMissingExtension(path: AnyPath, ext: string) {\n return path.endsWith(ext) ? path : `${path}.${ext}`;\n}\n\n/**\n * Joins path segments together.\n * The type of the first argument determines the type of the result.\n *\n * @param cwd - The base path (determines return type)\n * @param paths - Additional path segments to join\n * @returns The joined path\n *\n * ```typescript\n * const abs = join(\"/absolute\", \"path\", \"file.txt\");\n * console.log(abs); // \"/absolute/path/file.txt\"\n *\n * const rel = join(\"relative\", \"path\", \"file.txt\");\n * console.log(rel); // \"relative/path/file.txt\"\n * ```\n */\nexport function join(cwd: AbsolutePath, ...paths: Array<AnyPath>): AbsolutePath;\nexport function join(cwd: RelativePath, ...paths: Array<AnyPath>): RelativePath;\nexport function join(...paths: Array<AnyPath>): AnyPath;\nexport function join(cwd: AnyPath, ...paths: Array<AnyPath>): AnyPath {\n return fsPath.join(cwd, ...paths);\n}\n\n/**\n * Removes the leading \"./\" from a path if present.\n * Preserves the path type (absolute or relative).\n *\n * @param path - The path to process\n * @returns The path without the leading \"./\"\n *\n * ```typescript\n * console.log(removeRelativeIndicator(\"./file.txt\")); // \"file.txt\"\n * console.log(removeRelativeIndicator(\"file.txt\")); // \"file.txt\"\n * ```\n */\nexport function removeRelativeIndicator(path: AbsolutePath): AbsolutePath;\nexport function removeRelativeIndicator(path: RelativePath): RelativePath;\nexport function removeRelativeIndicator(path: AnyPath): AnyPath;\nexport function removeRelativeIndicator(path: AnyPath): AnyPath {\n return path.replace(/^\\.\\//, \"\");\n}\n\n/**\n * Ensures a file path has a specific extension.\n * If the path already ends with the extension, it is returned unchanged.\n *\n * @param filePath - The file path to process\n * @param extension - The extension to ensure (including the dot)\n * @returns The path with the specified extension\n *\n * ```typescript\n * const path = ensureFileExtension(\"/path/to/file\", \".txt\");\n * console.log(path); // \"/path/to/file.txt\"\n * ```\n */\nexport function ensureFileExtension(\n filePath: AbsolutePath,\n extension: string,\n): AbsolutePath;\nexport function ensureFileExtension(\n filePath: RelativePath,\n extension: string,\n): RelativePath;\nexport function ensureFileExtension(\n filePath: AnyPath,\n extension: string,\n): AnyPath;\nexport function ensureFileExtension(filePath: AnyPath, extension: string) {\n const normalizedExt = extension.startsWith(\".\")\n ? extension\n : `.${extension}`;\n if (filePath.endsWith(normalizedExt)) return filePath;\n return `${filePath}${normalizedExt}`;\n}\n\n/**\n * Converts an import URL to an absolute file system path.\n * Useful when working with ES modules and import.meta.url.\n *\n * @param importUrl - The import URL to convert\n * @returns The absolute path corresponding to the import URL\n *\n * ```typescript\n * const path = importUrlToAbsolutePath(import.meta.url);\n * console.log(path); // \"/absolute/path/to/current/file\"\n * ```\n */\nexport const importUrlToAbsolutePath = (importUrl: string): AbsolutePath => {\n return fsPath.dirname(fileURLToPath(importUrl)) as AbsolutePath;\n};\n\n/**\n * Gets the filename with extension from a path.\n *\n * @param path - The path to extract the filename from\n * @returns The filename with extension\n *\n * ```typescript\n * console.log(filename(\"/path/to/file.txt\")); // \"file.txt\"\n * ```\n */\nexport const filename = (path: AnyPath): string => {\n return fsPath.parse(path).base;\n};\n\n/**\n * Gets the filename without extension from a path.\n *\n * @param path - The path to extract the filename from\n * @returns The filename without extension\n *\n * ```typescript\n * console.log(filenameWithoutExtension(\"/path/to/file.txt\")); // \"file\"\n * ```\n */\nexport const filenameWithoutExtension = (path: AnyPath): string => {\n return fsPath.parse(path).name;\n};\n\n/**\n * Gets the file extension from a path.\n *\n * @param path - The path to extract the extension from\n * @returns The file extension (including the dot)\n *\n * ```typescript\n * console.log(fileExtension(\"/path/to/file.txt\")); // \".txt\"\n * ```\n */\nexport const fileExtension = (path: AnyPath): string => {\n return fsPath.parse(path).ext;\n};\n\n/**\n * Gets the MIME type for a file based on its extension.\n *\n * @param path - The path to get the MIME type for\n * @returns The MIME type string or null if it cannot be determined\n *\n * ```typescript\n * console.log(mimeType(\"/path/to/image.png\")); // \"image/png\"\n * console.log(mimeType(\"/path/to/unknown\")); // null\n * ```\n */\nexport const mimeType = (path: AnyPath): string | null => {\n const type = mime.lookup(path);\n if (!type) return null;\n return type;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAAC;AAAA,EAAA;AAAA,cAAAC;AAAA,EAAA;AAAA;AAAA,kBAAAC;AAAA,EAAA;AAAA,iBAAAC;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA,iBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAAC;AAAA,EAAA;AAAA,cAAAC;AAAA,EAAA;AAAA,kBAAAC;AAAA,EAAA;AAAA,iBAAAC;AAAA;;;ACAA,wBAAiB;AACjB,aAAwB;AACxB,iBAA8B;AAsBvB,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YAAY,MAAc,KAAa;AACrC,UAAM,QAAQ,IAAI,kBAAkB,GAAG,EAAE;AAAA,EAC3C;AACF;AAaO,SAASC,YAAW,OAAuB;AAChD,SAAc,eAAQ,GAAG,KAAK;AAChC;AAaO,SAASC,YAAW,MAAqC;AAC9D,SAAc,kBAAW,IAAI;AAC/B;AAcO,SAASC,SAAQ,MAA6B;AACnD,SAAc,eAAQF,SAAQ,IAAI,CAAC;AACrC;AAcO,SAAS,SAAS,UAAmB,MAAwB;AAClE,QAAM,mBAAmBA,SAAQ,QAAQ;AACzC,QAAM,eAAeA,SAAQ,IAAI;AACjC,SAAO,aAAa,WAAW,gBAAgB;AACjD;AAcO,SAASG,UAAS,UAAmB,MAA6B;AACvE,SAAO;AAAA,IACE,gBAAS,UAAU,IAAI;AAAA,EAChC;AACF;AAyBO,SAAS,oBAAoB,MAAe,KAAa;AAC9D,SAAO,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,GAAG;AACnD;AAqBO,SAASC,MAAK,QAAiB,OAAgC;AACpE,SAAc,YAAK,KAAK,GAAG,KAAK;AAClC;AAiBO,SAAS,wBAAwB,MAAwB;AAC9D,SAAO,KAAK,QAAQ,SAAS,EAAE;AACjC;AA2BO,SAAS,oBAAoB,UAAmB,WAAmB;AACxE,QAAM,gBAAgB,UAAU,WAAW,GAAG,IAC1C,YACA,IAAI,SAAS;AACjB,MAAI,SAAS,SAAS,aAAa,EAAG,QAAO;AAC7C,SAAO,GAAG,QAAQ,GAAG,aAAa;AACpC;AAcO,IAAM,0BAA0B,CAAC,cAAoC;AAC1E,SAAc,mBAAQ,0BAAc,SAAS,CAAC;AAChD;AAYO,IAAM,WAAW,CAAC,SAA0B;AACjD,SAAc,aAAM,IAAI,EAAE;AAC5B;AAYO,IAAM,2BAA2B,CAAC,SAA0B;AACjE,SAAc,aAAM,IAAI,EAAE;AAC5B;AAYO,IAAM,gBAAgB,CAAC,SAA0B;AACtD,SAAc,aAAM,IAAI,EAAE;AAC5B;AAaO,IAAM,WAAW,CAAC,SAAiC;AACxD,QAAM,OAAO,kBAAAC,QAAK,OAAO,IAAI;AAC7B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO;AACT;","names":["dirname","isAbsolute","join","relative","resolve","dirname","isAbsolute","join","relative","resolve","resolve","isAbsolute","dirname","relative","join","mime"]}