@travetto/transformer
Advanced tools
Comparing version 2.1.4 to 2.2.0
{ | ||
"name": "@travetto/transformer", | ||
"displayName": "Transformation", | ||
"version": "2.1.4", | ||
"version": "2.2.0", | ||
"description": "Functionality for AST transformations, with transformer registration, and general utils", | ||
@@ -28,3 +28,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@travetto/base": "^2.1.3" | ||
"@travetto/base": "^2.2.0" | ||
}, | ||
@@ -31,0 +31,0 @@ "publishConfig": { |
@@ -19,3 +19,3 @@ <!-- This file was generated by @travetto/doc and should not be modified directly --> | ||
Below is an example of a transformer that uppercases all `class`, `method` and `param` declarations. This will break any code that depends upon it as we are redefining all the identifiers at compile time. | ||
Below is an example of a transformer that upper cases all `class`, `method` and `param` declarations. This will break any code that depends upon it as we are redefining all the identifiers at compile time. | ||
@@ -33,3 +33,3 @@ **Code: Sample Transformer - Upper case all declarations** | ||
@OnProperty() | ||
static handleProperty(state: TransformerState, node: ts.PropertyDeclaration) { | ||
static handleProperty(state: TransformerState, node: ts.PropertyDeclaration): ts.PropertyDeclaration { | ||
if (!state.source.fileName.includes('doc/src')) { | ||
@@ -50,3 +50,3 @@ return node; | ||
@OnClass() | ||
static handleClass(state: TransformerState, node: ts.ClassDeclaration) { | ||
static handleClass(state: TransformerState, node: ts.ClassDeclaration): ts.ClassDeclaration { | ||
if (!state.source.fileName.includes('doc/src')) { | ||
@@ -67,3 +67,3 @@ return node; | ||
@OnMethod() | ||
static handleMethod(state: TransformerState, node: ts.MethodDeclaration) { | ||
static handleMethod(state: TransformerState, node: ts.MethodDeclaration): ts.MethodDeclaration { | ||
if (!state.source.fileName.includes('doc/src')) { | ||
@@ -70,0 +70,0 @@ return node; |
@@ -29,3 +29,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
getId(file: string) { | ||
getId(file: string): string { | ||
if (!this.#ids.has(file)) { | ||
@@ -41,3 +41,3 @@ const key = basename(file).replace(/[.][^.]*$/, '').replace(/[^A-Za-z0-9]+/g, '_'); | ||
*/ | ||
importFile(file: string, base?: string) { | ||
importFile(file: string, base?: string): Import { | ||
file = ModuleUtil.normalizePath(file); | ||
@@ -70,5 +70,5 @@ | ||
const ident = this.factory.createIdentifier(id); | ||
const imprt = { path: file, ident }; | ||
this.#imports.set(ident.escapedText.toString(), imprt); | ||
this.#newImports.set(file, imprt); | ||
const newImport = { path: file, ident }; | ||
this.#imports.set(ident.escapedText.toString(), newImport); | ||
this.#newImports.set(file, newImport); | ||
} | ||
@@ -81,3 +81,3 @@ return this.#newImports.get(file)!; | ||
*/ | ||
importFromResolved(...types: AnyType[]) { | ||
importFromResolved(...types: AnyType[]): void { | ||
for (const type of types) { | ||
@@ -100,3 +100,3 @@ if (type.key === 'external' && type.source && type.source !== this.source.fileName) { | ||
*/ | ||
finalizeNewImports(file: ts.SourceFile) { | ||
finalizeNewImports(file: ts.SourceFile): ts.SourceFile | undefined { | ||
if (!this.#newImports.size) { | ||
@@ -108,3 +108,3 @@ return; | ||
const importStmts = [...this.#newImports.values()].map(({ path, ident }) => { | ||
const imptStmt = this.factory.createImportDeclaration( | ||
const importStmt = this.factory.createImportDeclaration( | ||
undefined, undefined, | ||
@@ -114,3 +114,3 @@ this.factory.createImportClause(false, undefined, this.factory.createNamespaceImport(ident)), | ||
); | ||
return imptStmt; | ||
return importStmt; | ||
}); | ||
@@ -123,2 +123,5 @@ | ||
} catch (err) { // Missing import | ||
if (!(err instanceof Error)) { | ||
throw err; | ||
} | ||
const out = new Error(`${err.message} in ${file.fileName.replace(PathUtil.cwd, '.')}`); | ||
@@ -133,3 +136,3 @@ out.stack = err.stack; | ||
*/ | ||
finalize(ret: ts.SourceFile) { | ||
finalize(ret: ts.SourceFile): ts.SourceFile { | ||
return this.finalizeNewImports(ret) ?? ret; | ||
@@ -141,3 +144,3 @@ } | ||
*/ | ||
getOrImport(factory: ts.NodeFactory, type: ExternalType) { | ||
getOrImport(factory: ts.NodeFactory, type: ExternalType): ts.Identifier | ts.PropertyAccessExpression { | ||
if (type.source === this.source.fileName) { | ||
@@ -144,0 +147,0 @@ return factory.createIdentifier(type.name!); |
@@ -12,3 +12,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
export function getAllTransformers(obj: Record<string, { [HandlersProp]?: NodeTransformer[] }>) { | ||
export function getAllTransformers(obj: Record<string, { [HandlersProp]?: NodeTransformer[] }>): NodeTransformer[] { | ||
return Object.values(obj).flatMap(x => x[HandlersProp] ?? []); | ||
@@ -18,3 +18,3 @@ } | ||
// Store handlers in class | ||
function storeHandler(cls: TransformerWithHandlers, fn: Function, phase: TransformPhase, type: TransformerType, target?: string[]) { | ||
function storeHandler(cls: TransformerWithHandlers, fn: Function, phase: TransformPhase, type: TransformerType, target?: string[]): void { | ||
if (target) { | ||
@@ -34,3 +34,3 @@ const ns = cls[TransformerId].split('/')[0]; // Everything before the '/' | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.CallExpression) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'call', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'call', target); | ||
} | ||
@@ -44,3 +44,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.FunctionDeclaration | ts.FunctionExpression) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'function', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'function', target); | ||
} | ||
@@ -54,3 +54,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.ParameterDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'parameter', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'parameter', target); | ||
} | ||
@@ -64,3 +64,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.PropertyDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'property', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'property', target); | ||
} | ||
@@ -74,3 +74,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.GetAccessorDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'getter', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'getter', target); | ||
} | ||
@@ -84,3 +84,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.SetAccessorDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'setter', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'setter', target); | ||
} | ||
@@ -94,3 +94,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.MethodDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'method', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'method', target); | ||
} | ||
@@ -104,3 +104,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.MethodDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'static-method', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'static-method', target); | ||
} | ||
@@ -114,3 +114,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.ClassDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'before', 'class', target); | ||
): void => storeHandler(inst, d.value!, 'before', 'class', target); | ||
} | ||
@@ -124,3 +124,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.CallExpression, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'call', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'call', target); | ||
} | ||
@@ -134,3 +134,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.FunctionDeclaration | ts.FunctionExpression) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'function', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'function', target); | ||
} | ||
@@ -144,3 +144,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.ParameterDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'parameter', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'parameter', target); | ||
} | ||
@@ -154,3 +154,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.PropertyDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'property', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'property', target); | ||
} | ||
@@ -164,3 +164,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.GetAccessorDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'getter', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'getter', target); | ||
} | ||
@@ -174,3 +174,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.SetAccessorDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'setter', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'setter', target); | ||
} | ||
@@ -184,3 +184,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.MethodDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'method', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'method', target); | ||
} | ||
@@ -194,3 +194,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.MethodDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'static-method', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'static-method', target); | ||
} | ||
@@ -204,3 +204,3 @@ | ||
inst: Transformer, __: unknown, d: TypedPropertyDescriptor<(state: S, node: ts.ClassDeclaration, dm?: DecoratorMeta) => R> | ||
) => storeHandler(inst, d.value!, 'after', 'class', target); | ||
): void => storeHandler(inst, d.value!, 'after', 'class', target); | ||
} |
@@ -120,2 +120,3 @@ /* eslint-disable no-bitwise */ | ||
const cons = GLOBAL_SIMPLE[name]; | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
const ret = LiteralUtil.isLiteralType(type) ? Util.coerceType(type.value, cons as typeof String, false) : | ||
@@ -152,4 +153,3 @@ undefined; | ||
union: { | ||
build: (checker, type) => { | ||
const uType = type as ts.UnionType; | ||
build: (checker, uType: ts.UnionType) => { | ||
let undefinable = false; | ||
@@ -164,3 +164,3 @@ let nullable = false; | ||
}); | ||
const name = CoreUtil.getSymbol(type)?.getName(); | ||
const name = CoreUtil.getSymbol(uType)?.getName(); | ||
return { key: 'union', name, undefinable, nullable, tsSubTypes: remainder, subTypes: [] }; | ||
@@ -214,5 +214,5 @@ }, | ||
const sourceFile = DeclarationUtil.getDeclarations(type) | ||
const sourceFile: string = DeclarationUtil.getDeclarations(type) | ||
?.find(x => ts.getAllJSDocTags(x, (t): t is ts.JSDocTag => t.tagName.getText() === 'concrete').length) | ||
?.getSourceFile().fileName as string; | ||
?.getSourceFile().fileName ?? ''; | ||
@@ -219,0 +219,0 @@ if (source === '.') { |
@@ -22,3 +22,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
getChecker() { | ||
getChecker(): ts.TypeChecker { | ||
return this.#tsChecker; | ||
@@ -31,4 +31,4 @@ } | ||
*/ | ||
getType(el: ts.Type | ts.Node) { | ||
return 'getSourceFile' in el ? this.#tsChecker.getTypeAtLocation(el as ts.Node) : el; | ||
getType(el: ts.Type | ts.Node): ts.Type { | ||
return 'getSourceFile' in el ? this.#tsChecker.getTypeAtLocation(el) : el; | ||
} | ||
@@ -40,2 +40,3 @@ | ||
getAllTypeArguments(ref: ts.Type): ts.Type[] { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return this.#tsChecker.getTypeArguments(ref as ts.TypeReference) as ts.Type[]; | ||
@@ -47,3 +48,3 @@ } | ||
*/ | ||
getReturnType(node: ts.MethodDeclaration) { | ||
getReturnType(node: ts.MethodDeclaration): ts.Type { | ||
const type = this.getType(node); | ||
@@ -57,3 +58,3 @@ const [sig] = type.getCallSignatures(); | ||
*/ | ||
getTypeAsString(type: ts.Type) { | ||
getTypeAsString(type: ts.Type): string | undefined { | ||
return this.#tsChecker.typeToString(this.#tsChecker.getApparentType(type)) || undefined; | ||
@@ -65,3 +66,3 @@ } | ||
*/ | ||
getPropertiesOfType(type: ts.Type) { | ||
getPropertiesOfType(type: ts.Type): ts.Symbol[] { | ||
return this.#tsChecker.getPropertiesOfType(type); | ||
@@ -111,2 +112,3 @@ } | ||
if (finalize) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
result = finalize(result as never); | ||
@@ -122,2 +124,5 @@ } | ||
} catch (err) { | ||
if (!(err instanceof Error)) { | ||
throw err; | ||
} | ||
console.error('Unable to resolve type', err.stack); | ||
@@ -124,0 +129,0 @@ return { key: 'literal', ctor: Object, name: 'object' }; |
@@ -15,4 +15,6 @@ import * as ts from 'typescript'; | ||
import { CoreUtil, LiteralUtil } from './util'; | ||
import { Import } from './types/shared'; | ||
function hasOriginal(n: unknown): n is { original: ts.Node } { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return !!n && !(n as { parent?: unknown }).parent && !!(n as { original: unknown }).original; | ||
@@ -22,2 +24,3 @@ } | ||
function hasEscapedName(n: unknown): n is { name: { escapedText: string } } { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return !!n && !!(n as { name?: { escapedText?: string } }).name?.escapedText; | ||
@@ -50,3 +53,3 @@ } | ||
*/ | ||
getResolver() { | ||
getResolver(): TypeResolver { | ||
return this.#resolver; | ||
@@ -58,3 +61,3 @@ } | ||
*/ | ||
getOrImport(type: ExternalType) { | ||
getOrImport(type: ExternalType): ts.Identifier | ts.PropertyAccessExpression { | ||
return this.#imports.getOrImport(this.factory, type); | ||
@@ -66,3 +69,3 @@ } | ||
*/ | ||
importFile(file: string) { | ||
importFile(file: string): Import { | ||
return this.#imports.importFile(file); | ||
@@ -74,3 +77,3 @@ } | ||
*/ | ||
resolveType(node: ts.Type | ts.Node) { | ||
resolveType(node: ts.Type | ts.Node): AnyType { | ||
const resolved = this.#resolver.resolveType(node); | ||
@@ -84,3 +87,3 @@ this.#imports.importFromResolved(resolved); | ||
*/ | ||
resolveExternalType(node: ts.Node) { | ||
resolveExternalType(node: ts.Node): ExternalType { | ||
const resolved = this.resolveType(node); | ||
@@ -96,3 +99,3 @@ if (resolved.key !== 'external') { | ||
*/ | ||
typeToIdentifier(node: ts.Type | AnyType) { | ||
typeToIdentifier(node: ts.Type | AnyType): ts.Identifier | ts.PropertyAccessExpression | undefined { | ||
const type = 'flags' in node ? this.resolveType(node) : node; | ||
@@ -109,3 +112,3 @@ switch (type.key) { | ||
*/ | ||
resolveReturnType(node: ts.MethodDeclaration) { | ||
resolveReturnType(node: ts.MethodDeclaration): AnyType { | ||
const typeNode = ts.getJSDocReturnType(node); | ||
@@ -123,3 +126,3 @@ if (typeNode) { | ||
*/ | ||
readDocTag(node: ts.Declaration, name: string) { | ||
readDocTag(node: ts.Declaration, name: string): string[] { | ||
return DocUtil.readDocTag(this.#resolver.getType(node), name); | ||
@@ -131,3 +134,3 @@ } | ||
*/ | ||
importDecorator(pth: string, name: string) { | ||
importDecorator(pth: string, name: string): ts.PropertyAccessExpression | undefined { | ||
if (!this.#decorators.has(`${pth}:${name}`)) { | ||
@@ -144,3 +147,3 @@ const ref = this.#imports.importFile(pth); | ||
*/ | ||
createDecorator(pth: string, name: string, ...contents: (ts.Expression | undefined)[]) { | ||
createDecorator(pth: string, name: string, ...contents: (ts.Expression | undefined)[]): ts.Decorator { | ||
this.importDecorator(pth, name); | ||
@@ -166,2 +169,3 @@ return CoreUtil.createDecorator(this.factory, this.#decorators.get(name)!, ...contents); | ||
name: ident ? | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
ident.escapedText! as string : | ||
@@ -176,3 +180,3 @@ undefined | ||
getDecoratorList(node: ts.Node): DecoratorMeta[] { | ||
return ((node.decorators ?? []) as ts.Decorator[]) | ||
return (node.decorators ?? []) | ||
.map(dec => this.getDecoratorMeta(dec)) | ||
@@ -194,3 +198,3 @@ .filter(x => !!x.ident); | ||
*/ | ||
addStatement(stmt: ts.Statement, before?: ts.Node) { | ||
addStatement(stmt: ts.Statement, before?: ts.Node): void { | ||
const stmts = this.source.statements.slice(0); | ||
@@ -205,4 +209,6 @@ let idx = stmts.length; | ||
} | ||
if (n && ts.isSourceFile(n.parent) && stmts.indexOf(n as ts.Statement) >= 0) { | ||
idx = stmts.indexOf(n as ts.Statement) - 1; | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
const nStmt: ts.Statement = n as ts.Statement; | ||
if (n && ts.isSourceFile(n.parent) && stmts.indexOf(nStmt) >= 0) { | ||
idx = stmts.indexOf(nStmt) - 1; | ||
} | ||
@@ -218,3 +224,3 @@ if (!this.added.has(idx)) { | ||
*/ | ||
finalize(ret: ts.SourceFile) { | ||
finalize(ret: ts.SourceFile): ts.SourceFile { | ||
ret = this.#imports.finalize(ret); | ||
@@ -227,5 +233,5 @@ return ret; | ||
*/ | ||
getFilenameAsSrc() { | ||
getFilenameAsSrc(): ts.CallExpression { | ||
const ident = this.factory.createIdentifier('ᚕsrc'); | ||
ident.getSourceFile = () => this.source; | ||
ident.getSourceFile = (): ts.SourceFile => this.source; | ||
return this.factory.createCallExpression(ident, [], [this.createIdentifier('__filename')]); | ||
@@ -244,2 +250,3 @@ } | ||
fromLiteral(val: unknown): ts.Node { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return LiteralUtil.fromLiteral(this.factory, val as object); | ||
@@ -251,3 +258,3 @@ } | ||
*/ | ||
extendObjectLiteral(src: object | ts.Expression, ...rest: (object | ts.Expression)[]) { | ||
extendObjectLiteral(src: object | ts.Expression, ...rest: (object | ts.Expression)[]): ts.ObjectLiteralExpression { | ||
return LiteralUtil.extendObjectLiteral(this.factory, src, ...rest); | ||
@@ -259,3 +266,3 @@ } | ||
*/ | ||
createAccess(first: string | ts.Expression, second: string | ts.Identifier, ...items: (string | ts.Identifier)[]) { | ||
createAccess(first: string | ts.Expression, second: string | ts.Identifier, ...items: (string | ts.Identifier)[]): ts.PropertyAccessExpression { | ||
return CoreUtil.createAccess(this.factory, first, second, ...items); | ||
@@ -272,6 +279,6 @@ } | ||
/** | ||
* Ceate identifier from node or text | ||
* Create identifier from node or text | ||
* @param name | ||
*/ | ||
createIdentifier(name: string | { getText(): string }) { | ||
createIdentifier(name: string | { getText(): string }): ts.Identifier { | ||
return this.factory.createIdentifier(typeof name === 'string' ? name : name.getText()); | ||
@@ -287,3 +294,3 @@ } | ||
*/ | ||
findDecorator(cls: Transformer, node: ts.Node, name: string, module?: string) { | ||
findDecorator(cls: Transformer, node: ts.Node, name: string, module?: string): ts.Decorator | undefined { | ||
const target = `${cls[TransformerId]}/${name}`; | ||
@@ -299,3 +306,3 @@ return this.getDecoratorList(node) | ||
*/ | ||
generateUniqueIdentifier(node: ts.Node, type: AnyType) { | ||
generateUniqueIdentifier(node: ts.Node, type: AnyType): string { | ||
let unique: string; | ||
@@ -322,5 +329,5 @@ try { | ||
/** | ||
* Register synthetic idetnifier | ||
* Register synthetic identifier | ||
*/ | ||
createSyntheticIdentifier(id: string) { | ||
createSyntheticIdentifier(id: string): [identifier: ts.Identifier, exists: boolean] { | ||
id = `${id}${TransformerState.SYNTHETIC_EXT}`; | ||
@@ -332,3 +339,3 @@ let exists = true; | ||
} | ||
return [this.#syntheticIdentifiers.get(id), exists] as [id: ts.Identifier, exists: boolean]; | ||
return [this.#syntheticIdentifiers.get(id)!, exists]; | ||
} | ||
@@ -344,4 +351,4 @@ | ||
return cls.members.find( | ||
m => ts.isMethodDeclaration(m) && ts.isIdentifier(m.name) && m.name.escapedText === method | ||
) as ts.MethodDeclaration; | ||
(m): m is ts.MethodDeclaration => ts.isMethodDeclaration(m) && ts.isIdentifier(m.name) && m.name.escapedText === method | ||
); | ||
} else { | ||
@@ -348,0 +355,0 @@ const props = this.getResolver().getPropertiesOfType(cls); |
@@ -11,2 +11,3 @@ import * as ts from 'typescript'; | ||
static hasOriginal(o: ts.Node): o is (ts.Node & { original: ts.Node }) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return 'original' in o && !!(o as { original?: ts.Node }).original; | ||
@@ -19,2 +20,3 @@ } | ||
static hasTarget(o: ts.Type): o is (ts.Type & { target: ts.Type }) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return 'target' in o && !!(o as { target?: ts.Type }).target; | ||
@@ -27,3 +29,3 @@ } | ||
*/ | ||
static getRangeOf<T extends ts.Node>(source: ts.SourceFile, o: T | undefined) { | ||
static getRangeOf<T extends ts.Node>(source: ts.SourceFile, o: T | undefined): { start: number, end: number } | undefined { | ||
if (o) { | ||
@@ -44,2 +46,3 @@ const start = ts.getLineAndCharacterOfPosition(source, o.getStart(source)); | ||
if (node && node!.arguments && node!.arguments.length >= position + 1) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return node.arguments[position] as T; | ||
@@ -64,7 +67,9 @@ } | ||
*/ | ||
static getSymbol(type: ts.Type | ts.Symbol) { | ||
static getSymbol(type: ts.Type | ts.Symbol | ts.TypeReference): ts.Symbol { | ||
if ('valueDeclaration' in type || 'escapedName' in type) { | ||
return type; | ||
} else if ('aliasSymbol' in type && type.aliasSymbol) { | ||
return type.aliasSymbol; | ||
} else { | ||
return (type as ts.TypeReference).aliasSymbol ?? (type as ts.Type).symbol; | ||
return type.symbol; | ||
} | ||
@@ -78,3 +83,3 @@ } | ||
*/ | ||
static updateSource(factory: ts.NodeFactory, src: ts.SourceFile, statements: ts.NodeArray<ts.Statement> | ts.Statement[]) { | ||
static updateSource(factory: ts.NodeFactory, src: ts.SourceFile, statements: ts.NodeArray<ts.Statement> | ts.Statement[]): ts.SourceFile { | ||
return factory.updateSourceFile( | ||
@@ -88,3 +93,8 @@ src, statements, src.isDeclarationFile, src.referencedFiles, src.typeReferenceDirectives, src.hasNoDefaultLib | ||
*/ | ||
static createAccess(factory: ts.NodeFactory, first: string | ts.Expression, second: string | ts.Identifier, ...items: (string | ts.Identifier)[]) { | ||
static createAccess( | ||
factory: ts.NodeFactory, | ||
first: string | ts.Expression, | ||
second: string | ts.Identifier, | ||
...items: (string | ts.Identifier)[] | ||
): ts.PropertyAccessExpression { | ||
if (typeof first === 'string') { | ||
@@ -102,3 +112,3 @@ first = factory.createIdentifier(first); | ||
*/ | ||
static createDecorator(factory: ts.NodeFactory, name: ts.Expression, ...contents: (ts.Expression | undefined)[]) { | ||
static createDecorator(factory: ts.NodeFactory, name: ts.Expression, ...contents: (ts.Expression | undefined)[]): ts.Decorator { | ||
return factory.createDecorator( | ||
@@ -108,3 +118,3 @@ factory.createCallExpression( | ||
undefined, | ||
contents.filter(x => !!x) as ts.Expression[] | ||
contents.filter((x?: ts.Expression): x is ts.Expression => !!x) | ||
) | ||
@@ -117,3 +127,3 @@ ); | ||
*/ | ||
static isAbstract(node: ts.Declaration) { | ||
static isAbstract(node: ts.Declaration): boolean { | ||
// eslint-disable-next-line no-bitwise | ||
@@ -120,0 +130,0 @@ return !!(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Abstract); |
@@ -13,3 +13,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
static isConstantDeclaration(node: ts.Node) { | ||
static isConstantDeclaration(node: ts.Node): boolean { | ||
let s: ts.Node = node; | ||
@@ -25,3 +25,3 @@ while (s && !ts.isVariableDeclarationList(s)) { | ||
*/ | ||
static isPublic(node: ts.Declaration) { | ||
static isPublic(node: ts.Declaration): boolean { | ||
// eslint-disable-next-line no-bitwise | ||
@@ -72,3 +72,5 @@ return !(ts.getCombinedModifierFlags(node) & ts.ModifierFlags.NonPublicAccessibilityModifier); | ||
*/ | ||
static getAccessorPair(node: ts.GetAccessorDeclaration | ts.SetAccessorDeclaration) { | ||
static getAccessorPair( | ||
node: ts.GetAccessorDeclaration | ts.SetAccessorDeclaration | ||
): { getter?: ts.GetAccessorDeclaration, setter?: ts.SetAccessorDeclaration } { | ||
const acc = { getter: ts.isGetAccessorDeclaration(node) ? node : undefined, setter: ts.isSetAccessorDeclaration(node) ? node : undefined }; | ||
@@ -75,0 +77,0 @@ if (ts.isClassDeclaration(node.parent)) { |
@@ -13,6 +13,8 @@ import * as ts from 'typescript'; | ||
static getDecoratorIdent(d: ts.Decorator): ts.Identifier { | ||
if (ts.isCallExpression(d.expression)) { | ||
return d.expression.expression as ts.Identifier; | ||
if (ts.isCallExpression(d.expression) && ts.isIdentifier(d.expression.expression)) { | ||
return d.expression.expression; | ||
} else if (ts.isIdentifier(d.expression)) { | ||
return d.expression; | ||
} else if (ts.isCallExpression(d.expression) && ts.isPropertyAccessExpression(d.expression.expression) && ts.isIdentifier(d.expression.expression.expression)) { | ||
return d.expression.expression.expression; | ||
} else { | ||
@@ -26,3 +28,3 @@ throw new Error('No Identifier'); | ||
*/ | ||
static spliceDecorators(node: ts.Node, target: ts.Decorator | undefined, replacements: ts.Decorator[], idx = -1) { | ||
static spliceDecorators(node: ts.Node, target: ts.Decorator | undefined, replacements: ts.Decorator[], idx = -1): ts.Decorator[] { | ||
if (idx < 0 && target) { | ||
@@ -51,4 +53,5 @@ idx = node.decorators?.indexOf(target) ?? -1; | ||
static getArguments<T extends ts.Expression = ts.Expression>(node: ts.Decorator | undefined): T[] | undefined { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return node && ts.isCallExpression(node.expression) ? [...node.expression.arguments] as T[] : undefined; | ||
} | ||
} |
@@ -21,3 +21,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
static getDocComment(o: ts.JSDoc | ts.JSDocTag, def?: string) { | ||
static getDocComment(o: ts.JSDoc | ts.JSDocTag, def?: string): string | undefined { | ||
return (typeof o.comment === 'string' ? o.comment : undefined) ?? def; | ||
@@ -29,3 +29,3 @@ } | ||
*/ | ||
static describeDocs(node: ts.Declaration | ts.Type) { | ||
static describeDocs(node: ts.Declaration | ts.Type): DeclDocumentation { | ||
if (node && !('getSourceFile' in node)) { | ||
@@ -43,2 +43,3 @@ node = DeclarationUtil.getPrimaryDeclarationNode(node); | ||
while (!this.hasJSDoc(node) && CoreUtil.hasOriginal(node)) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
node = node.original as ts.Declaration; | ||
@@ -86,5 +87,5 @@ } | ||
*/ | ||
static readAugments(type: ts.Type | ts.Symbol) { | ||
static readAugments(type: ts.Type | ts.Symbol): string[] { | ||
return this.readDocTag(type, 'augments').map(x => x.replace(/^.*?([^` ]+).*?$/, (_, b) => b)); | ||
} | ||
} |
@@ -15,3 +15,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
static optionalResolve(file: string, base?: string) { | ||
static optionalResolve(file: string, base?: string): string { | ||
file = base ? pathResolve(base, file) : file; | ||
@@ -28,3 +28,3 @@ try { | ||
*/ | ||
static collectImports(src: ts.SourceFile) { | ||
static collectImports(src: ts.SourceFile): Map<string, Import> { | ||
const pth = require.resolve(src.fileName); | ||
@@ -31,0 +31,0 @@ const base = PathUtil.toUnix(pth); |
@@ -28,3 +28,5 @@ import * as ts from 'typescript'; | ||
static fromLiteral(factory: ts.NodeFactory, val: unknown): ts.Node { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
if (val && (val as ts.Expression).kind) { // If already a node | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return val as ts.Node; | ||
@@ -44,6 +46,9 @@ } else if (Array.isArray(val)) { | ||
} else if (val === String || val === Number || val === Boolean || val === Date || val === RegExp) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
val = factory.createIdentifier((val as Function).name); | ||
} else { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
const ov = val as object; | ||
const pairs: ts.PropertyAssignment[] = []; | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
for (const k of Object.keys(ov) as (keyof typeof ov)[]) { | ||
@@ -58,2 +63,3 @@ if (ov[k] !== undefined) { | ||
} | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
return val as ts.Expression; | ||
@@ -65,3 +71,11 @@ } | ||
*/ | ||
static toLiteral(val: ts.Node, strict = true): unknown { | ||
static toLiteral(val: ts.NullLiteral, strict?: boolean): null; | ||
static toLiteral(val: ts.NumericLiteral, strict?: boolean): number; | ||
static toLiteral(val: ts.StringLiteral, strict?: boolean): string; | ||
static toLiteral(val: ts.BooleanLiteral, strict?: boolean): boolean; | ||
static toLiteral(val: ts.ObjectLiteralExpression, strict?: boolean): object; | ||
static toLiteral(val: ts.ArrayLiteralExpression, strict?: boolean): unknown[]; | ||
static toLiteral(val: undefined, strict?: boolean): undefined; | ||
static toLiteral(val: ts.Node, strict?: boolean): unknown; | ||
static toLiteral(val?: ts.Node, strict = true): unknown { | ||
if (!val) { | ||
@@ -109,3 +123,3 @@ throw new Error('Val is not defined'); | ||
*/ | ||
static extendObjectLiteral(factory: ts.NodeFactory, src: object | ts.Expression, ...rest: (object | ts.Expression)[]) { | ||
static extendObjectLiteral(factory: ts.NodeFactory, src: object | ts.Expression, ...rest: (object | ts.Expression)[]): ts.ObjectLiteralExpression { | ||
let ret = this.fromLiteral(factory, src); | ||
@@ -124,3 +138,3 @@ if (rest.find(x => !!x)) { | ||
*/ | ||
static getObjectValue(node: ts.Expression | undefined, key: string) { | ||
static getObjectValue(node: ts.Expression | undefined, key: string): ts.Expression | undefined { | ||
if (node && ts.isObjectLiteralExpression(node) && node.properties) { | ||
@@ -127,0 +141,0 @@ for (const prop of node.properties) { |
@@ -17,3 +17,3 @@ import { Util } from '@travetto/base'; | ||
*/ | ||
static collapseNodes(all: unknown[]) { | ||
static collapseNodes(all: unknown[]): unknown[] { | ||
return all.map(x => this.collapseNode(x)); | ||
@@ -39,4 +39,6 @@ } | ||
} else { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
const ox = x as object; | ||
const out: Record<string, unknown> = {}; | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
for (const key of Object.keys(ox) as (keyof typeof x)[]) { | ||
@@ -48,3 +50,3 @@ if (Util.isFunction(ox[key]) || exclude.has(key) || ox[key] === undefined) { | ||
out[key] = this.collapseNode(ox[key], cache); | ||
} catch (err) { | ||
} catch { | ||
return undefined; | ||
@@ -51,0 +53,0 @@ } |
@@ -57,3 +57,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
#init(transformers: NodeTransformer<S, TransformerType, ts.Node>[]) { | ||
#init(transformers: NodeTransformer<S, TransformerType, ts.Node>[]): void { | ||
for (const trn of transformers) { | ||
@@ -120,6 +120,9 @@ if (!this.#transformers.has(trn.type)) { | ||
return state.finalize(ret); | ||
} catch (e) { | ||
console.error('Failed transforming', { error: e, file: file.fileName }); | ||
const out = new Error(`Failed transforming: ${file.fileName}: ${e.message}`); | ||
out.stack = e.stack; | ||
} catch (err) { | ||
if (!(err instanceof Error)) { | ||
throw err; | ||
} | ||
console.error('Failed transforming', { error: err, file: file.fileName }); | ||
const out = new Error(`Failed transforming: ${file.fileName}: ${err.message}`); | ||
out.stack = err.stack; | ||
throw out; | ||
@@ -135,3 +138,3 @@ } finally { | ||
*/ | ||
executePhaseAlways<T extends ts.Node>(state: S, set: TransformerSet<S>, phase: TransformPhase, node: T) { | ||
executePhaseAlways<T extends ts.Node>(state: S, set: TransformerSet<S>, phase: TransformPhase, node: T): T | undefined { | ||
if (!set[phase]?.size) { | ||
@@ -142,2 +145,3 @@ return; | ||
for (const all of set[phase]!.get('ALL') ?? []) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
node = (all[phase]!(state, node) as T) ?? node; | ||
@@ -151,3 +155,3 @@ } | ||
*/ | ||
executePhase<T extends ts.Node>(state: S, set: TransformerSet<S>, phase: TransformPhase, node: T) { | ||
executePhase<T extends ts.Node>(state: S, set: TransformerSet<S>, phase: TransformPhase, node: T): T | undefined { | ||
if (!set[phase]?.size) { | ||
@@ -177,2 +181,3 @@ return; | ||
for (const item of values) { | ||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions | ||
node = (item[phase]!(state, node, dec) as T) ?? node; | ||
@@ -179,0 +184,0 @@ } |
@@ -16,3 +16,3 @@ import * as ts from 'typescript'; | ||
*/ | ||
static async compile(folder: string, file?: string) { | ||
static async compile(folder: string, file?: string): Promise<string> { | ||
@@ -24,3 +24,3 @@ const tsconfigObj = await import('@travetto/boot/tsconfig.trv.json'); | ||
rootNames: (await ScanFs.scanDir({ testFile: f => f.startsWith('src/') && f.endsWith('.ts') }, folder)) | ||
.filter(x => x.stats.isFile()) | ||
.filter(x => x.stats?.isFile()) | ||
.filter(x => !file || x.file.endsWith(file)) | ||
@@ -35,3 +35,3 @@ .map(x => x.file), | ||
(await ScanFs.scanDir({ testFile: f => f.startsWith('support/transformer') }, folder)) | ||
.filter(x => x.stats.isFile()) | ||
.filter(x => x.stats?.isFile()) | ||
.map(x => import(x.file).then(getAllTransformers)); | ||
@@ -38,0 +38,0 @@ |
74912
1925
Updated@travetto/base@^2.2.0