UNPKG

@cloud-copilot/cli

Version:

A standardized library for CLI building TypeScript CLI applications

74 lines 3.44 kB
import { readFile } from 'fs/promises'; import { join, sep } from 'path'; class CommonJsPackageFileReader { constructor(currentFile, levelsUp) { const dirPath = currentFile.slice(0, currentFile.lastIndexOf(sep)); this.rootPath = join(dirPath, ...backSegments(levelsUp)); } async readFile(pathParts) { const fullPath = join(this.rootPath, ...pathParts); return readFile(fullPath, 'utf8'); } } class EsmPackageFileReader { constructor(currentFile, levelsUp) { this.currentFile = currentFile; this.levelsUp = levelsUp; } /** * Lookup the root path of the project, going up the specified number of levels from the current file. * * @returns the root path of the project, calculated once and cached */ async getRootPath() { if (!this.rootPath) { const dirPath = this.currentFile.slice(0, this.currentFile.lastIndexOf('/')); const { fileURLToPath } = await import('node:url'); const startPath = fileURLToPath(dirPath); this.rootPath = join(startPath, ...backSegments(this.levelsUp)); } return this.rootPath; } async readFile(pathParts) { const { join } = await import('node:path'); const root = await this.getRootPath(); const fullPath = join(root, ...pathParts); return readFile(fullPath, 'utf8'); } } /** * A relatively sane way to read a file from a relative path inside your packaged cli app. For instance to * read the package.json inside your package. Works on ESM and CommonJS modules. Use __filename * or import.meta.url to get the path of the file you are in and pass it to this function. Set the `levelsUp` * based on how your project is packaged. For instance, if your file is packaged in `dist/cli.js` and you would use `1` if * you packaged your file is in `dist/src/cli.js` and you would use `2`. Whatever you need to get to the root. * * You get back a `PackageFileReader` which has a `readFile` method. You can then call that method * with the path parts to the file you want to read, relative to the root of your project. * For instance, to read the `package.json` file in the root of your project, you would call: * ```ts * const reader = await createPackageFileReader(import.meta.url, 1) // if your file is in dist/cli.js * const packageJson = await reader.readFile(['package.json']) * ``` * * @param currentFile the path to start from use `import.meta.url` for esm or `__filename` for CommonJS in most cases * @param levelsUp since __import.meta.url or __filename is the file you are in, you need to go up a few levels to ge to the root of your project. Use 0 for the current directory of the file you're calling from. * @returns a `PackageFileReader` you can use to read files relative to the root of your project. */ export function createPackageFileReader(currentFile, levelsUp) { const isEsm = currentFile.startsWith('file://'); if (isEsm) { return new EsmPackageFileReader(currentFile, levelsUp); } return new CommonJsPackageFileReader(currentFile, levelsUp); } /** * Create an array of `..` segments to go up the specified number of levels in a path. * * @param levelsUp the number of levels to go up * @returns an array of `..` segments */ function backSegments(levelsUp) { return Array(levelsUp).fill('..'); } //# sourceMappingURL=readRelative.js.map