alm
Version:
The best IDE for TypeScript
144 lines (121 loc) • 4.25 kB
text/typescript
/**
* Wraps fs and path into a nice "consistentPath" API
*/
/** we work with "/" for all paths (so does the typescript language service) */
export function consistentPath(filePath: string): string {
return filePath.split('\\').join('/');
}
import * as path from "path";
import * as fs from "fs";
import mkdirp = require('mkdirp');
import * as rimraf from "rimraf";
/**
* Resolves to to an absolute path.
* @param from,to,to,to...
*/
export function resolve(...args: string[]) {
return consistentPath(path.resolve(...args));
}
/**
* Could be called ends with :)
*/
export function isExt(path: string, ext: string): boolean {
return path && ext && path.indexOf(ext, path.length - ext.length) !== -1;
}
/**
* Converts "C:\boo" , "C:\boo\foo.ts" => "./foo.ts"; Works on unix as well.
*/
export function makeRelativePath(relativeFolder: string, filePath: string) {
var relativePath = path.relative(relativeFolder, filePath).split('\\').join('/');
if (relativePath[0] !== '.') {
relativePath = './' + relativePath;
}
return relativePath;
}
export function removeExt(filePath: string) {
const lastIndex = filePath.lastIndexOf('.');
if (lastIndex == -1 /** Didn't find `.` */
/** Found `.` in case `./` || `../` */
|| (lastIndex === 0 && (filePath[1] === '/' || filePath[2] === '/'))) {
return filePath;
}
return filePath.substr(0, lastIndex);
}
export function readFile(filePath: string): string {
return fs.readFileSync(filePath, 'utf8');
}
/** Will write the file and even make directories if needed */
export function writeFile(filePath: string, content: string) {
mkdirp.sync(path.dirname(filePath));
fs.writeFileSync(filePath, content, { encoding: 'utf8' });
}
export function deleteFile(filePath: string) {
fs.unlinkSync(filePath);
}
export function deleteDir(dirPath: string): Promise<{}> {
return new Promise(resolve => {
rimraf(dirPath, { glob: false, maxBusyTries: 10 }, (e) => {
if (e) {
console.error('Failed to delete Dir: ', dirPath);
}
resolve({});
});
})
}
/** see if a file exists */
export var existsSync = (filePath: string) => fs.existsSync(filePath);
/** see if path is absolute */
export var isAbsolute = (filePath: string) => path.isAbsolute(filePath);
/** is the filePath a directory? */
export var isDir = (filePath: string): boolean => fs.lstatSync(filePath).isDirectory();
/**
* See if path is relative.
*/
// Not particularly awesome e.g. '/..foo' will be not relative ,
// but it shouldn't matter as the significance is really about if `cwd` matters
export function isRelative(str: string) {
if (!str.length) return false;
return str[0] == '.' || str.substring(0, 2) == "./" || str.substring(0, 3) == "../";
}
/**
* returns the path if found
* @throws an error "not found" if not found */
export function travelUpTheDirectoryTreeTillYouFind(startDir: string, fileOrDirectory: string,
/** This is useful if we don't want to file `node_modules from inside node_modules` */
abortIfInside = false): string {
while (fs.existsSync(startDir)) { // while directory exists
var potentialFile = startDir + '/' + fileOrDirectory;
/** This means that we were *just* in this directory */
if (before == potentialFile) {
if (abortIfInside) {
throw new Error("not found")
}
}
if (fs.existsSync(potentialFile)) { // found it
return consistentPath(potentialFile);
}
else { // go up
var before = startDir;
startDir = path.dirname(startDir);
// At root:
if (startDir == before) throw new Error("not found");
}
}
}
/**
* Gets the sub directories of a directory
*/
export function getDirs(rootDir: string): string[] {
var files = fs.readdirSync(rootDir)
var dirs = []
for (var file of files) {
if (file[0] != '.') {
var filePath = `${rootDir}/${file}`
var stat = fs.statSync(filePath);
if (stat.isDirectory()) {
dirs.push(filePath)
}
}
}
return dirs;
}