From 48c01807c2b10c1d3986bb45bfbf8e4f1a4b03b9 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Tue, 6 Feb 2018 11:54:05 +0000 Subject: [PATCH] fix(file): determine correct source file root Use the returned configuration parsed files to determine the common root of the source files. This will represent the out directory tree --- lib/File.ts | 26 +++++++++++++++++++++++--- lib/Mapper.ts | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/File.ts b/lib/File.ts index e7d10a1..050d57b 100644 --- a/lib/File.ts +++ b/lib/File.ts @@ -17,15 +17,35 @@ const writeFile = promisify(fs.writeFile); export interface IOptions { path: string | Path; options: ts.CompilerOptions; + config: ts.ParsedCommandLine; +} + +function commonPathPrefix(paths: IterableIterator): string { + const { done, value: left } = paths.next(); + if (done) { + return ''; + } + let index = left.length; + for (const right of paths) { + for (let i = 0; i < index; ++i) { + if (left.charAt(i) !== right.charAt(i)) { + index = i; + break; + } + } + } + return left.substring(0, index); } export default class File { readonly source: Path; + readonly root: Path; readonly options: ts.CompilerOptions; private program: estree.Program | undefined; - constructor({ path, options }: IOptions) { + constructor({ path, options, config: { fileNames } }: IOptions) { this.source = new Path(path.toString()); + this.root = new Path(commonPathPrefix(fileNames[Symbol.iterator]())); this.options = options; } @@ -94,14 +114,14 @@ export default class File { } get destination(): Path { - const { outDir, rootDir } = this.options; + const { outDir } = this.options; if (!outDir) { throw new TypeError(`Only 'outDir' is supported`); } const out = new Path(outDir); - const destination = out.join(this.source.relative(rootDir)); + const destination = out.join(this.source.relative(this.root)); destination.extension = '.js'; return destination; } diff --git a/lib/Mapper.ts b/lib/Mapper.ts index 1fd2a85..a92782a 100644 --- a/lib/Mapper.ts +++ b/lib/Mapper.ts @@ -50,7 +50,7 @@ export default class Mapper { async *files(): AsyncIterableIterator { const { options } = this.parsed; - yield* this.parsed.fileNames.map(path => new File({ path, options })); + yield* this.parsed.fileNames.map(path => new File({ path, options, config: this.parsed })); } async *map(): AsyncIterableIterator {