fix(ts-node): patch error
This commit is contained in:
		
							
								
								
									
										22
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2018 Lossless GmbH (hello@lossless.com) | ||||
| Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in | ||||
| all copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
| THE SOFTWARE. | ||||
							
								
								
									
										6
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| "use strict"; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| const tsNode = require("ts-node"); | ||||
| const path = require("path"); | ||||
| const tsNode = require("./tsnode"); | ||||
| tsNode.register({ | ||||
|     compilerOptions: { | ||||
|         lib: ['es2016', 'es2017'] | ||||
|     }, | ||||
|     ignore: ['^(.(.*\.d\.ts))*$'], | ||||
|     skipIgnore: true, | ||||
|     cacheDirectory: path.join(__dirname, '../tscache') | ||||
| }); | ||||
| if (process.env.CLI_CALL_TSRUN) { | ||||
| @@ -17,4 +17,4 @@ if (process.env.CLI_CALL_TSRUN) { | ||||
|     const pathToLoad = path.join(process.cwd(), pathToTsFile); | ||||
|     Promise.resolve().then(() => require(pathToLoad)); | ||||
| } | ||||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGtDQUFrQztBQUNsQyw2QkFBNkI7QUFFN0IsTUFBTSxDQUFDLFFBQVEsQ0FBQztJQUNkLGVBQWUsRUFBRTtRQUNmLEdBQUcsRUFBRSxDQUFFLFFBQVEsRUFBRSxRQUFRLENBQUU7S0FDNUI7SUFDRCxNQUFNLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztJQUM3QixjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDO0NBQ25ELENBQUMsQ0FBQztBQUVILElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUU7SUFDOUIseUJBQXlCO0lBQ3pCLHFDQUFxQztJQUNyQyxzQ0FBc0M7SUFDdEMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMxRCxxQ0FBTyxVQUFVLEdBQUU7Q0FDcEIifQ== | ||||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE2QjtBQUM3QixtQ0FBbUM7QUFFbkMsTUFBTSxDQUFDLFFBQVEsQ0FBQztJQUNkLGVBQWUsRUFBRTtRQUNmLEdBQUcsRUFBRSxDQUFFLFFBQVEsRUFBRSxRQUFRLENBQUU7S0FDNUI7SUFDRCxVQUFVLEVBQUUsSUFBSTtJQUNoQixjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDO0NBQ25ELENBQUMsQ0FBQztBQUVILElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUU7SUFDOUIseUJBQXlCO0lBQ3pCLHFDQUFxQztJQUNyQyxzQ0FBc0M7SUFDdEMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMxRCxxQ0FBTyxVQUFVLEdBQUU7Q0FDcEIifQ== | ||||
							
								
								
									
										99
									
								
								dist/tsnode.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								dist/tsnode.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| import { BaseError } from 'make-error'; | ||||
| import * as _ts from 'typescript'; | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| export declare const INSPECT_CUSTOM: string | symbol; | ||||
| /** | ||||
|  * Common TypeScript interfaces between versions. | ||||
|  */ | ||||
| export interface TSCommon { | ||||
|     version: typeof _ts.version; | ||||
|     sys: typeof _ts.sys; | ||||
|     ScriptSnapshot: typeof _ts.ScriptSnapshot; | ||||
|     displayPartsToString: typeof _ts.displayPartsToString; | ||||
|     createLanguageService: typeof _ts.createLanguageService; | ||||
|     getDefaultLibFilePath: typeof _ts.getDefaultLibFilePath; | ||||
|     getPreEmitDiagnostics: typeof _ts.getPreEmitDiagnostics; | ||||
|     flattenDiagnosticMessageText: typeof _ts.flattenDiagnosticMessageText; | ||||
|     transpileModule: typeof _ts.transpileModule; | ||||
|     ModuleKind: typeof _ts.ModuleKind; | ||||
|     ScriptTarget: typeof _ts.ScriptTarget; | ||||
|     findConfigFile: typeof _ts.findConfigFile; | ||||
|     readConfigFile: typeof _ts.readConfigFile; | ||||
|     parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent; | ||||
|     formatDiagnostics: typeof _ts.formatDiagnostics; | ||||
|     formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext; | ||||
| } | ||||
| /** | ||||
|  * Export the current version. | ||||
|  */ | ||||
| export declare const VERSION: any; | ||||
| /** | ||||
|  * Registration options. | ||||
|  */ | ||||
| export interface Options { | ||||
|     pretty?: boolean | null; | ||||
|     typeCheck?: boolean | null; | ||||
|     transpileOnly?: boolean | null; | ||||
|     files?: boolean | null; | ||||
|     cache?: boolean | null; | ||||
|     cacheDirectory?: string; | ||||
|     compiler?: string; | ||||
|     ignore?: string | string[]; | ||||
|     project?: string; | ||||
|     skipIgnore?: boolean | null; | ||||
|     skipProject?: boolean | null; | ||||
|     compilerOptions?: object; | ||||
|     ignoreDiagnostics?: number | string | Array<number | string>; | ||||
|     readFile?: (path: string) => string | undefined; | ||||
|     fileExists?: (path: string) => boolean; | ||||
|     transformers?: _ts.CustomTransformers; | ||||
| } | ||||
| /** | ||||
|  * Information retrieved from type info check. | ||||
|  */ | ||||
| export interface TypeInfo { | ||||
|     name: string; | ||||
|     comment: string; | ||||
| } | ||||
| /** | ||||
|  * Default register options. | ||||
|  */ | ||||
| export declare const DEFAULTS: Options; | ||||
| /** | ||||
|  * Split a string array of values. | ||||
|  */ | ||||
| export declare function split(value: string | undefined): string[]; | ||||
| /** | ||||
|  * Parse a string as JSON. | ||||
|  */ | ||||
| export declare function parse(value: string | undefined): object | undefined; | ||||
| /** | ||||
|  * Replace backslashes with forward slashes. | ||||
|  */ | ||||
| export declare function normalizeSlashes(value: string): string; | ||||
| /** | ||||
|  * TypeScript diagnostics error. | ||||
|  */ | ||||
| export declare class TSError extends BaseError { | ||||
|     diagnosticText: string; | ||||
|     diagnosticCodes: number[]; | ||||
|     name: string; | ||||
|     constructor(diagnosticText: string, diagnosticCodes: number[]); | ||||
| } | ||||
| /** | ||||
|  * Return type for registering `ts-node`. | ||||
|  */ | ||||
| export interface Register { | ||||
|     cwd: string; | ||||
|     extensions: string[]; | ||||
|     cachedir: string; | ||||
|     ts: TSCommon; | ||||
|     compile(code: string, fileName: string, lineOffset?: number): string; | ||||
|     getTypeInfo(code: string, fileName: string, position: number): TypeInfo; | ||||
| } | ||||
| /** | ||||
|  * Register TypeScript compiler. | ||||
|  */ | ||||
| export declare function register(opts?: Options): Register; | ||||
							
								
								
									
										440
									
								
								dist/tsnode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								dist/tsnode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										32
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -101,11 +101,6 @@ | ||||
|         "object-keys": "^1.0.8" | ||||
|       } | ||||
|     }, | ||||
|     "diff": { | ||||
|       "version": "3.5.0", | ||||
|       "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", | ||||
|       "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" | ||||
|     }, | ||||
|     "es-abstract": { | ||||
|       "version": "1.12.0", | ||||
|       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", | ||||
| @@ -278,9 +273,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "minimist": { | ||||
|       "version": "1.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", | ||||
|       "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" | ||||
|       "version": "0.0.8", | ||||
|       "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", | ||||
|       "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" | ||||
|     }, | ||||
|     "mkdirp": { | ||||
|       "version": "0.5.1", | ||||
| @@ -288,13 +283,6 @@ | ||||
|       "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", | ||||
|       "requires": { | ||||
|         "minimist": "0.0.8" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "minimist": { | ||||
|           "version": "0.0.8", | ||||
|           "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", | ||||
|           "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "object-keys": { | ||||
| @@ -467,20 +455,6 @@ | ||||
|         "strip-bom": "^2.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "ts-node": { | ||||
|       "version": "6.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.1.0.tgz", | ||||
|       "integrity": "sha512-mw11Bq08RZgrU/bzcVw/Ti9wNyefpOanXgWsHg008wyVHjvFhWxNatVVrciOAu8BcWSECoNOSunRzUokKH8Mmw==", | ||||
|       "requires": { | ||||
|         "arrify": "^1.0.0", | ||||
|         "diff": "^3.1.0", | ||||
|         "make-error": "^1.1.1", | ||||
|         "minimist": "^1.2.0", | ||||
|         "mkdirp": "^0.5.1", | ||||
|         "source-map-support": "^0.5.6", | ||||
|         "yn": "^2.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "typescript": { | ||||
|       "version": "2.9.1", | ||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.1.tgz", | ||||
|   | ||||
| @@ -19,9 +19,13 @@ | ||||
|     "@types/node": "^10.3.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "arrify": "^1.0.1", | ||||
|     "make-error": "^1.3.4", | ||||
|     "mkdirp": "^0.5.1", | ||||
|     "smartfile": "^4.2.28", | ||||
|     "ts-node": "^6.1.0", | ||||
|     "typescript": "^2.9.1" | ||||
|     "source-map-support": "^0.5.6", | ||||
|     "typescript": "^2.9.1", | ||||
|     "yn": "^2.0.0" | ||||
|   }, | ||||
|   "private": false | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| import * as tsNode from 'ts-node'; | ||||
| import * as path from 'path'; | ||||
| import * as tsNode from './tsnode'; | ||||
|  | ||||
| tsNode.register({ | ||||
|   compilerOptions: { | ||||
|     lib: [ 'es2016', 'es2017' ] | ||||
|   }, | ||||
|   ignore: ['^(.(.*\.d\.ts))*$'], | ||||
|   skipIgnore: true, | ||||
|   cacheDirectory: path.join(__dirname, '../tscache') | ||||
| }); | ||||
|  | ||||
|   | ||||
							
								
								
									
										613
									
								
								ts/tsnode.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										613
									
								
								ts/tsnode.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,613 @@ | ||||
| import { relative, basename, extname, resolve, dirname, join } from 'path' | ||||
| import { readFileSync, writeFileSync } from 'fs' | ||||
| import { EOL, tmpdir, homedir } from 'os' | ||||
| import sourceMapSupport = require('source-map-support') | ||||
| import mkdirp = require('mkdirp') | ||||
| import crypto = require('crypto') | ||||
| import yn = require('yn') | ||||
| import arrify = require('arrify') | ||||
| import bufferFrom = require('buffer-from') | ||||
| import { BaseError } from 'make-error' | ||||
| import * as util from 'util' | ||||
| import * as _ts from 'typescript' | ||||
|  | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| export const INSPECT_CUSTOM = util.inspect.custom || 'inspect' | ||||
|  | ||||
| /** | ||||
|  * Debugging `ts-node`. | ||||
|  */ | ||||
| const shouldDebug = yn(process.env.TS_NODE_DEBUG) | ||||
| const debug = shouldDebug ? console.log.bind(console, 'ts-node') : () => undefined | ||||
| const debugFn = shouldDebug ? | ||||
|   <T, U> (key: string, fn: (arg: T) => U) => { | ||||
|     return (x: T) => { | ||||
|       debug(key, x) | ||||
|       return fn(x) | ||||
|     } | ||||
|   } : | ||||
|   <T, U> (_: string, fn: (arg: T) => U) => fn | ||||
|  | ||||
| /** | ||||
|  * Common TypeScript interfaces between versions. | ||||
|  */ | ||||
| export interface TSCommon { | ||||
|   version: typeof _ts.version | ||||
|   sys: typeof _ts.sys | ||||
|   ScriptSnapshot: typeof _ts.ScriptSnapshot | ||||
|   displayPartsToString: typeof _ts.displayPartsToString | ||||
|   createLanguageService: typeof _ts.createLanguageService | ||||
|   getDefaultLibFilePath: typeof _ts.getDefaultLibFilePath | ||||
|   getPreEmitDiagnostics: typeof _ts.getPreEmitDiagnostics | ||||
|   flattenDiagnosticMessageText: typeof _ts.flattenDiagnosticMessageText | ||||
|   transpileModule: typeof _ts.transpileModule | ||||
|   ModuleKind: typeof _ts.ModuleKind | ||||
|   ScriptTarget: typeof _ts.ScriptTarget | ||||
|   findConfigFile: typeof _ts.findConfigFile | ||||
|   readConfigFile: typeof _ts.readConfigFile | ||||
|   parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent | ||||
|   formatDiagnostics: typeof _ts.formatDiagnostics | ||||
|   formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Export the current version. | ||||
|  */ | ||||
| export const VERSION = require('../package.json').version | ||||
|  | ||||
| /** | ||||
|  * Registration options. | ||||
|  */ | ||||
| export interface Options { | ||||
|   pretty?: boolean | null | ||||
|   typeCheck?: boolean | null | ||||
|   transpileOnly?: boolean | null | ||||
|   files?: boolean | null | ||||
|   cache?: boolean | null | ||||
|   cacheDirectory?: string | ||||
|   compiler?: string | ||||
|   ignore?: string | string[] | ||||
|   project?: string | ||||
|   skipIgnore?: boolean | null | ||||
|   skipProject?: boolean | null | ||||
|   compilerOptions?: object | ||||
|   ignoreDiagnostics?: number | string | Array<number | string> | ||||
|   readFile?: (path: string) => string | undefined | ||||
|   fileExists?: (path: string) => boolean | ||||
|   transformers?: _ts.CustomTransformers | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Track the project information. | ||||
|  */ | ||||
| interface MemoryCache { | ||||
|   contents: { [path: string]: string | undefined } | ||||
|   versions: { [path: string]: number | undefined } | ||||
|   outputs: { [path: string]: string } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Information retrieved from type info check. | ||||
|  */ | ||||
| export interface TypeInfo { | ||||
|   name: string | ||||
|   comment: string | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Default register options. | ||||
|  */ | ||||
| export const DEFAULTS: Options = { | ||||
|   files: yn(process.env['TS_NODE_FILES']), | ||||
|   cache: yn(process.env['TS_NODE_CACHE'], { default: true }), | ||||
|   pretty: yn(process.env['TS_NODE_PRETTY']), | ||||
|   cacheDirectory: process.env['TS_NODE_CACHE_DIRECTORY'], | ||||
|   compiler: process.env['TS_NODE_COMPILER'], | ||||
|   compilerOptions: parse(process.env['TS_NODE_COMPILER_OPTIONS']), | ||||
|   ignore: split(process.env['TS_NODE_IGNORE']), | ||||
|   project: process.env['TS_NODE_PROJECT'], | ||||
|   skipIgnore: yn(process.env['TS_NODE_SKIP_IGNORE']), | ||||
|   skipProject: yn(process.env['TS_NODE_SKIP_PROJECT']), | ||||
|   ignoreDiagnostics: split(process.env['TS_NODE_IGNORE_DIAGNOSTICS']), | ||||
|   typeCheck: yn(process.env['TS_NODE_TYPE_CHECK']), | ||||
|   transpileOnly: yn(process.env['TS_NODE_TRANSPILE_ONLY']) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Default TypeScript compiler options required by `ts-node`. | ||||
|  */ | ||||
| const DEFAULT_COMPILER_OPTIONS = { | ||||
|   sourceMap: true, | ||||
|   inlineSourceMap: false, | ||||
|   inlineSources: true, | ||||
|   declaration: false, | ||||
|   noEmit: false, | ||||
|   outDir: '$$ts-node$$' | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Split a string array of values. | ||||
|  */ | ||||
| export function split (value: string | undefined) { | ||||
|   return typeof value === 'string' ? value.split(/ *, */g) : undefined | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Parse a string as JSON. | ||||
|  */ | ||||
| export function parse (value: string | undefined): object | undefined { | ||||
|   return typeof value === 'string' ? JSON.parse(value) : undefined | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Replace backslashes with forward slashes. | ||||
|  */ | ||||
| export function normalizeSlashes (value: string): string { | ||||
|   return value.replace(/\\/g, '/') | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * TypeScript diagnostics error. | ||||
|  */ | ||||
| export class TSError extends BaseError { | ||||
|   name = 'TSError' | ||||
|  | ||||
|   constructor (public diagnosticText: string, public diagnosticCodes: number[]) { | ||||
|     super(`⨯ Unable to compile TypeScript:\n${diagnosticText}`) | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * @internal | ||||
|    */ | ||||
|   [INSPECT_CUSTOM] () { | ||||
|     return this.diagnosticText | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Return type for registering `ts-node`. | ||||
|  */ | ||||
| export interface Register { | ||||
|   cwd: string | ||||
|   extensions: string[] | ||||
|   cachedir: string | ||||
|   ts: TSCommon | ||||
|   compile (code: string, fileName: string, lineOffset?: number): string | ||||
|   getTypeInfo (code: string, fileName: string, position: number): TypeInfo | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Return a default temp directory based on home directory of user. | ||||
|  */ | ||||
| function getTmpDir (): string { | ||||
|   const hash = crypto.createHash('sha256').update(homedir(), 'utf8').digest('hex') | ||||
|  | ||||
|   return join(tmpdir(), `ts-node-${hash}`) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Register TypeScript compiler. | ||||
|  */ | ||||
| export function register (opts: Options = {}): Register { | ||||
|   const options = Object.assign({}, DEFAULTS, opts) | ||||
|   const cacheDirectory = options.cacheDirectory || getTmpDir() | ||||
|   const originalJsHandler = require.extensions['.js'] | ||||
|  | ||||
|   const ignoreDiagnostics = arrify(options.ignoreDiagnostics).concat([ | ||||
|     6059, // "'rootDir' is expected to contain all source files." | ||||
|     18002, // "The 'files' list in config file is empty." | ||||
|     18003 // "No inputs were found in config file." | ||||
|   ]).map(Number) | ||||
|  | ||||
|   const memoryCache: MemoryCache = { | ||||
|     contents: Object.create(null), | ||||
|     versions: Object.create(null), | ||||
|     outputs: Object.create(null) | ||||
|   } | ||||
|  | ||||
|   const ignore = options.skipIgnore ? [] : arrify( | ||||
|     options.ignore || '/node_modules/' | ||||
|   ).map(str => new RegExp(str)) | ||||
|  | ||||
|   // Install source map support and read from memory cache. | ||||
|   sourceMapSupport.install({ | ||||
|     environment: 'node', | ||||
|     retrieveFile (path: string) { | ||||
|       return memoryCache.outputs[path] | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   // Require the TypeScript compiler and configuration. | ||||
|   const cwd = process.cwd() | ||||
|   const { compilerOptions, project, skipProject } = options | ||||
|   const compiler = options.compiler || 'typescript' | ||||
|   const typeCheck = options.typeCheck === true || options.transpileOnly !== true | ||||
|   const ts: typeof _ts = require(compiler) | ||||
|   const transformers = options.transformers || undefined | ||||
|   const readFile = options.readFile || ts.sys.readFile | ||||
|   const fileExists = options.fileExists || ts.sys.fileExists | ||||
|   const config = readConfig(cwd, ts, fileExists, readFile, compilerOptions, project, skipProject) | ||||
|   const configDiagnosticList = filterDiagnostics(config.errors, ignoreDiagnostics) | ||||
|   const extensions = ['.ts', '.tsx'] | ||||
|   const fileNames = options.files ? config.fileNames : [] | ||||
|  | ||||
|   const cachedir = join( | ||||
|     resolve(cwd, cacheDirectory), | ||||
|     getCompilerDigest({ | ||||
|       version: ts.version, | ||||
|       options: config.options, | ||||
|       fileNames, | ||||
|       typeCheck, | ||||
|       ignoreDiagnostics, | ||||
|       compiler | ||||
|     }) | ||||
|   ) | ||||
|  | ||||
|   const diagnosticHost: _ts.FormatDiagnosticsHost = { | ||||
|     getNewLine: () => EOL, | ||||
|     getCurrentDirectory: () => cwd, | ||||
|     getCanonicalFileName: (path) => path | ||||
|   } | ||||
|  | ||||
|   const formatDiagnostics = options.pretty | ||||
|     ? ts.formatDiagnosticsWithColorAndContext | ||||
|     : ts.formatDiagnostics | ||||
|  | ||||
|   function createTSError (diagnostics: ReadonlyArray<_ts.Diagnostic>) { | ||||
|     const diagnosticText = formatDiagnostics(diagnostics, diagnosticHost) | ||||
|     const diagnosticCodes = diagnostics.map(x => x.code) | ||||
|     return new TSError(diagnosticText, diagnosticCodes) | ||||
|   } | ||||
|  | ||||
|   // Render the configuration errors and exit the script. | ||||
|   if (configDiagnosticList.length) throw createTSError(configDiagnosticList) | ||||
|  | ||||
|   // Enable `allowJs` when flag is set. | ||||
|   if (config.options.allowJs) { | ||||
|     extensions.push('.js') | ||||
|     extensions.push('.jsx') | ||||
|   } | ||||
|  | ||||
|   // Initialize files from TypeScript into project. | ||||
|   for (const path of fileNames) memoryCache.versions[path] = 1 | ||||
|  | ||||
|   /** | ||||
|    * Get the extension for a transpiled file. | ||||
|    */ | ||||
|   const getExtension = config.options.jsx === ts.JsxEmit.Preserve ? | ||||
|     ((path: string) => /\.[tj]sx$/.test(path) ? '.jsx' : '.js') : | ||||
|     ((_: string) => '.js') | ||||
|  | ||||
|   /** | ||||
|    * Create the basic required function using transpile mode. | ||||
|    */ | ||||
|   let getOutput = function (code: string, fileName: string, lineOffset = 0): SourceOutput { | ||||
|     const result = ts.transpileModule(code, { | ||||
|       fileName, | ||||
|       transformers, | ||||
|       compilerOptions: config.options, | ||||
|       reportDiagnostics: true | ||||
|     }) | ||||
|  | ||||
|     const diagnosticList = result.diagnostics ? | ||||
|       filterDiagnostics(result.diagnostics, ignoreDiagnostics) : | ||||
|       [] | ||||
|  | ||||
|     if (diagnosticList.length) throw createTSError(diagnosticList) | ||||
|  | ||||
|     return [result.outputText, result.sourceMapText as string] | ||||
|   } | ||||
|  | ||||
|   let getTypeInfo = function (_code: string, _fileName: string, _position: number): TypeInfo { | ||||
|     throw new TypeError(`Type information is unavailable without "--type-check"`) | ||||
|   } | ||||
|  | ||||
|   // Use full language services when the fast option is disabled. | ||||
|   if (typeCheck) { | ||||
|     // Set the file contents into cache. | ||||
|     const updateMemoryCache = function (code: string, fileName: string) { | ||||
|       if (memoryCache.contents[fileName] !== code) { | ||||
|         memoryCache.contents[fileName] = code | ||||
|         memoryCache.versions[fileName] = (memoryCache.versions[fileName] || 0) + 1 | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Create the compiler host for type checking. | ||||
|     const serviceHost = { | ||||
|       getScriptFileNames: () => Object.keys(memoryCache.versions), | ||||
|       getScriptVersion: (fileName: string) => { | ||||
|         const version = memoryCache.versions[fileName] | ||||
|  | ||||
|         // We need to return `undefined` and not a string here because TypeScript will use | ||||
|         // `getScriptVersion` and compare against their own version - which can be `undefined`. | ||||
|         // If we don't return `undefined` it results in `undefined === "undefined"` and run | ||||
|         // `createProgram` again (which is very slow). Using a `string` assertion here to avoid | ||||
|         // TypeScript errors from the function signature (expects `(x: string) => string`). | ||||
|         return version === undefined ? undefined as any as string : String(version) | ||||
|       }, | ||||
|       getScriptSnapshot (fileName: string) { | ||||
|         // Read contents into TypeScript memory cache. | ||||
|         if (!Object.prototype.hasOwnProperty.call(memoryCache.contents, fileName)) { | ||||
|           memoryCache.contents[fileName] = readFile(fileName) | ||||
|         } | ||||
|  | ||||
|         const contents = memoryCache.contents[fileName] | ||||
|         if (contents === undefined) return | ||||
|         return ts.ScriptSnapshot.fromString(contents) | ||||
|       }, | ||||
|       fileExists: debugFn('fileExists', fileExists), | ||||
|       readFile: debugFn('readFile', readFile), | ||||
|       readDirectory: debugFn('readDirectory', ts.sys.readDirectory), | ||||
|       getDirectories: debugFn('getDirectories', ts.sys.getDirectories), | ||||
|       directoryExists: debugFn('directoryExists', ts.sys.directoryExists), | ||||
|       getNewLine: () => EOL, | ||||
|       getCurrentDirectory: () => cwd, | ||||
|       getCompilationSettings: () => config.options, | ||||
|       getDefaultLibFileName: () => ts.getDefaultLibFilePath(config.options), | ||||
|       getCustomTransformers: () => transformers | ||||
|     } | ||||
|  | ||||
|     const service = ts.createLanguageService(serviceHost) | ||||
|  | ||||
|     getOutput = function (code: string, fileName: string, lineOffset: number = 0) { | ||||
|       // Must set memory cache before attempting to read file. | ||||
|       updateMemoryCache(code, fileName) | ||||
|  | ||||
|       const output = service.getEmitOutput(fileName) | ||||
|  | ||||
|       // Get the relevant diagnostics - this is 3x faster than `getPreEmitDiagnostics`. | ||||
|       const diagnostics = service.getCompilerOptionsDiagnostics() | ||||
|         .concat(service.getSyntacticDiagnostics(fileName)) | ||||
|         .concat(service.getSemanticDiagnostics(fileName)) | ||||
|  | ||||
|       const diagnosticList = filterDiagnostics(diagnostics, ignoreDiagnostics) | ||||
|  | ||||
|       if (diagnosticList.length) throw createTSError(diagnosticList) | ||||
|  | ||||
|       if (output.emitSkipped) { | ||||
|         throw new TypeError(`${relative(cwd, fileName)}: Emit skipped`) | ||||
|       } | ||||
|  | ||||
|       // Throw an error when requiring `.d.ts` files. | ||||
|       if (output.outputFiles.length === 0) { | ||||
|         return ['', '']; | ||||
|       } | ||||
|       return [output.outputFiles[1].text, output.outputFiles[0].text] | ||||
|     } | ||||
|  | ||||
|     getTypeInfo = function (code: string, fileName: string, position: number) { | ||||
|       updateMemoryCache(code, fileName) | ||||
|  | ||||
|       const info = service.getQuickInfoAtPosition(fileName, position) | ||||
|       const name = ts.displayPartsToString(info ? info.displayParts : []) | ||||
|       const comment = ts.displayPartsToString(info ? info.documentation : []) | ||||
|  | ||||
|       return { name, comment } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const compile = readThrough(cachedir, options.cache === true, memoryCache, getOutput, getExtension) | ||||
|   const register: Register = { cwd, compile, getTypeInfo, extensions, cachedir, ts } | ||||
|  | ||||
|   // Register the extensions. | ||||
|   extensions.forEach(extension => { | ||||
|     registerExtension(extension, ignore, register, originalJsHandler) | ||||
|   }) | ||||
|  | ||||
|   return register | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Check if the filename should be ignored. | ||||
|  */ | ||||
| function shouldIgnore (filename: string, ignore: RegExp[]) { | ||||
|   const relname = normalizeSlashes(filename) | ||||
|  | ||||
|   return ignore.some(x => x.test(relname)) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Register the extension for node. | ||||
|  */ | ||||
| function registerExtension ( | ||||
|   ext: string, | ||||
|   ignore: RegExp[], | ||||
|   register: Register, | ||||
|   originalHandler: (m: NodeModule, filename: string) => any | ||||
| ) { | ||||
|   const old = require.extensions[ext] || originalHandler | ||||
|  | ||||
|   require.extensions[ext] = function (m: any, filename) { | ||||
|     if (shouldIgnore(filename, ignore)) { | ||||
|       return old(m, filename) | ||||
|     } | ||||
|  | ||||
|     const _compile = m._compile | ||||
|  | ||||
|     m._compile = function (code: string, fileName: string) { | ||||
|       debug('module._compile', fileName) | ||||
|  | ||||
|       return _compile.call(this, register.compile(code, fileName), fileName) | ||||
|     } | ||||
|  | ||||
|     return old(m, filename) | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Do post-processing on config options to support `ts-node`. | ||||
|  */ | ||||
| function fixConfig (ts: TSCommon, config: _ts.ParsedCommandLine) { | ||||
|   // Delete options that *should not* be passed through. | ||||
|   delete config.options.out | ||||
|   delete config.options.outFile | ||||
|   delete config.options.declarationDir | ||||
|   delete config.options.declarationMap | ||||
|   delete config.options.emitDeclarationOnly | ||||
|  | ||||
|   // Target ES5 output by default (instead of ES3). | ||||
|   if (config.options.target === undefined) { | ||||
|     config.options.target = ts.ScriptTarget.ES5 | ||||
|   } | ||||
|  | ||||
|   // Target CommonJS modules by default (instead of magically switching to ES6 when the target is ES6). | ||||
|   if (config.options.module === undefined) { | ||||
|     config.options.module = ts.ModuleKind.CommonJS | ||||
|   } | ||||
|  | ||||
|   return config | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Load TypeScript configuration. | ||||
|  */ | ||||
| function readConfig ( | ||||
|   cwd: string, | ||||
|   ts: TSCommon, | ||||
|   fileExists: (path: string) => boolean, | ||||
|   readFile: (path: string) => string | undefined, | ||||
|   compilerOptions?: object, | ||||
|   project?: string | null, | ||||
|   noProject?: boolean | null | ||||
| ): _ts.ParsedCommandLine { | ||||
|   let config = { compilerOptions: {} } | ||||
|   let basePath = normalizeSlashes(cwd) | ||||
|   let configFileName: string | undefined = undefined | ||||
|  | ||||
|   // Read project configuration when available. | ||||
|   if (!noProject) { | ||||
|     configFileName = project | ||||
|       ? normalizeSlashes(resolve(cwd, project)) | ||||
|       : ts.findConfigFile(normalizeSlashes(cwd), fileExists) | ||||
|  | ||||
|     if (configFileName) { | ||||
|       const result = ts.readConfigFile(configFileName, readFile) | ||||
|  | ||||
|       // Return diagnostics. | ||||
|       if (result.error) { | ||||
|         return { errors: [result.error], fileNames: [], options: {} } | ||||
|       } | ||||
|  | ||||
|       config = result.config | ||||
|       basePath = normalizeSlashes(dirname(configFileName)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Override default configuration options `ts-node` requires. | ||||
|   config.compilerOptions = Object.assign({}, config.compilerOptions, compilerOptions, DEFAULT_COMPILER_OPTIONS) | ||||
|  | ||||
|   return fixConfig(ts, ts.parseJsonConfigFileContent(config, ts.sys, basePath, undefined, configFileName)) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Internal source output. | ||||
|  */ | ||||
| type SourceOutput = [string, string] | ||||
|  | ||||
| /** | ||||
|  * Wrap the function with caching. | ||||
|  */ | ||||
| function readThrough ( | ||||
|   cachedir: string, | ||||
|   shouldCache: boolean, | ||||
|   memoryCache: MemoryCache, | ||||
|   compile: (code: string, fileName: string, lineOffset?: number) => SourceOutput, | ||||
|   getExtension: (fileName: string) => string | ||||
| ) { | ||||
|   if (shouldCache === false) { | ||||
|     return function (code: string, fileName: string, lineOffset?: number) { | ||||
|       debug('readThrough', fileName) | ||||
|  | ||||
|       const [value, sourceMap] = compile(code, fileName, lineOffset) | ||||
|       const output = updateOutput(value, fileName, sourceMap, getExtension) | ||||
|  | ||||
|       memoryCache.outputs[fileName] = output | ||||
|  | ||||
|       return output | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Make sure the cache directory exists before continuing. | ||||
|   mkdirp.sync(cachedir) | ||||
|  | ||||
|   return function (code: string, fileName: string, lineOffset?: number) { | ||||
|     debug('readThrough', fileName) | ||||
|  | ||||
|     const cachePath = join(cachedir, getCacheName(code, fileName)) | ||||
|     const extension = getExtension(fileName) | ||||
|     const outputPath = `${cachePath}${extension}` | ||||
|  | ||||
|     try { | ||||
|       const output = readFileSync(outputPath, 'utf8') | ||||
|       if (isValidCacheContent(output)) { | ||||
|         memoryCache.outputs[fileName] = output | ||||
|         return output | ||||
|       } | ||||
|     } catch (err) {/* Ignore. */} | ||||
|  | ||||
|     const [value, sourceMap] = compile(code, fileName, lineOffset) | ||||
|     const output = updateOutput(value, fileName, sourceMap, getExtension) | ||||
|  | ||||
|     memoryCache.outputs[fileName] = output | ||||
|     writeFileSync(outputPath, output) | ||||
|  | ||||
|     return output | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Update the output remapping the source map. | ||||
|  */ | ||||
| function updateOutput (outputText: string, fileName: string, sourceMap: string, getExtension: (fileName: string) => string) { | ||||
|   const base64Map = bufferFrom(updateSourceMap(sourceMap, fileName), 'utf8').toString('base64') | ||||
|   const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}` | ||||
|   const sourceMapLength = `${basename(fileName)}.map`.length + (getExtension(fileName).length - extname(fileName).length) | ||||
|  | ||||
|   return outputText.slice(0, -sourceMapLength) + sourceMapContent | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Update the source map contents for improved output. | ||||
|  */ | ||||
| function updateSourceMap (sourceMapText: string, fileName: string) { | ||||
|   const sourceMap = JSON.parse(sourceMapText) | ||||
|   sourceMap.file = fileName | ||||
|   sourceMap.sources = [fileName] | ||||
|   delete sourceMap.sourceRoot | ||||
|   return JSON.stringify(sourceMap) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Get the file name for the cache entry. | ||||
|  */ | ||||
| function getCacheName (sourceCode: string, fileName: string) { | ||||
|   return crypto.createHash('sha256') | ||||
|     .update(extname(fileName), 'utf8') | ||||
|     .update('\x00', 'utf8') | ||||
|     .update(sourceCode, 'utf8') | ||||
|     .digest('hex') | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Ensure the given cached content is valid by sniffing for a base64 encoded '}' | ||||
|  * at the end of the content, which should exist if there is a valid sourceMap present. | ||||
|  */ | ||||
| function isValidCacheContent (contents: string) { | ||||
|   return /(?:9|0=|Q==)$/.test(contents.slice(-3)) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Create a hash of the current configuration. | ||||
|  */ | ||||
| function getCompilerDigest (obj: object) { | ||||
|   return crypto.createHash('sha256').update(JSON.stringify(obj), 'utf8').digest('hex') | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Filter diagnostics. | ||||
|  */ | ||||
| function filterDiagnostics (diagnostics: _ts.Diagnostic[], ignore: number[]) { | ||||
|   return diagnostics.filter(x => ignore.indexOf(x.code) === -1) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user