ts-runtime
Advanced tools
@@ -16,4 +16,6 @@ #!/usr/bin/env node | ||
let compilerOptions = '{}'; | ||
let parsedCompilerOptions; | ||
let tsConfigPath; | ||
function defaultAction() { | ||
program.start(options, pkg.version); | ||
const files = commander.args | ||
@@ -24,10 +26,25 @@ .filter(arg => typeof arg === 'string'); | ||
} | ||
compilerOptions = JSON.parse(compilerOptions); | ||
if (tsConfigPath && ts.sys.fileExists(tsConfigPath)) { | ||
const tsConfig = require(path.resolve(tsConfigPath)); | ||
try { | ||
parsedCompilerOptions = JSON.parse(compilerOptions); | ||
} | ||
catch (e) { | ||
program.status.error(`Could not parse compiler configuration.`); | ||
return; | ||
} | ||
if (tsConfigPath) { | ||
if (!ts.sys.fileExists(tsConfigPath)) { | ||
program.status.error(`Could not load configuration from ${tsConfigPath}.`); | ||
return; | ||
} | ||
const resolvedTsConfigPath = path.resolve(tsConfigPath); | ||
const tsConfig = require(resolvedTsConfigPath); | ||
if (tsConfig.hasOwnProperty('compilerOptions')) { | ||
compilerOptions = tsConfig.compilerOptions; | ||
parsedCompilerOptions = tsConfig.compilerOptions; | ||
} | ||
else { | ||
program.status.warn(`No compiler options found in ${tsConfigPath}, used defaults.`); | ||
parsedCompilerOptions = {}; | ||
} | ||
} | ||
const opts = ts.convertCompilerOptionsFromJson(compilerOptions, '.'); | ||
const opts = ts.convertCompilerOptionsFromJson(parsedCompilerOptions, '.'); | ||
options.log = false; | ||
@@ -40,3 +57,3 @@ options.compilerOptions = opts.options; | ||
} | ||
program.start(files, options, pkg.version); | ||
program.transform(files); | ||
} | ||
@@ -77,2 +94,5 @@ function useTsConfig(path) { | ||
} | ||
function setLibDeclarations() { | ||
options.libDeclarations = true; | ||
} | ||
function setLibNamespace(namespace) { | ||
@@ -101,12 +121,13 @@ options.libNamespace = namespace; | ||
.option('-a, --noAnnotate', 'do not annotate classes and functions', setNoAnnotate) | ||
.option('-c, --compilerOptions <compilerOptions>', 'set TypeScript compiler options. defaults to "{}"', setCompilerOptions) | ||
.option('-C, --tsConfig <path>', 'use the compiler options of the given tsconfig.json', useTsConfig) | ||
.option('-c, --tsConfig <path>', 'use the compiler options of the given tsconfig.json', useTsConfig) | ||
.option('-C, --compilerOptions <compilerOptions>', 'set TypeScript compiler options. defaults to "{}"', setCompilerOptions) | ||
.option('-d, --declarationFileName <fileName>', 'set file name for global declarations. defaults to "tsr-declarations"', setDeclarationFileName) | ||
.option('-e, --excludeDeclarationFile', 'do not automatically import ambient declarations in the entry file. default to false', setExcludeDeclarationFile) | ||
.option('-E, --excludeLib', 'do not automatically import the runtime library. default to false', setExcludeLib) | ||
.option('-E, --excludeLib', 'do not automatically import the runtime library. defaults to false', setExcludeLib) | ||
.option('-f, --force', 'try to finish on TypeScript compiler error. defaults to false', setForce) | ||
.option('-k, --keepTemp', 'keep temporary files. defaults to false', setKeepTemp) | ||
.option('-l, --libIdentifier <name>', 'lib import name. defaults to "t"', setLibIdentifier) | ||
.option('-L, --libDeclarations', 'reflect declarations from global libs (e.g. DOM). defaults to false', setLibDeclarations) | ||
.option('-m, --moduleAlias', 'import package module-alias on top of every file.', setModuleAlias) | ||
.option('-n, --libNamespace <namespace>', 'prefix for lib and code additions. defaults to "_"', setLibNamespace) | ||
.option('-n, --libNamespace <namespace>', 'prefix for lib and code additions. defaults to ""', setLibNamespace) | ||
.option('-p, --declarationPrefix <namespace>', 'prefix for added variables. defaults to "_"', setDeclarationPrefix) | ||
@@ -119,4 +140,4 @@ .option('-s, --stackTraceOutput <limit>', 'output a specified number of lines of the stack trace. defaults to 3', setStackTraceOutput) | ||
console.log(' $ tsr entry.ts --force'); | ||
console.log(' $ tsr src/bin/index.ts src/lib/index.ts'); | ||
console.log(' $ tsr -c \'{ "outDir": "dist" }\' entry.ts'); | ||
console.log(' $ tsr src/entry1 bin/entry2 lib/entry3'); | ||
console.log(' $ tsr -c tsconfig.json'); | ||
console.log(); | ||
@@ -123,0 +144,0 @@ }); |
@@ -11,3 +11,3 @@ import { Options } from '../options'; | ||
end: (time: string, totalTime: string) => void; | ||
warn: (warning: string) => void; | ||
warn: (warning: string, defer?: boolean) => void; | ||
stop: () => void; | ||
@@ -17,3 +17,4 @@ term: () => void; | ||
} | ||
export declare function start(entryFiles: string[], options: Options, version: string): void; | ||
export declare function start(opts: Options, version: string): void; | ||
export declare function transform(entryFiles: string[]): void; | ||
export declare const status: ProgramStatus; |
@@ -17,8 +17,4 @@ "use strict"; | ||
let warnings = []; | ||
function start(entryFiles, options, version) { | ||
if (child) { | ||
return; | ||
} | ||
child = cp.fork(path.join(__dirname, './process')); | ||
started = true; | ||
let options; | ||
function start(opts, version) { | ||
pkgVersion = version; | ||
@@ -30,2 +26,13 @@ current = 'Processing'; | ||
warnings = []; | ||
options = opts; | ||
exports.status.init(); | ||
exports.status.start(); | ||
} | ||
exports.start = start; | ||
function transform(entryFiles) { | ||
if (child) { | ||
return; | ||
} | ||
child = cp.fork(path.join(__dirname, './process')); | ||
started = true; | ||
child.on('exit', code => { | ||
@@ -47,6 +54,5 @@ exports.status.term(); | ||
}); | ||
exports.status.init(); | ||
child.send({ message: 'startTransformation', payload: [entryFiles, options] }); | ||
} | ||
exports.start = start; | ||
exports.transform = transform; | ||
exports.status = { | ||
@@ -60,3 +66,4 @@ init: () => { | ||
currentPast = 'Processed'; | ||
spinner.info(chalk.bold(`ts-runtime v${pkgVersion}`)); | ||
if (!started) | ||
spinner.info(chalk.bold(`ts-runtime v${pkgVersion}`)); | ||
spinner.text = current; | ||
@@ -132,6 +139,9 @@ spinner.start(); | ||
}, | ||
warn: (warning) => { | ||
warn: (warning, defer = true) => { | ||
if (warnings.indexOf(warning) === -1) { | ||
warnings.push(warning); | ||
} | ||
else if (!defer) { | ||
spinner.warn(warning); | ||
} | ||
}, | ||
@@ -138,0 +148,0 @@ stop: () => { |
@@ -31,5 +31,7 @@ import * as ts from 'typescript'; | ||
hasSelfReference(node: ts.Node): boolean; | ||
hasApparentSelfReference(node: ts.Node): boolean; | ||
getIdentifier(text: string): string; | ||
getTypeDeclarationName(node: string | ts.Identifier): string; | ||
getReturnTypeDeclarationName(): string; | ||
getInlineTypeName(node: string | ts.Identifier): string; | ||
getReturnTypeDeclarationName(): string; | ||
getLibDeclarationName(): string; | ||
@@ -40,2 +42,3 @@ getTypeSymbolDeclarationName(node: string | ts.Identifier): string; | ||
getMembers(node: ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration | ts.TypeLiteralNode): (ts.TypeElement | ts.ClassElement)[]; | ||
getAllMembers(node: ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration | ts.TypeLiteralNode): (ts.TypeElement | ts.ClassElement)[]; | ||
setMerged(symbol: ts.Symbol): Set<ts.Symbol>; | ||
@@ -42,0 +45,0 @@ wasMerged(symbol: ts.Symbol): boolean; |
@@ -131,3 +131,18 @@ "use strict"; | ||
hasSelfReference(node) { | ||
const typeInfo = this.scanner.getTypeInfo(node.name || node); | ||
const typeInfo = this.scanner.getTypeInfo(node); | ||
const members = typeInfo && typeInfo.symbol && typeInfo.symbol.members; | ||
if (!members) { | ||
return false; | ||
} | ||
for (let [key, member] of Array.from(members)) { | ||
for (let decl of member.getDeclarations() || []) { | ||
if (this.hasApparentSelfReference(decl)) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
hasApparentSelfReference(node) { | ||
const typeInfo = this.scanner.getTypeInfo(node); | ||
const search = (node) => { | ||
@@ -144,26 +159,33 @@ if (ts.isTypeReferenceNode(node)) { | ||
} | ||
getIdentifier(text) { | ||
const ids = this.scanner.getIdentifiers(this.sourceFile); | ||
while (ids && ids.has(text)) { | ||
text = `_${text}`; | ||
} | ||
return text; | ||
} | ||
getTypeDeclarationName(node) { | ||
const name = typeof node === 'string' ? node : node.text; | ||
return `${this.options.declarationPrefix}${name}Type`; | ||
return this.getIdentifier(`${this.options.declarationPrefix}${name}Type`); | ||
} | ||
getReturnTypeDeclarationName() { | ||
return this.getTypeDeclarationName('return'); | ||
} | ||
getInlineTypeName(node) { | ||
const name = typeof node === 'string' ? node : node.text; | ||
return `${this.options.declarationPrefix}${name}TypeInline`; | ||
return this.getIdentifier(`${this.options.declarationPrefix}${name}TypeInline`); | ||
} | ||
getReturnTypeDeclarationName() { | ||
return this.getTypeDeclarationName('return'); | ||
} | ||
getLibDeclarationName() { | ||
return `${this.options.libNamespace}${this.options.libIdentifier}`; | ||
return this.getIdentifier(`${this.options.libNamespace}${this.options.libIdentifier}`); | ||
} | ||
getTypeSymbolDeclarationName(node) { | ||
const name = typeof node === 'string' ? node : node.text; | ||
return `${this.options.declarationPrefix}${name}TypeParametersSymbol`; | ||
return this.getIdentifier(`${this.options.declarationPrefix}${name}TypeParametersSymbol`); | ||
} | ||
getTypeSymbolDeclarationInitializer(node) { | ||
const name = typeof node === 'string' ? node : node.text; | ||
return `${name}TypeParameters`; | ||
return this.getIdentifier(`${name}TypeParameters`); | ||
} | ||
getTypeParametersDeclarationName() { | ||
return `${this.options.declarationPrefix}typeParameters`; | ||
return this.getIdentifier(`${this.options.declarationPrefix}typeParameters`); | ||
} | ||
@@ -191,2 +213,24 @@ getMembers(node) { | ||
} | ||
getAllMembers(node) { | ||
const typeInfo = this.scanner.getTypeInfo(node); | ||
const merged = new Set(); | ||
let type; | ||
if (!typeInfo) { | ||
type = this.checker.getTypeAtLocation(node); | ||
} | ||
else { | ||
type = typeInfo.type; | ||
} | ||
if (!type) { | ||
return node.members; | ||
} | ||
(type.getProperties() || []).forEach(sym => { | ||
for (let typeElement of (sym.getDeclarations() || [])) { | ||
if (ts.isTypeElement(typeElement) || ts.isClassElement(typeElement)) { | ||
merged.add(typeElement); | ||
} | ||
} | ||
}); | ||
return Array.from(merged); | ||
} | ||
setMerged(symbol) { | ||
@@ -193,0 +237,0 @@ return this._merged.add(symbol); |
@@ -201,3 +201,3 @@ "use strict"; | ||
const typeInfo = this.scanner.getTypeInfo(node); | ||
const TSR_DECLARATION = !!typeInfo && typeInfo.TSR_DECLARATION; | ||
const TSR_DECLARATION = typeInfo.isTsrDeclaration(); | ||
let args = []; | ||
@@ -228,4 +228,2 @@ if (util.hasNonEmptyArrayProperty(node, 'typeArguments')) { | ||
const isSelfReference = this.context.isSelfReference(node); | ||
const isDeclared = this.context.isDeclared(node.typeName); | ||
const wasDeclared = this.context.wasDeclared(node.typeName); | ||
if (typeInfo && typeInfo.symbol) { | ||
@@ -240,3 +238,3 @@ if (util.hasFlag(typeInfo.symbol, ts.SymbolFlags.RegularEnum) || util.hasFlag(typeInfo.symbol, ts.SymbolFlags.ConstEnum)) { | ||
if (asLiteral && !isSelfReference) { | ||
let sf = typeInfo.declarations[0].getSourceFile().fileName; | ||
let sf = typeInfo.sourceFile.fileName; | ||
let hash = util.getHash(sf); | ||
@@ -251,3 +249,8 @@ let name = this.context.checker.getFullyQualifiedName(typeInfo.symbol); | ||
} | ||
if (!wasDeclared && isDeclared && !isSelfReference && !asLiteral) { | ||
let tdz = !isSelfReference && !asLiteral && !isTypeParameter && | ||
!this.context.wasDeclared(node.typeName) && this.context.isDeclared(node.typeName); | ||
if (!this.context.options.libDeclarations && !typeInfo.isExternalModule) { | ||
tdz = false; | ||
} | ||
if (tdz) { | ||
identifier = this.tdz(identifier); | ||
@@ -277,9 +280,4 @@ } | ||
node.expression; | ||
const wasDeclared = this.context.wasDeclared(identifier); | ||
const isDeclared = this.context.isDeclared(identifier); | ||
const typeInfo = this.scanner.getTypeInfo(node); | ||
const asLiteral = typeInfo && typeInfo.TSR_DECLARATION; | ||
const typeNameText = ts.isIdentifier(node.expression) ? | ||
node.expression.text : | ||
util.getPropertyAccessExpressionTextOrFail(node.expression); | ||
const asLiteral = typeInfo && typeInfo.isTsrDeclaration(); | ||
let keyword = 'ref'; | ||
@@ -303,5 +301,12 @@ if (typeInfo && typeInfo.symbol) { | ||
else { | ||
const typeNameText = ts.isIdentifier(node.expression) ? | ||
node.expression.text : | ||
util.getPropertyAccessExpressionTextOrFail(node.expression); | ||
id = ts.createIdentifier(typeNameText); | ||
} | ||
if (!asLiteral && !wasDeclared && isDeclared) { | ||
let tdz = !asLiteral && !this.context.wasDeclared(identifier) && this.context.isDeclared(identifier); | ||
if (!this.context.options.libDeclarations && !typeInfo.isExternalModule) { | ||
tdz = false; | ||
} | ||
if (tdz) { | ||
id = this.tdz(id); | ||
@@ -394,3 +399,4 @@ } | ||
if (intersections.length > 0) { | ||
reflection = [this.propertyAccessCall(this.intersect([...intersections, this.asObject(reflection)]), 'unwrap')]; | ||
// reflection = [this.propertyAccessCall(this.intersect([...intersections, this.asObject(reflection)]), 'unwrap')]; | ||
reflection = [this.intersect([...intersections, this.asObject(reflection)])]; | ||
} | ||
@@ -428,17 +434,19 @@ if (hasExtender) { | ||
case ts.SyntaxKind.InterfaceDeclaration: | ||
return this.interfaceReflection(declaration, name); | ||
return this.libCall('declare', [ts.createLiteral(name), this.interfaceReflection(declaration, name)]); | ||
case ts.SyntaxKind.ClassDeclaration: | ||
return this.classReflection(declaration, name); | ||
return this.libCall('declare', [ts.createLiteral(name), this.classReflection(declaration, name)]); | ||
case ts.SyntaxKind.TypeLiteral: | ||
return this.asType(name, this.typeLiteralReflection(declaration)); | ||
return this.libCall('declare', [ts.createLiteral(name), this.asType(name, this.typeLiteralReflection(declaration))]); | ||
case ts.SyntaxKind.EnumDeclaration: | ||
return this.asType(name, this.enumReflection(declaration)); | ||
return this.libCall('declare', [ts.createLiteral(name), this.asType(name, this.enumReflection(declaration))]); | ||
case ts.SyntaxKind.EnumMember: | ||
return this.asType(name, this.enumMemberReflection(declaration)); | ||
return this.libCall('declare', [ts.createLiteral(name), this.asType(name, this.enumMemberReflection(declaration))]); | ||
case ts.SyntaxKind.FunctionDeclaration: | ||
return this.asType(name, this.functionReflection(declaration)); | ||
return this.libCall('declare', [ts.createLiteral(name), this.asType(name, this.functionReflection(declaration))]); | ||
case ts.SyntaxKind.VariableDeclaration: | ||
return this.asVar(name, this.variableReflection(declaration)); | ||
return this.libCall('declare', [ts.createLiteral(name), this.asVar(name, this.variableReflection(declaration))]); | ||
case ts.SyntaxKind.TypeAliasDeclaration: | ||
return this.typeAliasReflection(declaration, name); | ||
return this.libCall('declare', [ts.createLiteral(name), this.typeAliasReflection(declaration, name)]); | ||
case ts.SyntaxKind.FunctionType: | ||
return this.libCall('declare', [ts.createLiteral(name), this.functionTypeReflection(declaration)]); | ||
default: | ||
@@ -1004,3 +1012,3 @@ throw new errors_1.ProgramError(`Could not reflect declaration for ${ts.SyntaxKind[declaration.kind]}`); | ||
get lib() { | ||
return `${this.namespace}${this._lib}`; | ||
return this.context.getIdentifier(`${this.namespace}${this._lib}`); | ||
} | ||
@@ -1007,0 +1015,0 @@ get package() { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const t = require("flow-runtime"); | ||
const map = new Map(); | ||
const voidType = t.void; | ||
const intersect = t.intersect; | ||
const declare = t.declare; | ||
const ref = t.ref; | ||
t.declare = (name, type) => { | ||
map.set(name, type); | ||
declare.bind(t)(name, type); | ||
}; | ||
t.ref = (type, ...args) => { | ||
if (typeof type === 'string') { | ||
if (map.has(type)) { | ||
type = map.get(type); | ||
} | ||
} | ||
return ref.bind(t)(type, ...args); | ||
}; | ||
// t.intersect = (...args: any[]) => { | ||
// return intersect.bind(t)(...args).unwrap(); | ||
// } | ||
// | ||
// t.intersection = (...args: any[]) => { | ||
// return t.intersect(...args); | ||
// } | ||
t.undef = () => { | ||
return voidType(); | ||
return voidType.bind(t)(); | ||
}; | ||
@@ -8,0 +31,0 @@ t.nostrict = (...args) => { |
import * as ts from 'typescript'; | ||
export interface Options { | ||
libDeclarations?: boolean; | ||
noAnnotate?: boolean; | ||
@@ -4,0 +5,0 @@ compilerOptions?: ts.CompilerOptions; |
@@ -17,2 +17,3 @@ "use strict"; | ||
}, | ||
libDeclarations: false, | ||
declarationFileName: 'tsr-declarations', | ||
@@ -24,3 +25,3 @@ force: false, | ||
libIdentifier: 't', | ||
libNamespace: '_', | ||
libNamespace: '', | ||
declarationPrefix: '_', | ||
@@ -27,0 +28,0 @@ moduleAlias: false, |
{ | ||
"name": "ts-runtime", | ||
"version": "0.1.7", | ||
"version": "0.1.8", | ||
"description": "Runtime type checks for TypeScript", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -420,2 +420,4 @@ # ts-runtime | ||
> By default declarations from built in libs (such as DOM, or ES6) are not reflected, but inferred at runtime. | ||
#### Declarations | ||
@@ -520,3 +522,3 @@ | ||
Type: `string` | ||
Default: "_" | ||
Default: "" | ||
@@ -533,5 +535,11 @@ Prefix for the default library import. | ||
```ts | ||
import _t from "ts-runtime/lib"; | ||
import t from "ts-runtime/lib"; | ||
``` | ||
#### libIdentifier | ||
Type: `boolean` | ||
Default: false | ||
By default, built in libraries, such as DOM or ES6, are not reflected, but inferred at runtime. | ||
#### declarationPrefix | ||
@@ -600,15 +608,16 @@ Type: `string` | ||
-a, --noAnnotate do not annotate classes and functions | ||
-c, --compilerOptions <compilerOptions> set TypeScript compiler options. defaults to "{}" | ||
-C, --tsConfig <path> use the compiler options of the given tsconfig.json | ||
-c, --tsConfig <path> use the compiler options of the given tsconfig.json | ||
-C, --compilerOptions <compilerOptions> set TypeScript compiler options. defaults to "{}" | ||
-d, --declarationFileName <fileName> set file name for global declarations. defaults to "tsr-declarations" | ||
-e, --excludeDeclarationFile do not automatically import ambient declarations in the entry file. default to false | ||
-E, --excludeLib do not automatically import the runtime library. default to false | ||
-E, --excludeLib do not automatically import the runtime library. defaults to false | ||
-f, --force try to finish on TypeScript compiler error. defaults to false | ||
-k, --keepTemp keep temporary files. defaults to false | ||
-l, --libIdentifier <name> lib import name. defaults to "t" | ||
-L, --libDeclarations reflect declarations from global libs (e.g. DOM). defaults to false | ||
-m, --moduleAlias import package module-alias on top of every file. | ||
-n, --libNamespace <namespace> prefix for lib and code additions. defaults to "_" | ||
-n, --libNamespace <namespace> prefix for lib and code additions. defaults to "" | ||
-p, --declarationPrefix <namespace> prefix for added variables. defaults to "_" | ||
-s, --stackTraceOutput <limit> output a specified number of lines of the stack trace. defaults to 3 | ||
-t, --tempFolder <name> set folder name for temporary files. defaults to ".tsr" | ||
-t, --tempFolderName <name> set folder name for temporary files. defaults to ".tsr" | ||
@@ -618,4 +627,4 @@ Examples: | ||
$ tsr entry.ts --force | ||
$ tsr src/bin/index.ts src/lib/index.ts | ||
$ tsr -c '{ "outDir": "dist" }' entry.ts | ||
$ tsr src/entry1 bin/entry2 lib/entry3 | ||
$ tsr -c tsconfig.json | ||
``` | ||
@@ -622,0 +631,0 @@ |
import * as ts from 'typescript'; | ||
import { Options } from './options'; | ||
export interface TsrDeclaration { | ||
@@ -7,2 +8,3 @@ symbol: ts.Symbol; | ||
export declare class Scanner { | ||
private _options; | ||
private _program; | ||
@@ -18,3 +20,3 @@ private _checker; | ||
private DisallowedDeclaratins; | ||
constructor(program: ts.Program); | ||
constructor(program: ts.Program, options: Options); | ||
scan(): void; | ||
@@ -39,4 +41,6 @@ mapNode<T extends ts.Node>(alias: T, original: ts.Node): T; | ||
private getMappedNode(node); | ||
private getNameExpression(node); | ||
private getAsExpression(node); | ||
private addDeclaration(symbol, fileName); | ||
readonly options: Options; | ||
readonly program: ts.Program; | ||
@@ -63,2 +67,3 @@ readonly checker: ts.TypeChecker; | ||
private _isLiteral; | ||
private _isExternalModule; | ||
private _isAmbient; | ||
@@ -71,3 +76,3 @@ private _isDeclaration; | ||
hasDeclarations(): boolean; | ||
readonly TSR_DECLARATION: boolean; | ||
private readonly TSR_DECLARATION; | ||
readonly symbol: ts.Symbol; | ||
@@ -92,2 +97,3 @@ readonly enclosing: ts.Node; | ||
readonly isExternal: boolean; | ||
readonly isExternalModule: boolean; | ||
} |
@@ -6,4 +6,5 @@ "use strict"; | ||
const path = require("path"); | ||
// TODO: only scan required nodes and build symbol table for other purposes | ||
class Scanner { | ||
constructor(program) { | ||
constructor(program, options) { | ||
this.declarations = []; | ||
@@ -18,8 +19,14 @@ this.aliases = new Map(); | ||
ts.SyntaxKind.ImportClause, | ||
ts.SyntaxKind.SourceFile | ||
ts.SyntaxKind.SourceFile, | ||
ts.SyntaxKind.EndOfFileToken, | ||
ts.SyntaxKind.ObjectBindingPattern, | ||
ts.SyntaxKind.ArrayBindingPattern, | ||
ts.SyntaxKind.VariableDeclaration, | ||
]; | ||
this.AllowedDeclarations = ts.SymbolFlags.Interface | ts.SymbolFlags.Class | | ||
ts.SymbolFlags.Enum | ts.SymbolFlags.EnumMember | ts.SymbolFlags.TypeAlias | | ||
ts.SymbolFlags.Function | ts.SymbolFlags.TypeLiteral | ts.SymbolFlags.Variable; | ||
this.DisallowedDeclaratins = ts.SymbolFlags.Module; | ||
ts.SymbolFlags.RegularEnum | ts.SymbolFlags.ConstEnum | ts.SymbolFlags.Enum | | ||
ts.SymbolFlags.EnumMember | ts.SymbolFlags.TypeAlias | ts.SymbolFlags.Function | | ||
/* ts.SymbolFlags.TypeLiteral | */ ts.SymbolFlags.Variable; | ||
this.DisallowedDeclaratins = ts.SymbolFlags.Module | ts.SymbolFlags.TypeParameter | ts.SymbolFlags.TypeLiteral; | ||
this._options = options; | ||
this._program = program; | ||
@@ -66,5 +73,9 @@ this._checker = program.getTypeChecker(); | ||
getSymbol(type, node) { | ||
let symbol = type && (type.aliasSymbol || type.symbol || | ||
(ts.isQualifiedName(node) || ts.isIdentifier(node) || ts.isEntityName(node) ? | ||
this.checker.getSymbolAtLocation(node) : undefined)); | ||
let symbol; | ||
if (type) { | ||
symbol = type.symbol || type.aliasSymbol; | ||
} | ||
if (!symbol && node) { | ||
symbol = this.checker.getSymbolAtLocation(node); | ||
} | ||
return symbol; | ||
@@ -113,4 +124,2 @@ } | ||
const scanNode = (node) => { | ||
if (!node) | ||
return; | ||
this.scanNode(node); | ||
@@ -142,3 +151,3 @@ ts.forEachChild(node, scanNode); | ||
this.properties.set(node, typeInfo); | ||
return typeInfo; | ||
return node; | ||
} | ||
@@ -162,4 +171,28 @@ shouldScan(node) { | ||
} | ||
node = this.getNameExpression(node); | ||
return node; | ||
} | ||
getNameExpression(node) { | ||
let expr = node; | ||
if (node.typeName) { | ||
expr = node.typeName; | ||
} | ||
// if ((node as any).exprName) { | ||
// expr = (node as any).exprName; | ||
// } | ||
// if ((node as any).parameterName) { | ||
// expr = (node as any).parameterName; | ||
// } | ||
// if ((node as any).name) { | ||
// expr = (node as any).name; | ||
// } | ||
// | ||
// if ((node as any).tagName) { | ||
// expr = (node as any).tagName; | ||
// } | ||
if (expr !== node) { | ||
this.mapNode(node, expr); | ||
} | ||
return expr; | ||
} | ||
getAsExpression(node) { | ||
@@ -175,7 +208,10 @@ let expression = node.expression; | ||
const uid = util.getHashedDeclarationName(name, fileName); | ||
let decl = this.declarations.find(decl => decl.symbol === symbol); | ||
if (!decl) { | ||
let index = this.declarations.findIndex(decl => decl.symbol === symbol); | ||
if (index === -1) { | ||
this.declarations.unshift({ symbol, name: uid }); | ||
} | ||
} | ||
get options() { | ||
return this._options; | ||
} | ||
get program() { | ||
@@ -196,5 +232,8 @@ return this._program; | ||
if (this._isTsrDeclaration === undefined) { | ||
if (!this.scanner.options.libDeclarations && !this.isExternalModule) { | ||
return this._isTsrDeclaration = false; | ||
} | ||
this._isTsrDeclaration = this.TSR_DECLARATION && | ||
this.scanner.isAllowedDeclarationSymbol(this.symbol) && | ||
(util.isPartOfTypeNode(this.enclosing) || (this.isReference && this.enclosing.getSourceFile().isDeclarationFile)); | ||
this.scanner.isAllowedDeclarationSymbol(this.symbol) | ||
&& (util.isPartOfTypeNode(this.enclosing) || (this.enclosing.getSourceFile().isDeclarationFile)); | ||
} | ||
@@ -226,3 +265,3 @@ return this._isTsrDeclaration; | ||
get sourceFile() { | ||
return this.firstDeclaration && this.firstDeclaration.getSourceFile(); | ||
return (this.firstDeclaration && this.firstDeclaration.getSourceFile()) || (this.enclosing && this.enclosing.getSourceFile()); | ||
} | ||
@@ -236,3 +275,3 @@ get fileName() { | ||
} | ||
return this.symbol.declarations; | ||
return this.symbol.getDeclarations(); | ||
} | ||
@@ -309,4 +348,4 @@ get firstDeclaration() { | ||
get isInDeclarationFile() { | ||
if (this.hasDeclarations() && this._isInDeclarationFile === undefined) { | ||
this._isInDeclarationFile = this.sourceFile.isDeclarationFile; | ||
if (this._isInDeclarationFile === undefined) { | ||
this._isInDeclarationFile = this.sourceFile && this.sourceFile.isDeclarationFile; | ||
} | ||
@@ -321,3 +360,9 @@ return this._isInDeclarationFile; | ||
} | ||
get isExternalModule() { | ||
if (this.hasDeclarations() && this._isExternalModule === undefined) { | ||
this._isExternalModule = ts.isExternalModule(this.sourceFile); | ||
} | ||
return this._isExternalModule; | ||
} | ||
} | ||
exports.TypeInfo = TypeInfo; |
@@ -63,3 +63,3 @@ "use strict"; | ||
emit(bus.events.SCAN, getElapsedTime()); | ||
scanner = new scanner_1.Scanner(program); | ||
scanner = new scanner_1.Scanner(program, options); | ||
emit(bus.events.TRANSFORM, sourceFiles, getElapsedTime()); | ||
@@ -137,2 +137,6 @@ const result = ts.transform(sourceFiles, [transformer], options.compilerOptions); | ||
const location = path.join(outDir, filename); | ||
rimraf.sync(location); | ||
const printerOptions = { | ||
removeComments: false | ||
}; | ||
const printHandlers = { | ||
@@ -145,3 +149,3 @@ substituteNode(hint, node) { | ||
}; | ||
const printer = ts.createPrinter(undefined, printHandlers); | ||
const printer = ts.createPrinter(printerOptions, printHandlers); | ||
let sf = ts.createSourceFile(filename, '', options.compilerOptions.target, true, ts.ScriptKind.TS); | ||
@@ -174,3 +178,3 @@ const expressions = []; | ||
...expressions.map(exp => { | ||
return ts.createStatement(context.factory.libCall('declare', exp)); | ||
return ts.createStatement(exp); | ||
}) | ||
@@ -180,3 +184,2 @@ ]); | ||
const transpiled = ts.transpile(printed, options.compilerOptions); | ||
rimraf.sync(location); | ||
ts.sys.writeFile(location, transpiled); | ||
@@ -183,0 +186,0 @@ } |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
188202
3.51%4117
4.2%634
1.44%