This repository has been archived by the owner on Jun 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(*): implement TypeScript declaration mapping
Adds the necessary derived classes to map the paths in the generated TypeScript declaration files. fixes #2
- Loading branch information
1 parent
3e3df9d
commit 3392752
Showing
7 changed files
with
137 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ExportDeclaration, ImportDeclaration, StringLiteral, SyntaxKind } from 'typescript'; | ||
|
||
import Base, { IDerivedOptions as IBaseOptions } from '@lib/Declaration'; | ||
|
||
export type Interface = ExportDeclaration | ImportDeclaration; | ||
|
||
export type IOptions<T extends Interface> = IBaseOptions<T>; | ||
|
||
export default class Declaration<T extends Interface> extends Base<T> { | ||
constructor({ declaration, ...rest}: IOptions<T>) { | ||
|
||
// RAII checks | ||
const { kind, text } = (declaration.moduleSpecifier as StringLiteral); | ||
if (kind !== SyntaxKind.StringLiteral) { | ||
throw new TypeError(`Invalid TS declaration source type: ${kind}`); | ||
} | ||
|
||
super({declaration, ...rest, path: text}); | ||
} | ||
|
||
private get literal(): StringLiteral { | ||
return (this.declaration.moduleSpecifier as StringLiteral); | ||
} | ||
|
||
get path(): string { | ||
return this.literal.text; | ||
} | ||
|
||
protected update(value: string): void { | ||
this.literal.text = value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ExportDeclaration } from 'typescript'; | ||
|
||
import Declaration, { IOptions as IDeclarationOptions } from '@ts/Declaration'; | ||
|
||
export type Interface = ExportDeclaration; | ||
|
||
export type IOptions = IDeclarationOptions<Interface>; | ||
|
||
export default class Export extends Declaration<Interface> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { PathLike, readFile as readFileSync, writeFile as writeFileSync } from 'fs'; | ||
import { | ||
createPrinter, | ||
createSourceFile, | ||
EmitHint, | ||
ExportDeclaration, | ||
ImportDeclaration, | ||
ScriptTarget, | ||
SourceFile, | ||
SyntaxKind, | ||
} from 'typescript'; | ||
import { promisify } from 'util'; | ||
|
||
import ParseError from '@error/Parse'; | ||
import Base, { IDerivedOptions as IBaseOptions } from '@lib/File'; | ||
import Export from '@ts/Export'; | ||
import Import from '@ts/Import'; | ||
|
||
const readFile = promisify(readFileSync); | ||
const writeFile = promisify(writeFileSync); | ||
|
||
export type IOptions = IBaseOptions; | ||
|
||
export default class File extends Base<Import, Export> { | ||
private sourceFile: SourceFile | undefined; | ||
|
||
constructor({ ...options }: IOptions) { | ||
super({...options, extension: '.d.ts'}); | ||
this.sourceFile = undefined; | ||
} | ||
|
||
private get ast(): Promise<SourceFile> { | ||
if (this.sourceFile) { | ||
return Promise.resolve(this.sourceFile); | ||
} else { | ||
return (async () => { | ||
const data = await readFile(this.destination.toString(), 'utf-8'); | ||
try { | ||
return this.sourceFile = createSourceFile(this.destination.toString(), data, ScriptTarget.Latest); | ||
} catch (error) { | ||
if (error instanceof SyntaxError) { | ||
throw new ParseError({file: this, error, data}); | ||
} else { | ||
throw error; | ||
} | ||
} | ||
})(); | ||
} | ||
} | ||
|
||
async *imports(): AsyncIterableIterator<Import> { | ||
const { statements } = await this.ast; | ||
yield* statements | ||
.filter(({kind}) => kind === SyntaxKind.ImportDeclaration) | ||
.map(n => new Import({file: this, declaration: n as ImportDeclaration})); | ||
} | ||
|
||
async *exports(): AsyncIterableIterator<Export> { | ||
const { statements } = await this.ast; | ||
yield* statements | ||
.filter(({kind}) => kind === SyntaxKind.ExportDeclaration) | ||
.map(n => new Export({file: this, declaration: n as ExportDeclaration})); | ||
} | ||
|
||
async write(path?: PathLike | number, options?: { | ||
encoding?: string | null; | ||
mode?: number | string; | ||
flag?: string; | ||
} | string | null): Promise<void> { | ||
const sourceFile = await this.ast; | ||
const { newLine } = this.options; | ||
const printer = createPrinter({ newLine }); | ||
const data = printer.printNode(EmitHint.SourceFile, sourceFile, sourceFile); | ||
return writeFile((path === undefined) ? this.destination.toString() : path, data, options); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { ImportDeclaration } from 'typescript'; | ||
|
||
import Declaration, { IOptions as IDeclarationOptions } from '@ts/Declaration'; | ||
|
||
export type Interface = ImportDeclaration; | ||
|
||
export type IOptions = IDeclarationOptions<Interface>; | ||
|
||
export default class Import extends Declaration<Interface> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters