Skip to content

Commit

Permalink
add scripts and improve the api a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
Matheus Xavier committed Sep 16, 2020
1 parent 4770d16 commit 0fbd813
Show file tree
Hide file tree
Showing 9 changed files with 594 additions and 26 deletions.
135 changes: 124 additions & 11 deletions Path.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copryright 2020 Matheus Xavier all rights reserved. MIT licensed
import { _determineSeparators } from "./_separator.ts";
import Hashids from "./hashids.ts";

export const LINUX_SEPS = ["/"];
export const WINDOWS_SEPS = ["\\", "/"];
Expand All @@ -13,9 +14,9 @@ export class Path {
public trailingSlash: boolean = false;

/**
*
* @param path initialiize this instance with a path if passed
* @param separators not needed most of the time
* Construct a path object
* @param path initialize this instance with a path if passed
* @param separators not needed most of the time allows for
*/
constructor(path?: string, separators?: string[]) {
this.separators = separators || _determineSeparators();
Expand Down Expand Up @@ -56,19 +57,64 @@ export class Path {

/**
* @returns the stored path structure as a string
* the preferred system separator will be used
* using the preferred system separator.
*/
public toString(): string {
const path = this.pathElements.join(this.separators[0])
public toString(prefix?: string, suffix?: string): string {
let path = this.pathElements.join(this.separators[0]);
prefix = prefix || "";
suffix = suffix || "";
path = prefix.concat(path.concat(suffix));
return this.trailingSlash ? "/".concat(path) : path;
}

public push(e: string) {
this.pathElements.push(e);
/**
* push a path fragment onto the end of this Path
* @param e a string denoting a Path fragment
*/
public push(e: string): Path {
let pe = Path.explodePath(this.separatorList, e);
pe.forEach((e) => this.pathElements.push(e));
return this;
}

public pop(): string | undefined {
return this.pathElements.pop();
public pop(): Path {
this.pathElements.pop();
return this;
}

/**
* finds the first valid node walking a path from the right
* @param ignoreFiles if set files will be ignored on the resolution
* @returns a new Path object with a Path object until the valid node
*/
public findLastValidNode(ignoreFiles?: boolean): Path {
let strRepr = this.toString();
const np = new Path(strRepr);
if (ignoreFiles) {
while (!np.exists && !np.isFile) {
np.pop();
}
} else {
while (!np.exists) {
np.pop();
}
}
return np;
}

/**
* takes the diff between Path x and Path y
* @param x
* @param y
* @returns elements in x but not in y
*/
public static diff(x: Path, y: Path): string[] {
const xRepr = x.elements;
const yRepr = y.elements;
let res = xRepr.filter((e) => {
return yRepr.indexOf(e) === -1;
});
return res;
}

/**
Expand Down Expand Up @@ -143,7 +189,7 @@ export class Path {
}

/**
* rquest the inner representation of the path inside the class
* request the inner representation of the path inside the class
*/
get elements(): string[] {
return this.pathElements;
Expand All @@ -163,4 +209,71 @@ export class Path {
get separatorList(): string[] {
return this.separators;
}

public static fromCWD(): Path {
return new Path(Deno.cwd());
}
}

/**
*
* @param path the desired path
* @param parents whether or not to create the structure needed to achieve the final path
* @returns `true` on success and `false` on failure
*/
export function mkDirSync(path: Path, parents: boolean): boolean {
// if the path already exists and is a dir there is nothing to do
if (path.exists && path.isDir) {
return true;
}
// find the last part of the path that is valid
let vp = path.findLastValidNode();
// take the diff between the valid path and the desired path
let needs = Path.diff(path, vp);
// create the needed paths
for (let i = 0; i < needs.length; i++) {
vp.push(needs[i]);
Deno.mkdirSync(vp.toString());
}
return true;
}

export async function mkDir(path: Path, parents: boolean): Promise<boolean> {
// if the path already exists and is a dir there is nothing to do
if (path.exists && path.isDir) {
return true;
}
// find the last part of the path that is valid
let vp = path.findLastValidNode();
// take the diff between the valid path and the desired path
let needs = Path.diff(path, vp);
// create the needed paths
for (let i = 0; i < needs.length; i++) {
vp.push(needs[i]);
await Deno.mkdir(vp.toString());
}
return true;
}

export function genTmpPath(
rngScalar: number = 4096,
prefix: string = "",
suffix: string = "",
joinChar: string = ".",
): Path {
const rn = Math.floor(Math.random() * rngScalar);
const hsi = new Hashids(rn.toString(), 10);
let tempPath;
prefix = prefix ? prefix+joinChar:"";
suffix = suffix ? joinChar+suffix:"";
switch (Deno.build.os) {
case "windows":
tempPath = Deno.env.get("TMP") || Deno.env.get("TEMP");
break;
case "darwin":
case "linux":
tempPath = Deno.env.get("TMPDIR") || "/tmp";
}
let pt = new Path(tempPath)
return pt.push(prefix + hsi.encode(rn) + suffix);
}
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ console.log(nixPath.exists);
```

# Features
* Handles windows acceptance of `\\` or `/` as separators
* On linux `\\` is treated as escaped charachters correctly
* Handles windows acceptance of `\` or `/` as separators
* On linux `\` is treated as escaped charachters correctly
* Easily manipulate paths by pushing/poping or like an array
* Get file extensions with ease and correctly
* Make assertions about a path

# Thanks
this lib incorporates work from the hashids lib found on hashids.ts
Copyright (c) 2012-2020 Bazyli Brzóska & Ivan Akimov
5 changes: 5 additions & 0 deletions example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Path from "./mod.ts";
import { genTmpPath } from "./mod.js";

const path = genTmpPath();
console.log(path.toString());
Loading

0 comments on commit 0fbd813

Please sign in to comment.