diff --git a/README.md b/README.md index be0aa120..ac7bffd7 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,10 @@ Plugin takes following options: If true, declaration files will be emitted in the directory given in the tsconfig. If false, the declaration files will be placed inside the destination directory given in the Rollup configuration. +* `typescript`: typescript module installed with the plugin + + When typescript version installed by the plugin (latest 2.x) is unacceptable, you can import your own typescript module and pass it in as `typescript: require("typescript")`. Must be 2.0+, things might break if transpiler interfaces changed enough from what the plugin was built against. + ### Declarations This plugin respects `declaration: true` in your `tsconfig.json` file. When set, it will emit `*.d.ts` files for your bundle. The resulting file(s) can then be used with the `types` property in your `package.json` file as described [here](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html). diff --git a/dist/get-options-overrides.d.ts b/dist/get-options-overrides.d.ts index cb8433af..08928408 100644 --- a/dist/get-options-overrides.d.ts +++ b/dist/get-options-overrides.d.ts @@ -1,3 +1,3 @@ -import { CompilerOptions } from "typescript"; +import * as tsTypes from "typescript"; import { IOptions } from "./ioptions"; -export declare function getOptionsOverrides({useTsconfigDeclarationDir}: IOptions, tsConfigJson?: any): CompilerOptions; +export declare function getOptionsOverrides({useTsconfigDeclarationDir}: IOptions, tsConfigJson?: any): tsTypes.CompilerOptions; diff --git a/dist/host.d.ts b/dist/host.d.ts index e710cbc5..39405b82 100644 --- a/dist/host.d.ts +++ b/dist/host.d.ts @@ -1,18 +1,18 @@ -import { LanguageServiceHost as TypescriptLanguageServiceHost, IScriptSnapshot, ParsedCommandLine, CompilerOptions } from "typescript"; -export declare class LanguageServiceHost implements TypescriptLanguageServiceHost { +import * as tsTypes from "typescript"; +export declare class LanguageServiceHost implements tsTypes.LanguageServiceHost { private parsedConfig; private cwd; private snapshots; private versions; - constructor(parsedConfig: ParsedCommandLine); + constructor(parsedConfig: tsTypes.ParsedCommandLine); reset(): void; - setSnapshot(fileName: string, data: string): IScriptSnapshot; - getScriptSnapshot(fileName: string): IScriptSnapshot | undefined; + setSnapshot(fileName: string, data: string): tsTypes.IScriptSnapshot; + getScriptSnapshot(fileName: string): tsTypes.IScriptSnapshot | undefined; getCurrentDirectory(): string; getScriptVersion(fileName: string): string; getScriptFileNames(): string[]; - getCompilationSettings(): CompilerOptions; - getDefaultLibFileName(opts: CompilerOptions): string; + getCompilationSettings(): tsTypes.CompilerOptions; + getDefaultLibFileName(opts: tsTypes.CompilerOptions): string; useCaseSensitiveFileNames(): boolean; readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[]; readFile(path: string, encoding?: string): string; diff --git a/dist/parse-ts-config.d.ts b/dist/parse-ts-config.d.ts index 00583464..a3752fc4 100644 --- a/dist/parse-ts-config.d.ts +++ b/dist/parse-ts-config.d.ts @@ -1,4 +1,4 @@ -import { ParsedCommandLine } from "typescript"; +import * as tsTypes from "typescript"; import { IContext } from "./context"; import { IOptions } from "./ioptions"; -export declare function parseTsConfig(tsconfig: string, context: IContext, pluginOptions: IOptions): ParsedCommandLine; +export declare function parseTsConfig(tsconfig: string, context: IContext, pluginOptions: IOptions): tsTypes.ParsedCommandLine; diff --git a/dist/rollup-plugin-typescript2.cjs.js b/dist/rollup-plugin-typescript2.cjs.js index 2561051c..0e27441d 100644 --- a/dist/rollup-plugin-typescript2.cjs.js +++ b/dist/rollup-plugin-typescript2.cjs.js @@ -2,7 +2,6 @@ 'use strict'; var lodash = require('lodash'); -var typescript = require('typescript'); var fs = require('fs'); var graphlib = require('graphlib'); var objectHash = require('object-hash'); @@ -116,6 +115,11 @@ var RollupContext = (function () { return RollupContext; }()); +var tsModule; +function setTypescriptModule(override) { + tsModule = override; +} + var LanguageServiceHost = (function () { function LanguageServiceHost(parsedConfig) { this.parsedConfig = parsedConfig; @@ -129,7 +133,7 @@ var LanguageServiceHost = (function () { }; LanguageServiceHost.prototype.setSnapshot = function (fileName, data) { fileName = this.normalize(fileName); - var snapshot = typescript.ScriptSnapshot.fromString(data); + var snapshot = tsModule.ScriptSnapshot.fromString(data); this.snapshots[fileName] = snapshot; this.versions[fileName] = (this.versions[fileName] || 0) + 1; return snapshot; @@ -139,7 +143,7 @@ var LanguageServiceHost = (function () { if (lodash.has(this.snapshots, fileName)) return this.snapshots[fileName]; if (fs.existsSync(fileName)) { - this.snapshots[fileName] = typescript.ScriptSnapshot.fromString(typescript.sys.readFile(fileName)); + this.snapshots[fileName] = tsModule.ScriptSnapshot.fromString(tsModule.sys.readFile(fileName)); this.versions[fileName] = (this.versions[fileName] || 0) + 1; return this.snapshots[fileName]; } @@ -159,28 +163,28 @@ var LanguageServiceHost = (function () { return this.parsedConfig.options; }; LanguageServiceHost.prototype.getDefaultLibFileName = function (opts) { - return typescript.getDefaultLibFilePath(opts); + return tsModule.getDefaultLibFilePath(opts); }; LanguageServiceHost.prototype.useCaseSensitiveFileNames = function () { - return typescript.sys.useCaseSensitiveFileNames; + return tsModule.sys.useCaseSensitiveFileNames; }; LanguageServiceHost.prototype.readDirectory = function (path$$1, extensions, exclude, include) { - return typescript.sys.readDirectory(path$$1, extensions, exclude, include); + return tsModule.sys.readDirectory(path$$1, extensions, exclude, include); }; LanguageServiceHost.prototype.readFile = function (path$$1, encoding) { - return typescript.sys.readFile(path$$1, encoding); + return tsModule.sys.readFile(path$$1, encoding); }; LanguageServiceHost.prototype.fileExists = function (path$$1) { - return typescript.sys.fileExists(path$$1); + return tsModule.sys.fileExists(path$$1); }; LanguageServiceHost.prototype.getTypeRootsVersion = function () { return 0; }; LanguageServiceHost.prototype.directoryExists = function (directoryName) { - return typescript.sys.directoryExists(directoryName); + return tsModule.sys.directoryExists(directoryName); }; LanguageServiceHost.prototype.getDirectories = function (directoryName) { - return typescript.sys.getDirectories(directoryName); + return tsModule.sys.getDirectories(directoryName); }; LanguageServiceHost.prototype.normalize = function (fileName) { return fileName.split("\\").join("/"); @@ -264,7 +268,7 @@ var RollingCache = (function () { function convertDiagnostic(type, data) { return lodash.map(data, function (diagnostic) { var entry = { - flatMessage: typescript.flattenDiagnosticMessageText(diagnostic.messageText, "\n"), + flatMessage: tsModule.flattenDiagnosticMessageText(diagnostic.messageText, "\n"), category: diagnostic.category, code: diagnostic.code, type: type, @@ -290,11 +294,11 @@ var TsCache = (function () { rootFilenames: rootFilenames, options: this.options, rollupConfig: this.rollupConfig, - tsVersion: typescript.version, + tsVersion: tsModule.version, }); this.dependencyTree = new graphlib.Graph({ directed: true }); this.dependencyTree.setDefaultNodeLabel(function (_node) { return ({ dirty: false }); }); - var automaticTypes = lodash.map(typescript.getAutomaticTypeDirectiveNames(options, typescript.sys), function (entry) { return typescript.resolveTypeReferenceDirective(entry, undefined, options, typescript.sys); }) + var automaticTypes = lodash.map(tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys), function (entry) { return tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys); }) .filter(function (entry) { return entry.resolvedTypeReferenceDirective && entry.resolvedTypeReferenceDirective.resolvedFileName; }) .map(function (entry) { return entry.resolvedTypeReferenceDirective.resolvedFileName; }); this.ambientTypes = lodash.filter(rootFilenames, function (file) { return lodash.endsWith(file, ".d.ts"); }) @@ -424,17 +428,17 @@ function printDiagnostics(context, diagnostics) { var color; var category; switch (diagnostic.category) { - case typescript.DiagnosticCategory.Message: + case tsModule.DiagnosticCategory.Message: print = context.info; color = colors_safe.white; category = ""; break; - case typescript.DiagnosticCategory.Error: + case tsModule.DiagnosticCategory.Error: print = context.error; color = colors_safe.red; category = "error"; break; - case typescript.DiagnosticCategory.Warning: + case tsModule.DiagnosticCategory.Warning: default: print = context.warn; color = colors_safe.yellow; @@ -452,20 +456,20 @@ function printDiagnostics(context, diagnostics) { function getOptionsOverrides(_a, tsConfigJson) { var useTsconfigDeclarationDir = _a.useTsconfigDeclarationDir; var declaration = lodash.get(tsConfigJson, "compilerOptions.declaration", false); - return __assign({ module: typescript.ModuleKind.ES2015, noEmitHelpers: true, importHelpers: true, noResolve: false, outDir: process.cwd() }, (!declaration || useTsconfigDeclarationDir ? {} : { declarationDir: process.cwd() })); + return __assign({ module: tsModule.ModuleKind.ES2015, noEmitHelpers: true, importHelpers: true, noResolve: false, outDir: process.cwd() }, (!declaration || useTsconfigDeclarationDir ? {} : { declarationDir: process.cwd() })); } function parseTsConfig(tsconfig, context, pluginOptions) { - var fileName = typescript.findConfigFile(process.cwd(), typescript.sys.fileExists, tsconfig); + var fileName = tsModule.findConfigFile(process.cwd(), tsModule.sys.fileExists, tsconfig); if (!fileName) throw new Error("couldn't find '" + tsconfig + "' in " + process.cwd()); - var text = typescript.sys.readFile(fileName); - var result = typescript.parseConfigFileTextToJson(fileName, text); + var text = tsModule.sys.readFile(fileName); + var result = tsModule.parseConfigFileTextToJson(fileName, text); if (result.error) { printDiagnostics(context, convertDiagnostic("config", [result.error])); throw new Error("failed to parse " + fileName); } - return typescript.parseJsonConfigFileContent(result.config, typescript.sys, path.dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); + return tsModule.parseJsonConfigFileContent(result.config, tsModule.sys, path.dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); } // The injected id for helpers. @@ -481,7 +485,7 @@ catch (e) { throw e; } -function typescript$1(options) { +function typescript(options) { // tslint:disable-next-line:no-var-requires var createFilter = require("rollup-pluginutils").createFilter; // tslint:enable-next-line:no-var-requires @@ -514,17 +518,19 @@ function typescript$1(options) { rollupCommonJSResolveHack: false, tsconfig: "tsconfig.json", useTsconfigDeclarationDir: false, + typescript: require("typescript"), }); + setTypescriptModule(pluginOptions.typescript); return { options: function (config) { rollupOptions = config; context = new ConsoleContext(pluginOptions.verbosity, "rpt2: "); - context.info("Typescript version: " + typescript.version); - context.debug("Plugin Options: " + JSON.stringify(pluginOptions, undefined, 4)); + context.info("Typescript version: " + tsModule.version); + context.debug("Plugin Options: " + JSON.stringify(pluginOptions, function (key, value) { return key === "typescript" ? "version " + value.version : value; }, 4)); filter$$1 = createFilter(pluginOptions.include, pluginOptions.exclude); parsedConfig = parseTsConfig(pluginOptions.tsconfig, context, pluginOptions); servicesHost = new LanguageServiceHost(parsedConfig); - service = typescript.createLanguageService(servicesHost, typescript.createDocumentRegistry()); + service = tsModule.createLanguageService(servicesHost, tsModule.createDocumentRegistry()); // printing compiler option errors if (pluginOptions.check) printDiagnostics(context, convertDiagnostic("options", service.getCompilerOptionsDiagnostics())); @@ -539,7 +545,7 @@ function typescript$1(options) { return null; importer = importer.split("\\").join("/"); // TODO: use module resolution cache - var result = typescript.nodeModuleNameResolver(importee, importer, parsedConfig.options, typescript.sys); + var result = tsModule.nodeModuleNameResolver(importee, importer, parsedConfig.options, tsModule.sys); if (result.resolvedModule && result.resolvedModule.resolvedFileName) { if (filter$$1(result.resolvedModule.resolvedFileName)) cache().setDependency(result.resolvedModule.resolvedFileName, importer); @@ -643,10 +649,10 @@ function typescript$1(options) { writeToPath = path.join(destDirectory, path.relative(baseDeclarationDir, name)); } // Write the declaration file to disk. - typescript.sys.writeFile(writeToPath, text, writeByteOrderMark); + tsModule.sys.writeFile(writeToPath, text, writeByteOrderMark); }); }, }; } -module.exports = typescript$1; +module.exports = typescript; diff --git a/dist/rollup-plugin-typescript2.es.js b/dist/rollup-plugin-typescript2.es.js index d0997d6a..625c83f7 100644 --- a/dist/rollup-plugin-typescript2.es.js +++ b/dist/rollup-plugin-typescript2.es.js @@ -1,6 +1,5 @@ /* eslint-disable */ import { concat, defaults, each, endsWith, filter, find, get, has, isEqual, isFunction, map, some } from 'lodash'; -import { DiagnosticCategory, ModuleKind, ScriptSnapshot, createDocumentRegistry, createLanguageService, findConfigFile, flattenDiagnosticMessageText, getAutomaticTypeDirectiveNames, getDefaultLibFilePath, nodeModuleNameResolver, parseConfigFileTextToJson, parseJsonConfigFileContent, resolveTypeReferenceDirective, sys, version } from 'typescript'; import { existsSync, readFileSync, readdirSync, renameSync } from 'fs'; import { Graph, alg } from 'graphlib'; import { sha1 } from 'object-hash'; @@ -115,6 +114,11 @@ var RollupContext = (function () { return RollupContext; }()); +var tsModule; +function setTypescriptModule(override) { + tsModule = override; +} + var LanguageServiceHost = (function () { function LanguageServiceHost(parsedConfig) { this.parsedConfig = parsedConfig; @@ -128,7 +132,7 @@ var LanguageServiceHost = (function () { }; LanguageServiceHost.prototype.setSnapshot = function (fileName, data) { fileName = this.normalize(fileName); - var snapshot = ScriptSnapshot.fromString(data); + var snapshot = tsModule.ScriptSnapshot.fromString(data); this.snapshots[fileName] = snapshot; this.versions[fileName] = (this.versions[fileName] || 0) + 1; return snapshot; @@ -138,7 +142,7 @@ var LanguageServiceHost = (function () { if (has(this.snapshots, fileName)) return this.snapshots[fileName]; if (existsSync(fileName)) { - this.snapshots[fileName] = ScriptSnapshot.fromString(sys.readFile(fileName)); + this.snapshots[fileName] = tsModule.ScriptSnapshot.fromString(tsModule.sys.readFile(fileName)); this.versions[fileName] = (this.versions[fileName] || 0) + 1; return this.snapshots[fileName]; } @@ -158,28 +162,28 @@ var LanguageServiceHost = (function () { return this.parsedConfig.options; }; LanguageServiceHost.prototype.getDefaultLibFileName = function (opts) { - return getDefaultLibFilePath(opts); + return tsModule.getDefaultLibFilePath(opts); }; LanguageServiceHost.prototype.useCaseSensitiveFileNames = function () { - return sys.useCaseSensitiveFileNames; + return tsModule.sys.useCaseSensitiveFileNames; }; LanguageServiceHost.prototype.readDirectory = function (path$$1, extensions, exclude, include) { - return sys.readDirectory(path$$1, extensions, exclude, include); + return tsModule.sys.readDirectory(path$$1, extensions, exclude, include); }; LanguageServiceHost.prototype.readFile = function (path$$1, encoding) { - return sys.readFile(path$$1, encoding); + return tsModule.sys.readFile(path$$1, encoding); }; LanguageServiceHost.prototype.fileExists = function (path$$1) { - return sys.fileExists(path$$1); + return tsModule.sys.fileExists(path$$1); }; LanguageServiceHost.prototype.getTypeRootsVersion = function () { return 0; }; LanguageServiceHost.prototype.directoryExists = function (directoryName) { - return sys.directoryExists(directoryName); + return tsModule.sys.directoryExists(directoryName); }; LanguageServiceHost.prototype.getDirectories = function (directoryName) { - return sys.getDirectories(directoryName); + return tsModule.sys.getDirectories(directoryName); }; LanguageServiceHost.prototype.normalize = function (fileName) { return fileName.split("\\").join("/"); @@ -263,7 +267,7 @@ var RollingCache = (function () { function convertDiagnostic(type, data) { return map(data, function (diagnostic) { var entry = { - flatMessage: flattenDiagnosticMessageText(diagnostic.messageText, "\n"), + flatMessage: tsModule.flattenDiagnosticMessageText(diagnostic.messageText, "\n"), category: diagnostic.category, code: diagnostic.code, type: type, @@ -289,11 +293,11 @@ var TsCache = (function () { rootFilenames: rootFilenames, options: this.options, rollupConfig: this.rollupConfig, - tsVersion: version, + tsVersion: tsModule.version, }); this.dependencyTree = new Graph({ directed: true }); this.dependencyTree.setDefaultNodeLabel(function (_node) { return ({ dirty: false }); }); - var automaticTypes = map(getAutomaticTypeDirectiveNames(options, sys), function (entry) { return resolveTypeReferenceDirective(entry, undefined, options, sys); }) + var automaticTypes = map(tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys), function (entry) { return tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys); }) .filter(function (entry) { return entry.resolvedTypeReferenceDirective && entry.resolvedTypeReferenceDirective.resolvedFileName; }) .map(function (entry) { return entry.resolvedTypeReferenceDirective.resolvedFileName; }); this.ambientTypes = filter(rootFilenames, function (file) { return endsWith(file, ".d.ts"); }) @@ -423,17 +427,17 @@ function printDiagnostics(context, diagnostics) { var color; var category; switch (diagnostic.category) { - case DiagnosticCategory.Message: + case tsModule.DiagnosticCategory.Message: print = context.info; color = white; category = ""; break; - case DiagnosticCategory.Error: + case tsModule.DiagnosticCategory.Error: print = context.error; color = red; category = "error"; break; - case DiagnosticCategory.Warning: + case tsModule.DiagnosticCategory.Warning: default: print = context.warn; color = yellow; @@ -451,20 +455,20 @@ function printDiagnostics(context, diagnostics) { function getOptionsOverrides(_a, tsConfigJson) { var useTsconfigDeclarationDir = _a.useTsconfigDeclarationDir; var declaration = get(tsConfigJson, "compilerOptions.declaration", false); - return __assign({ module: ModuleKind.ES2015, noEmitHelpers: true, importHelpers: true, noResolve: false, outDir: process.cwd() }, (!declaration || useTsconfigDeclarationDir ? {} : { declarationDir: process.cwd() })); + return __assign({ module: tsModule.ModuleKind.ES2015, noEmitHelpers: true, importHelpers: true, noResolve: false, outDir: process.cwd() }, (!declaration || useTsconfigDeclarationDir ? {} : { declarationDir: process.cwd() })); } function parseTsConfig(tsconfig, context, pluginOptions) { - var fileName = findConfigFile(process.cwd(), sys.fileExists, tsconfig); + var fileName = tsModule.findConfigFile(process.cwd(), tsModule.sys.fileExists, tsconfig); if (!fileName) throw new Error("couldn't find '" + tsconfig + "' in " + process.cwd()); - var text = sys.readFile(fileName); - var result = parseConfigFileTextToJson(fileName, text); + var text = tsModule.sys.readFile(fileName); + var result = tsModule.parseConfigFileTextToJson(fileName, text); if (result.error) { printDiagnostics(context, convertDiagnostic("config", [result.error])); throw new Error("failed to parse " + fileName); } - return parseJsonConfigFileContent(result.config, sys, dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); + return tsModule.parseJsonConfigFileContent(result.config, tsModule.sys, dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); } // The injected id for helpers. @@ -480,7 +484,7 @@ catch (e) { throw e; } -function typescript$1(options) { +function typescript(options) { // tslint:disable-next-line:no-var-requires var createFilter = require("rollup-pluginutils").createFilter; // tslint:enable-next-line:no-var-requires @@ -513,17 +517,19 @@ function typescript$1(options) { rollupCommonJSResolveHack: false, tsconfig: "tsconfig.json", useTsconfigDeclarationDir: false, + typescript: require("typescript"), }); + setTypescriptModule(pluginOptions.typescript); return { options: function (config) { rollupOptions = config; context = new ConsoleContext(pluginOptions.verbosity, "rpt2: "); - context.info("Typescript version: " + version); - context.debug("Plugin Options: " + JSON.stringify(pluginOptions, undefined, 4)); + context.info("Typescript version: " + tsModule.version); + context.debug("Plugin Options: " + JSON.stringify(pluginOptions, function (key, value) { return key === "typescript" ? "version " + value.version : value; }, 4)); filter$$1 = createFilter(pluginOptions.include, pluginOptions.exclude); parsedConfig = parseTsConfig(pluginOptions.tsconfig, context, pluginOptions); servicesHost = new LanguageServiceHost(parsedConfig); - service = createLanguageService(servicesHost, createDocumentRegistry()); + service = tsModule.createLanguageService(servicesHost, tsModule.createDocumentRegistry()); // printing compiler option errors if (pluginOptions.check) printDiagnostics(context, convertDiagnostic("options", service.getCompilerOptionsDiagnostics())); @@ -538,7 +544,7 @@ function typescript$1(options) { return null; importer = importer.split("\\").join("/"); // TODO: use module resolution cache - var result = nodeModuleNameResolver(importee, importer, parsedConfig.options, sys); + var result = tsModule.nodeModuleNameResolver(importee, importer, parsedConfig.options, tsModule.sys); if (result.resolvedModule && result.resolvedModule.resolvedFileName) { if (filter$$1(result.resolvedModule.resolvedFileName)) cache().setDependency(result.resolvedModule.resolvedFileName, importer); @@ -642,10 +648,10 @@ function typescript$1(options) { writeToPath = join(destDirectory, relative(baseDeclarationDir, name)); } // Write the declaration file to disk. - sys.writeFile(writeToPath, text, writeByteOrderMark); + tsModule.sys.writeFile(writeToPath, text, writeByteOrderMark); }); }, }; } -export default typescript$1; +export default typescript; diff --git a/dist/tscache.d.ts b/dist/tscache.d.ts index 446b90d1..e1e9d422 100644 --- a/dist/tscache.d.ts +++ b/dist/tscache.d.ts @@ -1,18 +1,18 @@ import { IContext } from "./context"; -import { Diagnostic, DiagnosticCategory, IScriptSnapshot, OutputFile, LanguageServiceHost, CompilerOptions } from "typescript"; +import * as tsTypes from "typescript"; export interface ICode { code: string | undefined; map: string | undefined; - dts?: OutputFile | undefined; + dts?: tsTypes.OutputFile | undefined; } export interface IDiagnostics { flatMessage: string; fileLine?: string; - category: DiagnosticCategory; + category: tsTypes.DiagnosticCategory; code: number; type: string; } -export declare function convertDiagnostic(type: string, data: Diagnostic[]): IDiagnostics[]; +export declare function convertDiagnostic(type: string, data: tsTypes.Diagnostic[]): IDiagnostics[]; export declare class TsCache { private host; private options; @@ -27,14 +27,14 @@ export declare class TsCache { private typesCache; private semanticDiagnosticsCache; private syntacticDiagnosticsCache; - constructor(host: LanguageServiceHost, cache: string, options: CompilerOptions, rollupConfig: any, rootFilenames: string[], context: IContext); + constructor(host: tsTypes.LanguageServiceHost, cache: string, options: tsTypes.CompilerOptions, rollupConfig: any, rootFilenames: string[], context: IContext); clean(): void; setDependency(importee: string, importer: string): void; walkTree(cb: (id: string) => void | false): void; done(): void; - getCompiled(id: string, snapshot: IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined; - getSyntacticDiagnostics(id: string, snapshot: IScriptSnapshot, check: () => Diagnostic[]): IDiagnostics[]; - getSemanticDiagnostics(id: string, snapshot: IScriptSnapshot, check: () => Diagnostic[]): IDiagnostics[]; + getCompiled(id: string, snapshot: tsTypes.IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined; + getSyntacticDiagnostics(id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[]; + getSemanticDiagnostics(id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[]; private checkAmbientTypes(); private getDiagnostics(type, cache, id, snapshot, check); private init(); diff --git a/dist/tsproxy.d.ts b/dist/tsproxy.d.ts new file mode 100644 index 00000000..3354feee --- /dev/null +++ b/dist/tsproxy.d.ts @@ -0,0 +1,3 @@ +import * as tsTypes from "typescript"; +export declare let tsModule: typeof tsTypes; +export declare function setTypescriptModule(override: typeof tsTypes): void; diff --git a/src/get-options-overrides.ts b/src/get-options-overrides.ts index 69adc555..df52d37a 100644 --- a/src/get-options-overrides.ts +++ b/src/get-options-overrides.ts @@ -1,16 +1,17 @@ -import { CompilerOptions, ModuleKind } from "typescript"; +import { tsModule } from "./tsproxy"; +import * as tsTypes from "typescript"; import { IOptions } from "./ioptions"; import { get } from "lodash"; -export function getOptionsOverrides({ useTsconfigDeclarationDir }: IOptions, tsConfigJson?: any): CompilerOptions +export function getOptionsOverrides({ useTsconfigDeclarationDir }: IOptions, tsConfigJson?: any): tsTypes.CompilerOptions { const declaration = get(tsConfigJson, "compilerOptions.declaration", false); return { - module: ModuleKind.ES2015, + module: tsModule.ModuleKind.ES2015, noEmitHelpers: true, importHelpers: true, noResolve: false, outDir: process.cwd(), - ...(!declaration || useTsconfigDeclarationDir ? {} : {declarationDir: process.cwd()}), + ...(!declaration || useTsconfigDeclarationDir ? {} : { declarationDir: process.cwd() }), }; } diff --git a/src/host.ts b/src/host.ts index 8877d821..3e70d383 100644 --- a/src/host.ts +++ b/src/host.ts @@ -1,14 +1,16 @@ -import {LanguageServiceHost as TypescriptLanguageServiceHost, IScriptSnapshot, ParsedCommandLine, ScriptSnapshot, sys, CompilerOptions, getDefaultLibFilePath} from "typescript"; -import {existsSync} from "fs"; -import {has} from "lodash"; -export class LanguageServiceHost implements TypescriptLanguageServiceHost +import { tsModule } from "./tsproxy"; +import * as tsTypes from "typescript"; +import { existsSync } from "fs"; +import { has } from "lodash"; + +export class LanguageServiceHost implements tsTypes.LanguageServiceHost { private cwd = process.cwd(); - private snapshots: { [fileName: string]: IScriptSnapshot } = {}; + private snapshots: { [fileName: string]: tsTypes.IScriptSnapshot } = {}; private versions: { [fileName: string]: number } = {}; - constructor(private parsedConfig: ParsedCommandLine) + constructor(private parsedConfig: tsTypes.ParsedCommandLine) { } @@ -18,17 +20,17 @@ export class LanguageServiceHost implements TypescriptLanguageServiceHost this.versions = {}; } - public setSnapshot(fileName: string, data: string): IScriptSnapshot + public setSnapshot(fileName: string, data: string): tsTypes.IScriptSnapshot { fileName = this.normalize(fileName); - const snapshot = ScriptSnapshot.fromString(data); + const snapshot = tsModule.ScriptSnapshot.fromString(data); this.snapshots[fileName] = snapshot; this.versions[fileName] = (this.versions[fileName] || 0) + 1; return snapshot; } - public getScriptSnapshot(fileName: string): IScriptSnapshot | undefined + public getScriptSnapshot(fileName: string): tsTypes.IScriptSnapshot | undefined { fileName = this.normalize(fileName); @@ -37,7 +39,7 @@ export class LanguageServiceHost implements TypescriptLanguageServiceHost if (existsSync(fileName)) { - this.snapshots[fileName] = ScriptSnapshot.fromString(sys.readFile(fileName)); + this.snapshots[fileName] = tsModule.ScriptSnapshot.fromString(tsModule.sys.readFile(fileName)); this.versions[fileName] = (this.versions[fileName] || 0) + 1; return this.snapshots[fileName]; } @@ -62,34 +64,34 @@ export class LanguageServiceHost implements TypescriptLanguageServiceHost return this.parsedConfig.fileNames; } - public getCompilationSettings(): CompilerOptions + public getCompilationSettings(): tsTypes.CompilerOptions { return this.parsedConfig.options; } - public getDefaultLibFileName(opts: CompilerOptions) + public getDefaultLibFileName(opts: tsTypes.CompilerOptions) { - return getDefaultLibFilePath(opts); + return tsModule.getDefaultLibFilePath(opts); } public useCaseSensitiveFileNames(): boolean { - return sys.useCaseSensitiveFileNames; + return tsModule.sys.useCaseSensitiveFileNames; } public readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] { - return sys.readDirectory(path, extensions, exclude, include); + return tsModule.sys.readDirectory(path, extensions, exclude, include); } public readFile(path: string, encoding?: string): string { - return sys.readFile(path, encoding); + return tsModule.sys.readFile(path, encoding); } public fileExists(path: string): boolean { - return sys.fileExists(path); + return tsModule.sys.fileExists(path); } public getTypeRootsVersion(): number @@ -99,12 +101,12 @@ export class LanguageServiceHost implements TypescriptLanguageServiceHost public directoryExists(directoryName: string): boolean { - return sys.directoryExists(directoryName); + return tsModule.sys.directoryExists(directoryName); } public getDirectories(directoryName: string): string[] { - return sys.getDirectories(directoryName); + return tsModule.sys.getDirectories(directoryName); } private normalize(fileName: string) diff --git a/src/index.ts b/src/index.ts index e9123155..a495719c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,9 +2,10 @@ import { RollupContext } from "./rollupcontext"; import { ConsoleContext, IRollupContext, VerbosityLevel } from "./context"; import { LanguageServiceHost } from "./host"; import { TsCache, convertDiagnostic, ICode } from "./tscache"; -import { createLanguageService, version, createDocumentRegistry, OutputFile, ParsedCommandLine, sys, LanguageService, nodeModuleNameResolver } from "typescript"; +import { tsModule, setTypescriptModule } from "./tsproxy"; +import * as tsTypes from "typescript"; import * as resolve from "resolve"; -import {defaults, endsWith, concat, find, isFunction, get, each} from "lodash"; +import { defaults, endsWith, concat, find, isFunction, get, each } from "lodash"; import { IRollupOptions } from "./irollup-options"; import { IOptions } from "./ioptions"; import { Partial } from "./partial"; @@ -25,11 +26,11 @@ export default function typescript(options?: Partial) let rollupOptions: IRollupOptions; let context: ConsoleContext; let filter: any; - let parsedConfig: ParsedCommandLine; + let parsedConfig: tsTypes.ParsedCommandLine; let servicesHost: LanguageServiceHost; - let service: LanguageService; + let service: tsTypes.LanguageService; let noErrors = true; - const declarations: { [name: string]: OutputFile } = {}; + const declarations: { [name: string]: tsTypes.OutputFile } = {}; let _cache: TsCache; const cache = (): TsCache => @@ -38,21 +39,25 @@ export default function typescript(options?: Partial) _cache = new TsCache(servicesHost, pluginOptions.cacheRoot, parsedConfig.options, rollupOptions, parsedConfig.fileNames, context); return _cache; }; - const pluginOptions = { ... options } as IOptions; + + const pluginOptions = { ...options } as IOptions; defaults(pluginOptions, - { - check: true, - verbosity: VerbosityLevel.Warning, - clean: false, - cacheRoot: `${process.cwd()}/.rpt2_cache`, - include: [ "*.ts+(|x)", "**/*.ts+(|x)" ], - exclude: [ "*.d.ts", "**/*.d.ts" ], - abortOnError: true, - rollupCommonJSResolveHack: false, - tsconfig: "tsconfig.json", - useTsconfigDeclarationDir: false, - }); + { + check: true, + verbosity: VerbosityLevel.Warning, + clean: false, + cacheRoot: `${process.cwd()}/.rpt2_cache`, + include: ["*.ts+(|x)", "**/*.ts+(|x)"], + exclude: ["*.d.ts", "**/*.d.ts"], + abortOnError: true, + rollupCommonJSResolveHack: false, + tsconfig: "tsconfig.json", + useTsconfigDeclarationDir: false, + typescript: require("typescript"), + }); + + setTypescriptModule(pluginOptions.typescript); return { @@ -61,8 +66,8 @@ export default function typescript(options?: Partial) rollupOptions = config; context = new ConsoleContext(pluginOptions.verbosity, "rpt2: "); - context.info(`Typescript version: ${version}`); - context.debug(`Plugin Options: ${JSON.stringify(pluginOptions, undefined, 4)}`); + context.info(`Typescript version: ${tsModule.version}`); + context.debug(`Plugin Options: ${JSON.stringify(pluginOptions, (key, value) => key === "typescript" ? `version ${(value as typeof tsModule).version}` : value, 4)}`); filter = createFilter(pluginOptions.include, pluginOptions.exclude); @@ -70,7 +75,7 @@ export default function typescript(options?: Partial) servicesHost = new LanguageServiceHost(parsedConfig); - service = createLanguageService(servicesHost, createDocumentRegistry()); + service = tsModule.createLanguageService(servicesHost, tsModule.createDocumentRegistry()); // printing compiler option errors if (pluginOptions.check) @@ -93,7 +98,7 @@ export default function typescript(options?: Partial) importer = importer.split("\\").join("/"); // TODO: use module resolution cache - const result = nodeModuleNameResolver(importee, importer, parsedConfig.options, sys); + const result = tsModule.nodeModuleNameResolver(importee, importer, parsedConfig.options, tsModule.sys); if (result.resolvedModule && result.resolvedModule.resolvedFileName) { @@ -234,7 +239,7 @@ export default function typescript(options?: Partial) round++; }, - onwrite({dest}: IRollupOptions) + onwrite({ dest }: IRollupOptions) { const baseDeclarationDir = parsedConfig.options.outDir; each(declarations, ({ name, text, writeByteOrderMark }) => @@ -253,7 +258,7 @@ export default function typescript(options?: Partial) } // Write the declaration file to disk. - sys.writeFile(writeToPath, text, writeByteOrderMark); + tsModule.sys.writeFile(writeToPath, text, writeByteOrderMark); }); }, }; diff --git a/src/ioptions.ts b/src/ioptions.ts index 0749ac86..a15524b7 100644 --- a/src/ioptions.ts +++ b/src/ioptions.ts @@ -1,3 +1,5 @@ +import { tsModule } from "./tsproxy"; + export interface IOptions { include: string; @@ -10,4 +12,5 @@ export interface IOptions rollupCommonJSResolveHack: boolean; tsconfig: string; useTsconfigDeclarationDir: boolean; + typescript: typeof tsModule; } diff --git a/src/parse-ts-config.ts b/src/parse-ts-config.ts index ff6d4239..96cdf7f7 100644 --- a/src/parse-ts-config.ts +++ b/src/parse-ts-config.ts @@ -1,25 +1,27 @@ -import {findConfigFile, parseConfigFileTextToJson, ParsedCommandLine, parseJsonConfigFileContent, sys} from "typescript"; -import {IContext} from "./context"; -import {dirname} from "path"; -import {printDiagnostics} from "./print-diagnostics"; -import {convertDiagnostic} from "./tscache"; -import {getOptionsOverrides} from "./get-options-overrides"; -import {IOptions} from "./ioptions"; +import { tsModule } from "./tsproxy"; +import * as tsTypes from "typescript"; +import { IContext } from "./context"; +import { dirname } from "path"; +import { printDiagnostics } from "./print-diagnostics"; +import { convertDiagnostic } from "./tscache"; +import { getOptionsOverrides } from "./get-options-overrides"; +import { IOptions } from "./ioptions"; -export function parseTsConfig(tsconfig: string, context: IContext, pluginOptions: IOptions): ParsedCommandLine +export function parseTsConfig(tsconfig: string, context: IContext, pluginOptions: IOptions): tsTypes.ParsedCommandLine { - const fileName = findConfigFile(process.cwd(), sys.fileExists, tsconfig); + const fileName = tsModule.findConfigFile(process.cwd(), tsModule.sys.fileExists, tsconfig); if (!fileName) throw new Error(`couldn't find '${tsconfig}' in ${process.cwd()}`); - const text = sys.readFile(fileName); - const result = parseConfigFileTextToJson(fileName, text); + const text = tsModule.sys.readFile(fileName); + const result = tsModule.parseConfigFileTextToJson(fileName, text); - if (result.error) { + if (result.error) + { printDiagnostics(context, convertDiagnostic("config", [result.error])); throw new Error(`failed to parse ${fileName}`); } - return parseJsonConfigFileContent(result.config, sys, dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); + return tsModule.parseJsonConfigFileContent(result.config, tsModule.sys, dirname(fileName), getOptionsOverrides(pluginOptions, result.config), fileName); } diff --git a/src/print-diagnostics.ts b/src/print-diagnostics.ts index 7f9c75c3..35cbe8db 100644 --- a/src/print-diagnostics.ts +++ b/src/print-diagnostics.ts @@ -1,8 +1,8 @@ -import {DiagnosticCategory} from "typescript"; -import {red, white, yellow} from "colors/safe"; -import {each} from "lodash"; -import {IContext} from "./context"; -import {IDiagnostics} from "./tscache"; +import { tsModule } from "./tsproxy"; +import { red, white, yellow } from "colors/safe"; +import { each } from "lodash"; +import { IContext } from "./context"; +import { IDiagnostics } from "./tscache"; export function printDiagnostics(context: IContext, diagnostics: IDiagnostics[]): void { @@ -13,17 +13,17 @@ export function printDiagnostics(context: IContext, diagnostics: IDiagnostics[]) let category; switch (diagnostic.category) { - case DiagnosticCategory.Message: + case tsModule.DiagnosticCategory.Message: print = context.info; color = white; category = ""; break; - case DiagnosticCategory.Error: + case tsModule.DiagnosticCategory.Error: print = context.error; color = red; category = "error"; break; - case DiagnosticCategory.Warning: + case tsModule.DiagnosticCategory.Warning: default: print = context.warn; color = yellow; diff --git a/src/rollingcache.ts b/src/rollingcache.ts index 747b17b0..fb00538c 100644 --- a/src/rollingcache.ts +++ b/src/rollingcache.ts @@ -1,13 +1,13 @@ import { ICache } from "./icache"; -import {emptyDirSync, ensureFileSync, readJsonSync, removeSync, writeJsonSync} from "fs-extra"; -import {existsSync, readdirSync, renameSync} from "fs"; -import {isEqual} from "lodash"; +import { emptyDirSync, ensureFileSync, readJsonSync, removeSync, writeJsonSync } from "fs-extra"; +import { existsSync, readdirSync, renameSync } from "fs"; +import { isEqual } from "lodash"; /** * Saves data in new cache folder or reads it from old one. * Avoids perpetually growing cache and situations when things need to consider changed and then reverted data to be changed. */ -export class RollingCache implements ICache +export class RollingCache implements ICache { private oldCacheRoot: string; private newCacheRoot: string; diff --git a/src/rollupcontext.ts b/src/rollupcontext.ts index 433e3e4b..3417ae3d 100644 --- a/src/rollupcontext.ts +++ b/src/rollupcontext.ts @@ -1,5 +1,5 @@ import { IContext, IRollupContext, VerbosityLevel } from "./context"; -import {isFunction} from "lodash"; +import { isFunction } from "lodash"; export class RollupContext implements IContext { diff --git a/src/tscache.ts b/src/tscache.ts index 130d3e32..20c1f409 100644 --- a/src/tscache.ts +++ b/src/tscache.ts @@ -1,18 +1,19 @@ import { IContext } from "./context"; -import {Graph, alg} from "graphlib"; -import {sha1} from "object-hash"; +import { Graph, alg } from "graphlib"; +import { sha1 } from "object-hash"; import { RollingCache } from "./rollingcache"; import { ICache } from "./icache"; -import {map, endsWith, filter, each, some} from "lodash"; -import {Diagnostic, DiagnosticCategory, IScriptSnapshot, OutputFile, LanguageServiceHost, version, getAutomaticTypeDirectiveNames, sys, resolveTypeReferenceDirective, flattenDiagnosticMessageText, CompilerOptions} from "typescript"; -import {blue, yellow, green} from "colors/safe"; -import {emptyDirSync} from "fs-extra"; +import { map, endsWith, filter, each, some } from "lodash"; +import { tsModule } from "./tsproxy"; +import * as tsTypes from "typescript"; +import { blue, yellow, green } from "colors/safe"; +import { emptyDirSync } from "fs-extra"; export interface ICode { code: string | undefined; map: string | undefined; - dts?: OutputFile | undefined; + dts?: tsTypes.OutputFile | undefined; } interface INodeLabel @@ -24,7 +25,7 @@ export interface IDiagnostics { flatMessage: string; fileLine?: string; - category: DiagnosticCategory; + category: tsTypes.DiagnosticCategory; code: number; type: string; } @@ -32,20 +33,20 @@ export interface IDiagnostics interface ITypeSnapshot { id: string; - snapshot: IScriptSnapshot | undefined; + snapshot: tsTypes.IScriptSnapshot | undefined; } -export function convertDiagnostic(type: string, data: Diagnostic[]): IDiagnostics[] +export function convertDiagnostic(type: string, data: tsTypes.Diagnostic[]): IDiagnostics[] { return map(data, (diagnostic) => { const entry: IDiagnostics = - { - flatMessage: flattenDiagnosticMessageText(diagnostic.messageText, "\n"), - category: diagnostic.category, - code: diagnostic.code, - type, - }; + { + flatMessage: tsModule.flattenDiagnosticMessageText(diagnostic.messageText, "\n"), + category: diagnostic.category, + code: diagnostic.code, + type, + }; if (diagnostic.file && diagnostic.start !== undefined) { @@ -69,20 +70,20 @@ export class TsCache private semanticDiagnosticsCache: ICache; private syntacticDiagnosticsCache: ICache; - constructor(private host: LanguageServiceHost, cache: string, private options: CompilerOptions, private rollupConfig: any, rootFilenames: string[], private context: IContext) + constructor(private host: tsTypes.LanguageServiceHost, cache: string, private options: tsTypes.CompilerOptions, private rollupConfig: any, rootFilenames: string[], private context: IContext) { this.cacheDir = `${cache}/${sha1({ version: this.cacheVersion, rootFilenames, options: this.options, rollupConfig: this.rollupConfig, - tsVersion : version, + tsVersion: tsModule.version, })}`; this.dependencyTree = new Graph({ directed: true }); - this.dependencyTree.setDefaultNodeLabel((_node: string) => ({ dirty: false }) ); + this.dependencyTree.setDefaultNodeLabel((_node: string) => ({ dirty: false })); - const automaticTypes = map(getAutomaticTypeDirectiveNames(options, sys), (entry) => resolveTypeReferenceDirective(entry, undefined, options, sys)) + const automaticTypes = map(tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys), (entry) => tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys)) .filter((entry) => entry.resolvedTypeReferenceDirective && entry.resolvedTypeReferenceDirective.resolvedFileName) .map((entry) => entry.resolvedTypeReferenceDirective!.resolvedFileName!); @@ -135,7 +136,7 @@ export class TsCache this.typesCache.roll(); } - public getCompiled(id: string, snapshot: IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined + public getCompiled(id: string, snapshot: tsTypes.IScriptSnapshot, transform: () => ICode | undefined): ICode | undefined { const name = this.makeName(id, snapshot); @@ -159,12 +160,12 @@ export class TsCache return data; } - public getSyntacticDiagnostics(id: string, snapshot: IScriptSnapshot, check: () => Diagnostic[]): IDiagnostics[] + public getSyntacticDiagnostics(id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[] { return this.getDiagnostics("syntax", this.syntacticDiagnosticsCache, id, snapshot, check); } - public getSemanticDiagnostics(id: string, snapshot: IScriptSnapshot, check: () => Diagnostic[]): IDiagnostics[] + public getSemanticDiagnostics(id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[] { return this.getDiagnostics("semantic", this.semanticDiagnosticsCache, id, snapshot, check); } @@ -187,7 +188,7 @@ export class TsCache each(typeNames, (name) => this.typesCache.touch(name)); } - private getDiagnostics(type: string, cache: ICache, id: string, snapshot: IScriptSnapshot, check: () => Diagnostic[]): IDiagnostics[] + private getDiagnostics(type: string, cache: ICache, id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[] { const name = this.makeName(id, snapshot); @@ -254,7 +255,7 @@ export class TsCache }); } - private makeName(id: string, snapshot: IScriptSnapshot) + private makeName(id: string, snapshot: tsTypes.IScriptSnapshot) { const data = snapshot.getText(0, snapshot.getLength()); return sha1({ data, id }); diff --git a/src/tslib.ts b/src/tslib.ts index 5031ebf3..d8f9301d 100644 --- a/src/tslib.ts +++ b/src/tslib.ts @@ -1,4 +1,4 @@ -import {readFileSync} from "fs"; +import { readFileSync } from "fs"; // The injected id for helpers. export const TSLIB = "tslib"; diff --git a/src/tsproxy.ts b/src/tsproxy.ts new file mode 100644 index 00000000..4050af12 --- /dev/null +++ b/src/tsproxy.ts @@ -0,0 +1,8 @@ +import * as tsTypes from "typescript"; + +export let tsModule: typeof tsTypes; + +export function setTypescriptModule(override: typeof tsTypes) +{ + tsModule = override; +}