| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | const unique = new Map<string, WeakRef<Path>>(); |
| 2 | const final = new FinalizationRegistry((raw: string) => unique.delete(raw)); |
| 3 | |
| 4 | export class Path { |
| 5 | raw: string; |
| 6 | |
| 7 | static from(...parts: (string | Path)[]) { |
| 8 | return new Path(...parts.map((x) => x instanceof Path ? x.raw : x)); |
| 9 | } |
| 10 | |
| 11 | /** For convenience, paths are deduplicated. */ |
| 12 | constructor(...parts: string[]) { |
| 13 | const raw = this.raw = |
| 14 | parts.length === 1 && parts[0] && path.isAbsolute(parts[0]) |
| 15 | ? parts[0] |
| 16 | : path.resolve(...parts); |
| 17 | const existing = unique.get(raw)?.deref(); |
| 18 | if (existing) return existing; |
| 19 | unique.set(raw, new WeakRef(this)); |
| 20 | final.register(this, raw); |
| 21 | } |
| 22 | |
| 23 | toString() { |
| 24 | return this.raw; |
| 25 | } |
| 26 | |
| 27 | get parent(): Path | null { |
| 28 | const { raw } = this; |
| 29 | const parent = path.dirname(raw); |
| 30 | if (raw === parent) return null; |
| 31 | return new Path(parent); |
| 32 | } |
| 33 | |
| 34 | get relative() { |
| 35 | return path.relative(".", this.raw); |
| 36 | } |
| 37 | |
| 38 | get ext() { |
| 39 | return path.extname(this.raw); |
| 40 | } |
| 41 | |
| 42 | get base() { |
| 43 | return path.basename(this.raw); |
| 44 | } |
| 45 | |
| 46 | get baseWithoutExt() { |
| 47 | return path.basename(this.raw, this.ext); |
| 48 | } |
| 49 | |
| 50 | join(subPath: string, ...more: string[]) { |
| 51 | return new Path(this.raw, subPath, ...more); |
| 52 | } |
| 53 | |
| 54 | existsSync() { |
| 55 | return fs.existsSync(this.raw); |
| 56 | } |
| 57 | |
| 58 | static sep = path.sep; |
| 59 | |
| 60 | [Symbol.for("nodejs.util.inspect.custom")]( |
| 61 | _: number, |
| 62 | o: util.InspectOptionsStylized, |
| 63 | i: typeof util.inspect, |
| 64 | ) { |
| 65 | return o.stylize(`Path ${i(this.raw, false, 1, false)}`, "special"); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | import * as path from "node:path"; |
| 70 | import * as fs from "./fs.ts"; |
| 71 | import * as util from "node:util"; |