Socket
Socket
Sign inDemoInstall

tsickle

Package Overview
Dependencies
Maintainers
2
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tsickle - npm Package Compare versions

Comparing version 0.2.4 to 0.2.5

2

build/definitions/main.d.ts

@@ -15,5 +15,5 @@ import * as ts from 'typescript';

*/
export declare function toClosureJS(options: ts.CompilerOptions, fileNames: string[], settings: Settings, allDiagnostics: ts.Diagnostic[]): {
export declare function toClosureJS(options: ts.CompilerOptions, fileNames: string[], settings: Settings, allDiagnostics: ts.Diagnostic[], files?: Map<string, string>): {
jsFiles: Map<string, string>;
externs: string;
} | null;

@@ -6,3 +6,5 @@ export interface FileMap<T> {

export declare class ModulesManifest {
/** Map of googmodule module name to file name */
private moduleToFileName;
/** Map of file name to arrays of imported googmodule module names */
private referencedModules;

@@ -9,0 +11,0 @@ addModule(fileName: string, module: string): void;

@@ -0,15 +1,44 @@

import { SourceMapConsumer, SourceMapGenerator } from 'source-map';
import * as ts from 'typescript';
import { ModulesManifest } from './modules_manifest';
/**
* Tsickle can perform 2 different precompilation transforms - decorator downleveling
* and closurization. Both require tsc to have already type checked their
* input, so they can't both be run in one call to tsc. If you only want one of
* the transforms, you can specify it in the constructor, if you want both, you'll
* have to specify it by calling reconfigureForRun() with the appropriate Pass.
*/
export declare enum Pass {
None = 0,
DecoratorDownlevel = 1,
Tsickle = 2,
NONE = 0,
DECORATOR_DOWNLEVEL = 1,
CLOSURIZE = 2,
}
export interface TsickleCompilerHostOptions {
googmodule: boolean;
es5Mode: boolean;
tsickleTyped: boolean;
prelude: string;
export interface Options {
googmodule?: boolean;
es5Mode?: boolean;
prelude?: string;
/**
* If true, convert every type to the Closure {?} type, which means
* "don't check types".
*/
untyped?: boolean;
/**
* If provided a function that logs an internal warning.
* These warnings are not actionable by an end user and should be hidden
* by default.
*/
logWarning?: (warning: ts.Diagnostic) => void;
/** If provided, a set of paths whose types should always generate as {?}. */
typeBlackListPaths?: Set<string>;
/**
* Convert shorthand "/index" imports to full path (include the "/index").
* Annotation will be slower because every import must be resolved.
*/
convertIndexImportShorthand?: boolean;
}
export interface TsickleEnvironment {
/**
* Provides hooks to customize TsickleCompilerHost's behavior for different
* compilation environments.
*/
export interface TsickleHost {
/**

@@ -19,3 +48,3 @@ * If true, tsickle and decorator downlevel processing will be skipped for

*/
shouldSkipTsickleProcessing: (fileName: string) => boolean;
shouldSkipTsickleProcessing(fileName: string): boolean;
/**

@@ -25,3 +54,3 @@ * Takes a context (the current file) and the path of the file to import

*/
pathToModuleName: (context: string, importPath: string) => string;
pathToModuleName(context: string, importPath: string): string;
/**

@@ -31,3 +60,3 @@ * Tsickle treats warnings as errors, if true, ignore warnings. This might be

*/
shouldIgnoreWarningsForPath: (filePath: string) => boolean;
shouldIgnoreWarningsForPath(filePath: string): boolean;
/**

@@ -38,3 +67,3 @@ * If we do googmodule processing, we polyfill module.id, since that's

*/
fileNameToModuleId: (fileName: string) => string;
fileNameToModuleId(fileName: string): string;
}

@@ -48,7 +77,6 @@ /**

private delegate;
private tscOptions;
private options;
private environment;
private oldProgram;
private pass;
private ANNOTATION_SUPPORT;
private runConfiguration;
modulesManifest: ModulesManifest;

@@ -61,9 +89,27 @@ /** Error messages produced by tsickle, if any. */

};
constructor(delegate: ts.CompilerHost, options: TsickleCompilerHostOptions, environment: TsickleEnvironment, oldProgram?: ts.Program, pass?: Pass);
reconfigureForRun(program: ts.Program, pass: Pass): void;
private decoratorDownlevelSourceMaps;
private tsickleSourceMaps;
constructor(delegate: ts.CompilerHost, tscOptions: ts.CompilerOptions, options: Options, environment: TsickleHost, runConfiguration?: {
oldProgram: ts.Program;
pass: Pass;
});
/**
* Tsickle can perform 2 kinds of precompilation source transforms - decorator
* downleveling and closurization. They can't be run in the same run of the
* typescript compiler, because they both depend on type information that comes
* from running the compiler. We need to use the same compiler host to run both
* so we have all the source map data when finally write out. Thus if we want
* to run both transforms, we call reconfigureForRun() between the calls to
* ts.createProgram().
*/
reconfigureForRun(oldProgram: ts.Program, pass: Pass): void;
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void): ts.SourceFile;
writeFile(fileName: string, content: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: ts.SourceFile[]): void;
sourceMapConsumerToGenerator(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
sourceMapGeneratorToConsumer(sourceMapGenerator: SourceMapGenerator): SourceMapConsumer;
sourceMapTextToConsumer(sourceMapText: string): SourceMapConsumer;
combineSourceMaps(tscSourceMapText: string): string;
convertCommonJsToGoogModule(fileName: string, content: string): string;
private runDecoratorDownlevel(sourceFile, program, fileName, languageVersion);
private runTsickle(sourceFile, program, fileName, languageVersion);
private downlevelDecorators(sourceFile, program, fileName, languageVersion);
private closurize(sourceFile, program, fileName, languageVersion);
/** Concatenate all generated externs definitions together into a string. */

@@ -70,0 +116,0 @@ getGeneratedExterns(): string;

@@ -10,26 +10,7 @@ /**

import * as ts from 'typescript';
import { Options } from './tsickle_compiler_host';
export { convertDecorators } from './decorator-annotator';
export { processES5 } from './es5processor';
export { FileMap, ModulesManifest } from './modules_manifest';
export { Pass, TsickleCompilerHost, TsickleCompilerHostOptions, TsickleEnvironment } from './tsickle_compiler_host';
export interface Options {
/**
* If true, convert every type to the Closure {?} type, which means
* "don't check types".
*/
untyped?: boolean;
/**
* If provided a function that logs an internal warning.
* These warnings are not actionable by an end user and should be hidden
* by default.
*/
logWarning?: (warning: ts.Diagnostic) => void;
/** If provided, a set of paths whose types should always generate as {?}. */
typeBlackListPaths?: Set<string>;
/**
* Convert shorthand "/index" imports to full path (include the "/index").
* Annotation will be slower because every import must be resolved.
*/
convertIndexImportShorthand?: boolean;
}
export { Options, Pass, TsickleCompilerHost, TsickleHost } from './tsickle_compiler_host';
export interface Output {

@@ -36,0 +17,0 @@ /** The TypeScript source with Closure annotations inserted. */

@@ -93,3 +93,3 @@ #!/usr/bin/env node

*/
function toClosureJS(options, fileNames, settings, allDiagnostics) {
function toClosureJS(options, fileNames, settings, allDiagnostics, files) {
// Parse and load the program without tsickle processing.

@@ -99,3 +99,5 @@ // This is so:

// - tsickle can use the result of typechecking for annotation
var program = ts.createProgram(fileNames, options);
var program = files === undefined ?
ts.createProgram(fileNames, options) :
ts.createProgram(fileNames, options, util_1.createSourceReplacingCompilerHost(files, ts.createCompilerHost(options)));
{

@@ -111,6 +113,5 @@ var diagnostics_1 = ts.getPreEmitDiagnostics(program);

es5Mode: false,
tsickleTyped: !settings.isUntyped,
prelude: '',
untyped: settings.isUntyped,
};
var tsickleEnvironment = {
var tsickleHost = {
shouldSkipTsickleProcessing: function (fileName) { return fileNames.indexOf(fileName) === -1; },

@@ -125,3 +126,3 @@ pathToModuleName: cliSupport.pathToModuleName,

// place of the original source.
var host = new tsickle.TsickleCompilerHost(hostDelegate, tsickleCompilerHostOptions, tsickleEnvironment, program, tsickle.Pass.Tsickle);
var host = new tsickle.TsickleCompilerHost(hostDelegate, options, tsickleCompilerHostOptions, tsickleHost, { oldProgram: program, pass: tsickle.Pass.CLOSURIZE });
program = ts.createProgram(fileNames, options, host);

@@ -128,0 +129,0 @@ var diagnostics = program.emit(undefined).diagnostics;

@@ -5,5 +5,5 @@ "use strict";

function ModulesManifest() {
// Map of googmodule module name to file name
/** Map of googmodule module name to file name */
this.moduleToFileName = {};
// Map of file name to arrays of imported googmodule module names
/** Map of file name to arrays of imported googmodule module names */
this.referencedModules = {};

@@ -10,0 +10,0 @@ }

@@ -22,4 +22,2 @@ /**

this.diagnostics = [];
/** The source map that's generated while rewriting this file. */
this.sourceMap = new source_map_1.SourceMapGenerator();
/** Current position in the output. */

@@ -32,2 +30,3 @@ this.position = { line: 1, column: 1 };

this.indent = 0;
this.sourceMap = new source_map_1.SourceMapGenerator({ file: file.fileName });
this.sourceMap.addMapping({

@@ -34,0 +33,0 @@ original: this.position,

"use strict";
var path = require('path');
var source_map_1 = require('source-map');
var ts = require('typescript');

@@ -7,8 +9,16 @@ var decorator_annotator_1 = require('./decorator-annotator');

var tsickle_1 = require('./tsickle');
/**
* Tsickle can perform 2 different precompilation transforms - decorator downleveling
* and closurization. Both require tsc to have already type checked their
* input, so they can't both be run in one call to tsc. If you only want one of
* the transforms, you can specify it in the constructor, if you want both, you'll
* have to specify it by calling reconfigureForRun() with the appropriate Pass.
*/
(function (Pass) {
Pass[Pass["None"] = 0] = "None";
Pass[Pass["DecoratorDownlevel"] = 1] = "DecoratorDownlevel";
Pass[Pass["Tsickle"] = 2] = "Tsickle";
Pass[Pass["NONE"] = 0] = "NONE";
Pass[Pass["DECORATOR_DOWNLEVEL"] = 1] = "DECORATOR_DOWNLEVEL";
Pass[Pass["CLOSURIZE"] = 2] = "CLOSURIZE";
})(exports.Pass || (exports.Pass = {}));
var Pass = exports.Pass;
var ANNOTATION_SUPPORT = "\ninterface DecoratorInvocation {\n type: Function;\n args?: any[];\n}\n";
/**

@@ -20,10 +30,8 @@ * TsickleCompilerHost does tsickle processing of input files, including

var TsickleCompilerHost = (function () {
function TsickleCompilerHost(delegate, options, environment, oldProgram, pass) {
if (pass === void 0) { pass = Pass.None; }
function TsickleCompilerHost(delegate, tscOptions, options, environment, runConfiguration) {
this.delegate = delegate;
this.tscOptions = tscOptions;
this.options = options;
this.environment = environment;
this.oldProgram = oldProgram;
this.pass = pass;
this.ANNOTATION_SUPPORT = "\ninterface DecoratorInvocation {\n type: Function;\n args?: any[];\n}\n";
this.runConfiguration = runConfiguration;
// The manifest of JS modules output by the compiler.

@@ -35,20 +43,27 @@ this.modulesManifest = new modules_manifest_1.ModulesManifest();

this.externs = {};
this.decoratorDownlevelSourceMaps = new Map();
this.tsickleSourceMaps = new Map();
}
TsickleCompilerHost.prototype.reconfigureForRun = function (program, pass) {
this.oldProgram = program;
this.pass = pass;
/**
* Tsickle can perform 2 kinds of precompilation source transforms - decorator
* downleveling and closurization. They can't be run in the same run of the
* typescript compiler, because they both depend on type information that comes
* from running the compiler. We need to use the same compiler host to run both
* so we have all the source map data when finally write out. Thus if we want
* to run both transforms, we call reconfigureForRun() between the calls to
* ts.createProgram().
*/
TsickleCompilerHost.prototype.reconfigureForRun = function (oldProgram, pass) {
this.runConfiguration = { oldProgram: oldProgram, pass: pass };
};
TsickleCompilerHost.prototype.getSourceFile = function (fileName, languageVersion, onError) {
if (this.pass === Pass.None) {
if (this.runConfiguration === undefined || this.runConfiguration.pass === Pass.NONE) {
return this.delegate.getSourceFile(fileName, languageVersion, onError);
}
if (!this.oldProgram) {
throw new Error('tried to run a pass other than None without setting a program');
}
var sourceFile = this.oldProgram.getSourceFile(fileName);
switch (this.pass) {
case Pass.DecoratorDownlevel:
return this.runDecoratorDownlevel(sourceFile, this.oldProgram, fileName, languageVersion);
case Pass.Tsickle:
return this.runTsickle(sourceFile, this.oldProgram, fileName, languageVersion);
var sourceFile = this.runConfiguration.oldProgram.getSourceFile(fileName);
switch (this.runConfiguration.pass) {
case Pass.DECORATOR_DOWNLEVEL:
return this.downlevelDecorators(sourceFile, this.runConfiguration.oldProgram, fileName, languageVersion);
case Pass.CLOSURIZE:
return this.closurize(sourceFile, this.runConfiguration.oldProgram, fileName, languageVersion);
default:

@@ -59,8 +74,47 @@ throw new Error('tried to use TsickleCompilerHost with unknown pass enum');

TsickleCompilerHost.prototype.writeFile = function (fileName, content, writeByteOrderMark, onError, sourceFiles) {
fileName = this.delegate.getCanonicalFileName(fileName);
if (this.options.googmodule && !fileName.match(/\.d\.ts$/)) {
content = this.convertCommonJsToGoogModule(fileName, content);
if (path.extname(fileName) !== '.map') {
fileName = this.delegate.getCanonicalFileName(fileName);
if (this.options.googmodule && !fileName.match(/\.d\.ts$/)) {
content = this.convertCommonJsToGoogModule(fileName, content);
}
}
else {
content = this.combineSourceMaps(content);
}
this.delegate.writeFile(fileName, content, writeByteOrderMark, onError, sourceFiles);
};
TsickleCompilerHost.prototype.sourceMapConsumerToGenerator = function (sourceMapConsumer) {
return source_map_1.SourceMapGenerator.fromSourceMap(sourceMapConsumer);
};
TsickleCompilerHost.prototype.sourceMapGeneratorToConsumer = function (sourceMapGenerator) {
var rawSourceMap = sourceMapGenerator.toJSON();
return new source_map_1.SourceMapConsumer(rawSourceMap);
};
TsickleCompilerHost.prototype.sourceMapTextToConsumer = function (sourceMapText) {
var sourceMapJson = sourceMapText;
return new source_map_1.SourceMapConsumer(sourceMapJson);
};
TsickleCompilerHost.prototype.combineSourceMaps = function (tscSourceMapText) {
var tscSourceMapConsumer = this.sourceMapTextToConsumer(tscSourceMapText);
var tscSourceMapGenerator = this.sourceMapConsumerToGenerator(tscSourceMapConsumer);
if (this.tsickleSourceMaps.size > 0) {
// TODO(lucassloan): remove when the .d.ts has the correct types
for (var _i = 0, _a = tscSourceMapConsumer.sources; _i < _a.length; _i++) {
var sourceFileName = _a[_i];
var tsickleSourceMapGenerator = this.tsickleSourceMaps.get(sourceFileName);
var tsickleSourceMapConsumer = this.sourceMapGeneratorToConsumer(tsickleSourceMapGenerator);
tscSourceMapGenerator.applySourceMap(tsickleSourceMapConsumer);
}
}
if (this.decoratorDownlevelSourceMaps.size > 0) {
// TODO(lucassloan): remove when the .d.ts has the correct types
for (var _b = 0, _c = tscSourceMapConsumer.sources; _b < _c.length; _b++) {
var sourceFileName = _c[_b];
var decoratorDownlevelSourceMapGenerator = this.decoratorDownlevelSourceMaps.get(sourceFileName);
var decoratorDownlevelSourceMapConsumer = this.sourceMapGeneratorToConsumer(decoratorDownlevelSourceMapGenerator);
tscSourceMapGenerator.applySourceMap(decoratorDownlevelSourceMapConsumer);
}
}
return tscSourceMapGenerator.toString();
};
TsickleCompilerHost.prototype.convertCommonJsToGoogModule = function (fileName, content) {

@@ -77,3 +131,3 @@ var moduleId = this.environment.fileNameToModuleId(fileName);

};
TsickleCompilerHost.prototype.runDecoratorDownlevel = function (sourceFile, program, fileName, languageVersion) {
TsickleCompilerHost.prototype.downlevelDecorators = function (sourceFile, program, fileName, languageVersion) {
if (this.environment.shouldSkipTsickleProcessing(fileName))

@@ -90,7 +144,8 @@ return sourceFile;

}
fileContent = converted.output + this.ANNOTATION_SUPPORT;
fileContent = converted.output + ANNOTATION_SUPPORT;
this.decoratorDownlevelSourceMaps.set(fileName, converted.sourceMap);
return ts.createSourceFile(fileName, fileContent, languageVersion, true);
var _a;
};
TsickleCompilerHost.prototype.runTsickle = function (sourceFile, program, fileName, languageVersion) {
TsickleCompilerHost.prototype.closurize = function (sourceFile, program, fileName, languageVersion) {
var isDefinitions = /\.d\.ts$/.test(fileName);

@@ -101,3 +156,3 @@ // Don't tsickle-process any d.ts that isn't a compilation target;

return sourceFile;
var _a = tsickle_1.annotate(program, sourceFile, { untyped: !this.options.tsickleTyped }), output = _a.output, externs = _a.externs, diagnostics = _a.diagnostics;
var _a = tsickle_1.annotate(program, sourceFile, this.options, this.delegate, this.tscOptions), output = _a.output, externs = _a.externs, diagnostics = _a.diagnostics, sourceMap = _a.sourceMap;
if (externs) {

@@ -114,2 +169,3 @@ this.externs[fileName] = externs;

this.diagnostics = diagnostics;
this.tsickleSourceMaps.set(path.parse(fileName).base, sourceMap);
return ts.createSourceFile(fileName, output, languageVersion, true);

@@ -116,0 +172,0 @@ };

{
"name": "tsickle",
"version": "0.2.4",
"version": "0.2.5",
"description": "Transpile TypeScript code to JavaScript with Closure annotations.",

@@ -5,0 +5,0 @@ "main": "build/src/tsickle.js",

@@ -19,4 +19,3 @@ #!/usr/bin/env node

import * as tsickle from './tsickle';
import {toArray, createOutputRetainingCompilerHost} from './util';
import {toArray, createOutputRetainingCompilerHost, createSourceReplacingCompilerHost} from './util';
/** Tsickle settings passed on the command line. */

@@ -134,3 +133,4 @@ export interface Settings {

options: ts.CompilerOptions, fileNames: string[], settings: Settings,
allDiagnostics: ts.Diagnostic[]): {jsFiles: Map<string, string>, externs: string}|null {
allDiagnostics: ts.Diagnostic[],
files?: Map<string, string>): {jsFiles: Map<string, string>, externs: string}|null {
// Parse and load the program without tsickle processing.

@@ -140,3 +140,7 @@ // This is so:

// - tsickle can use the result of typechecking for annotation
let program = ts.createProgram(fileNames, options);
let program = files === undefined ?
ts.createProgram(fileNames, options) :
ts.createProgram(
fileNames, options,
createSourceReplacingCompilerHost(files, ts.createCompilerHost(options)));
{ // Scope for the "diagnostics" variable so we can use the name again later.

@@ -150,10 +154,9 @@ let diagnostics = ts.getPreEmitDiagnostics(program);

const tsickleCompilerHostOptions: tsickle.TsickleCompilerHostOptions = {
const tsickleCompilerHostOptions: tsickle.Options = {
googmodule: true,
es5Mode: false,
tsickleTyped: !settings.isUntyped,
prelude: '',
untyped: settings.isUntyped,
};
const tsickleEnvironment: tsickle.TsickleEnvironment = {
const tsickleHost: tsickle.TsickleHost = {
shouldSkipTsickleProcessing: (fileName) => fileNames.indexOf(fileName) === -1,

@@ -171,3 +174,4 @@ pathToModuleName: cliSupport.pathToModuleName,

let host = new tsickle.TsickleCompilerHost(
hostDelegate, tsickleCompilerHostOptions, tsickleEnvironment, program, tsickle.Pass.Tsickle);
hostDelegate, options, tsickleCompilerHostOptions, tsickleHost,
{oldProgram: program, pass: tsickle.Pass.CLOSURIZE});
program = ts.createProgram(fileNames, options, host);

@@ -174,0 +178,0 @@

@@ -5,5 +5,5 @@ export interface FileMap<T> { [fileName: string]: T; }

export class ModulesManifest {
// Map of googmodule module name to file name
/** Map of googmodule module name to file name */
private moduleToFileName: FileMap<string> = {};
// Map of file name to arrays of imported googmodule module names
/** Map of file name to arrays of imported googmodule module names */
private referencedModules: FileMap<string[]> = {};

@@ -10,0 +10,0 @@

@@ -22,3 +22,3 @@ /**

/** The source map that's generated while rewriting this file. */
private sourceMap = new SourceMapGenerator();
private sourceMap: SourceMapGenerator;
/** Current position in the output. */

@@ -33,2 +33,3 @@ private position = {line: 1, column: 1};

constructor(protected file: ts.SourceFile) {
this.sourceMap = new SourceMapGenerator({file: file.fileName});
this.sourceMap.addMapping({

@@ -35,0 +36,0 @@ original: this.position,

@@ -0,1 +1,3 @@

import * as path from 'path';
import {SourceMapConsumer, SourceMapGenerator} from 'source-map';
import * as ts from 'typescript';

@@ -8,16 +10,44 @@

/**
* Tsickle can perform 2 different precompilation transforms - decorator downleveling
* and closurization. Both require tsc to have already type checked their
* input, so they can't both be run in one call to tsc. If you only want one of
* the transforms, you can specify it in the constructor, if you want both, you'll
* have to specify it by calling reconfigureForRun() with the appropriate Pass.
*/
export enum Pass {
None,
DecoratorDownlevel,
Tsickle
NONE,
DECORATOR_DOWNLEVEL,
CLOSURIZE
}
export interface TsickleCompilerHostOptions {
googmodule: boolean;
es5Mode: boolean;
tsickleTyped: boolean;
prelude: string;
export interface Options {
googmodule?: boolean;
es5Mode?: boolean;
prelude?: string;
/**
* If true, convert every type to the Closure {?} type, which means
* "don't check types".
*/
untyped?: boolean;
/**
* If provided a function that logs an internal warning.
* These warnings are not actionable by an end user and should be hidden
* by default.
*/
logWarning?: (warning: ts.Diagnostic) => void;
/** If provided, a set of paths whose types should always generate as {?}. */
typeBlackListPaths?: Set<string>;
/**
* Convert shorthand "/index" imports to full path (include the "/index").
* Annotation will be slower because every import must be resolved.
*/
convertIndexImportShorthand?: boolean;
}
export interface TsickleEnvironment {
/**
* Provides hooks to customize TsickleCompilerHost's behavior for different
* compilation environments.
*/
export interface TsickleHost {
/**

@@ -27,3 +57,3 @@ * If true, tsickle and decorator downlevel processing will be skipped for

*/
shouldSkipTsickleProcessing: (fileName: string) => boolean;
shouldSkipTsickleProcessing(fileName: string): boolean;
/**

@@ -33,3 +63,3 @@ * Takes a context (the current file) and the path of the file to import

*/
pathToModuleName: (context: string, importPath: string) => string;
pathToModuleName(context: string, importPath: string): string;
/**

@@ -39,3 +69,3 @@ * Tsickle treats warnings as errors, if true, ignore warnings. This might be

*/
shouldIgnoreWarningsForPath: (filePath: string) => boolean;
shouldIgnoreWarningsForPath(filePath: string): boolean;
/**

@@ -46,5 +76,13 @@ * If we do googmodule processing, we polyfill module.id, since that's

*/
fileNameToModuleId: (fileName: string) => string;
fileNameToModuleId(fileName: string): string;
}
const ANNOTATION_SUPPORT = `
interface DecoratorInvocation {
type: Function;
args?: any[];
}
`;
/**

@@ -56,8 +94,2 @@ * TsickleCompilerHost does tsickle processing of input files, including

export class TsickleCompilerHost implements ts.CompilerHost {
private ANNOTATION_SUPPORT = `
interface DecoratorInvocation {
type: Function;
args?: any[];
}
`;
// The manifest of JS modules output by the compiler.

@@ -72,11 +104,21 @@ public modulesManifest: ModulesManifest = new ModulesManifest();

private decoratorDownlevelSourceMaps = new Map<string, SourceMapGenerator>();
private tsickleSourceMaps = new Map<string, SourceMapGenerator>();
constructor(
private delegate: ts.CompilerHost, private options: TsickleCompilerHostOptions,
private environment: TsickleEnvironment, private oldProgram?: ts.Program,
private pass = Pass.None) {}
private delegate: ts.CompilerHost, private tscOptions: ts.CompilerOptions,
private options: Options, private environment: TsickleHost,
private runConfiguration?: {oldProgram: ts.Program, pass: Pass}) {}
public reconfigureForRun(program: ts.Program, pass: Pass) {
this.oldProgram = program;
this.pass = pass;
/**
* Tsickle can perform 2 kinds of precompilation source transforms - decorator
* downleveling and closurization. They can't be run in the same run of the
* typescript compiler, because they both depend on type information that comes
* from running the compiler. We need to use the same compiler host to run both
* so we have all the source map data when finally write out. Thus if we want
* to run both transforms, we call reconfigureForRun() between the calls to
* ts.createProgram().
*/
public reconfigureForRun(oldProgram: ts.Program, pass: Pass) {
this.runConfiguration = {oldProgram, pass};
}

@@ -87,16 +129,14 @@

onError?: (message: string) => void): ts.SourceFile {
if (this.pass === Pass.None) {
if (this.runConfiguration === undefined || this.runConfiguration.pass === Pass.NONE) {
return this.delegate.getSourceFile(fileName, languageVersion, onError);
}
if (!this.oldProgram) {
throw new Error('tried to run a pass other than None without setting a program');
}
const sourceFile = this.oldProgram.getSourceFile(fileName);
switch (this.pass) {
case Pass.DecoratorDownlevel:
return this.runDecoratorDownlevel(sourceFile, this.oldProgram, fileName, languageVersion);
case Pass.Tsickle:
return this.runTsickle(sourceFile, this.oldProgram, fileName, languageVersion);
const sourceFile = this.runConfiguration.oldProgram.getSourceFile(fileName);
switch (this.runConfiguration.pass) {
case Pass.DECORATOR_DOWNLEVEL:
return this.downlevelDecorators(
sourceFile, this.runConfiguration.oldProgram, fileName, languageVersion);
case Pass.CLOSURIZE:
return this.closurize(
sourceFile, this.runConfiguration.oldProgram, fileName, languageVersion);
default:

@@ -110,5 +150,9 @@ throw new Error('tried to use TsickleCompilerHost with unknown pass enum');

onError?: (message: string) => void, sourceFiles?: ts.SourceFile[]): void {
fileName = this.delegate.getCanonicalFileName(fileName);
if (this.options.googmodule && !fileName.match(/\.d\.ts$/)) {
content = this.convertCommonJsToGoogModule(fileName, content);
if (path.extname(fileName) !== '.map') {
fileName = this.delegate.getCanonicalFileName(fileName);
if (this.options.googmodule && !fileName.match(/\.d\.ts$/)) {
content = this.convertCommonJsToGoogModule(fileName, content);
}
} else {
content = this.combineSourceMaps(content);
}

@@ -119,2 +163,42 @@

sourceMapConsumerToGenerator(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator {
return SourceMapGenerator.fromSourceMap(sourceMapConsumer);
}
sourceMapGeneratorToConsumer(sourceMapGenerator: SourceMapGenerator): SourceMapConsumer {
const rawSourceMap = sourceMapGenerator.toJSON();
return new SourceMapConsumer(rawSourceMap);
}
sourceMapTextToConsumer(sourceMapText: string): SourceMapConsumer {
const sourceMapJson: any = sourceMapText;
return new SourceMapConsumer(sourceMapJson);
}
combineSourceMaps(tscSourceMapText: string): string {
const tscSourceMapConsumer = this.sourceMapTextToConsumer(tscSourceMapText);
const tscSourceMapGenerator = this.sourceMapConsumerToGenerator(tscSourceMapConsumer);
if (this.tsickleSourceMaps.size > 0) {
// TODO(lucassloan): remove when the .d.ts has the correct types
for (const sourceFileName of (tscSourceMapConsumer as any).sources) {
const tsickleSourceMapGenerator = this.tsickleSourceMaps.get(sourceFileName)!;
const tsickleSourceMapConsumer =
this.sourceMapGeneratorToConsumer(tsickleSourceMapGenerator);
tscSourceMapGenerator.applySourceMap(tsickleSourceMapConsumer);
}
}
if (this.decoratorDownlevelSourceMaps.size > 0) {
// TODO(lucassloan): remove when the .d.ts has the correct types
for (const sourceFileName of (tscSourceMapConsumer as any).sources) {
const decoratorDownlevelSourceMapGenerator =
this.decoratorDownlevelSourceMaps.get(sourceFileName)!;
const decoratorDownlevelSourceMapConsumer =
this.sourceMapGeneratorToConsumer(decoratorDownlevelSourceMapGenerator);
tscSourceMapGenerator.applySourceMap(decoratorDownlevelSourceMapConsumer);
}
}
return tscSourceMapGenerator.toString();
}
convertCommonJsToGoogModule(fileName: string, content: string): string {

@@ -136,3 +220,3 @@ const moduleId = this.environment.fileNameToModuleId(fileName);

private runDecoratorDownlevel(
private downlevelDecorators(
sourceFile: ts.SourceFile, program: ts.Program, fileName: string,

@@ -150,7 +234,8 @@ languageVersion: ts.ScriptTarget): ts.SourceFile {

}
fileContent = converted.output + this.ANNOTATION_SUPPORT;
fileContent = converted.output + ANNOTATION_SUPPORT;
this.decoratorDownlevelSourceMaps.set(fileName, converted.sourceMap);
return ts.createSourceFile(fileName, fileContent, languageVersion, true);
}
private runTsickle(
private closurize(
sourceFile: ts.SourceFile, program: ts.Program, fileName: string,

@@ -163,4 +248,4 @@ languageVersion: ts.ScriptTarget): ts.SourceFile {

let {output, externs, diagnostics} =
annotate(program, sourceFile, {untyped: !this.options.tsickleTyped});
let {output, externs, diagnostics, sourceMap} =
annotate(program, sourceFile, this.options, this.delegate, this.tscOptions);
if (externs) {

@@ -177,2 +262,3 @@ this.externs[fileName] = externs;

this.diagnostics = diagnostics;
this.tsickleSourceMaps.set(path.parse(fileName).base, sourceMap);
return ts.createSourceFile(fileName, output, languageVersion, true);

@@ -179,0 +265,0 @@ }

@@ -14,2 +14,3 @@ /**

import {getIdentifierText, Rewriter, unescapeName} from './rewriter';
import {Options} from './tsickle_compiler_host';
import {assertTypeChecked, TypeTranslator} from './type-translator';

@@ -21,25 +22,4 @@ import {toArray} from './util';

export {FileMap, ModulesManifest} from './modules_manifest';
export {Pass, TsickleCompilerHost, TsickleCompilerHostOptions, TsickleEnvironment} from './tsickle_compiler_host';
export {Options, Pass, TsickleCompilerHost, TsickleHost} from './tsickle_compiler_host';
export interface Options {
/**
* If true, convert every type to the Closure {?} type, which means
* "don't check types".
*/
untyped?: boolean;
/**
* If provided a function that logs an internal warning.
* These warnings are not actionable by an end user and should be hidden
* by default.
*/
logWarning?: (warning: ts.Diagnostic) => void;
/** If provided, a set of paths whose types should always generate as {?}. */
typeBlackListPaths?: Set<string>;
/**
* Convert shorthand "/index" imports to full path (include the "/index").
* Annotation will be slower because every import must be resolved.
*/
convertIndexImportShorthand?: boolean;
}
export interface Output {

@@ -46,0 +26,0 @@ /** The TypeScript source with Closure annotations inserted. */

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc