Skip to content

Commit

Permalink
Update project, parse environment variables (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey authored Oct 6, 2016
1 parent fb65422 commit 7e3d6f4
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ notifications:
on_failure: change

script:
- npm run build
- npm run lint
- npm rm tslint
- npm install $TYPESCRIPT --force
Expand All @@ -16,6 +15,7 @@ env:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- TYPESCRIPT=typescript@next

node_js:
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"build": "npm run build-ts",
"build-ts": "rm -rf dist && tsc",
"test-spec": "mocha dist/**/*.spec.js -R spec --bail",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- dist/**/*.spec.js -R spec --bail",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- \"dist/**/*.spec.js\" -R spec --bail",
"test": "npm run build && npm run lint && npm run test-cov",
"prepublish": "typings install && npm run build"
},
Expand Down Expand Up @@ -52,7 +52,7 @@
"proxyquire": "^1.7.2",
"semver": "^5.1.0",
"tslint": "^3.13.0",
"tslint-config-standard": "^1.3.0",
"tslint-config-standard": "^1.5.0",
"typescript": "^2.0.3",
"typings": "^1.0.4"
},
Expand All @@ -66,6 +66,7 @@
"pinkie": "^2.0.4",
"source-map-support": "^0.4.0",
"tsconfig": "^5.0.2",
"xtend": "^4.0.0"
"xtend": "^4.0.0",
"yn": "^1.2.0"
}
}
4 changes: 2 additions & 2 deletions src/_bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function isFlagOnly (arg: string) {
const name = arg.replace(/^--?/, '')

// The value is part of this argument.
if (/=/.test(name)) {
if (/=/.test(name) || /^--no-/.test(arg)) {
return true
}

Expand Down Expand Up @@ -177,7 +177,7 @@ for (const id of arrify(argv.require)) {

// Execute the main contents (either eval, script or piped).
if (isEvalScript) {
evalAndExit(code, isPrinted)
evalAndExit(code as string, isPrinted)
} else {
if (stop < process.argv.length) {
const args = process.argv.slice(stop)
Expand Down
4 changes: 2 additions & 2 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { register, VERSION } from './index'

const testDir = join(__dirname, '../tests')
const EXEC_PATH = join(__dirname, '../dist/bin')
const BIN_EXEC = `node ${EXEC_PATH}`
const BIN_EXEC = `node "${EXEC_PATH}" --project "${testDir}"`

describe('ts-node', function () {
this.timeout(10000)
Expand Down Expand Up @@ -171,7 +171,7 @@ describe('ts-node', function () {
})

describe('register', function () {
register({ project: join(testDir, '..') })
register({ project: testDir })

it('should be able to require typescript', function () {
const m = require('../tests/module')
Expand Down
120 changes: 68 additions & 52 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import extend = require('xtend')
import arrify = require('arrify')
import mkdirp = require('mkdirp')
import crypto = require('crypto')
import yn = require('yn')
import { BaseError } from 'make-error'
import * as TS from 'typescript'
import { loadSync } from 'tsconfig'
Expand Down Expand Up @@ -57,14 +58,14 @@ export const VERSION = pkg.version
* Registration options.
*/
export interface Options {
fast?: boolean
lazy?: boolean
cache?: boolean
fast?: boolean | null
lazy?: boolean | null
cache?: boolean | null
cacheDirectory?: string
compiler?: string
project?: string
ignoreWarnings?: Array<number | string>
disableWarnings?: boolean
disableWarnings?: boolean | null
getFile?: (fileName: string) => string
fileExists?: (fileName: string) => boolean
compilerOptions?: any
Expand Down Expand Up @@ -93,14 +94,21 @@ export interface TypeInfo {
const DEFAULT_OPTIONS: Options = {
getFile,
fileExists,
cache: process.env.TS_NODE_CACHE,
cache: yn(process.env.TS_NODE_CACHE),
cacheDirectory: process.env.TS_NODE_CACHE_DIRECTORY || join(tmpdir(), 'ts-node'),
disableWarnings: process.env.TS_NODE_DISABLE_WARNINGS,
disableWarnings: yn(process.env.TS_NODE_DISABLE_WARNINGS),
compiler: process.env.TS_NODE_COMPILER,
compilerOptions: process.env.TS_NODE_COMPILER_OPTIONS,
project: process.env.TS_NODE_PROJECT,
ignoreWarnings: process.env.TS_NODE_IGNORE_WARNINGS,
fast: process.env.TS_NODE_FAST
ignoreWarnings: split(process.env.TS_NODE_IGNORE_WARNINGS),
fast: yn(process.env.TS_NODE_FAST)
}

/**
* Split a string array of values.
*/
function split (value: string | undefined) {
return value ? value.split(/ *, */g) : []
}

export interface Register {
Expand All @@ -114,14 +122,17 @@ export interface Register {
*/
export function register (opts?: Options): () => Register {
const options = extend(DEFAULT_OPTIONS, opts)
const compiler = options.compiler || 'typescript'
const ignoreWarnings = arrify(options.ignoreWarnings).map(Number)
const disableWarnings = !!options.disableWarnings
const getFile = options.getFile as ((fileName: string) => string)
const fileExists = options.fileExists as ((fileName: string) => boolean)
const cache = !!options.cache
const fast = !!options.fast
let result: Register

// Enable compiler overrides.
options.compiler = options.compiler || 'typescript'
options.ignoreWarnings = arrify(options.ignoreWarnings).map(Number)

// Parse compiler options as JSON.
options.compilerOptions = typeof options.compilerOptions === 'string' ?
const compilerOptions = typeof options.compilerOptions === 'string' ?
JSON.parse(options.compilerOptions) :
options.compilerOptions

Expand All @@ -135,18 +146,22 @@ export function register (opts?: Options): () => Register {
if (project.sourceMaps[fileName]) {
return {
url: project.sourceMaps[fileName],
map: options.getFile(project.sourceMaps[fileName])
map: getFile(project.sourceMaps[fileName])
}
}
}
})

// Require the TypeScript compiler and configuration.
const cwd = process.cwd()
const ts: typeof TS = require(options.compiler)
const config = readConfig(options, cwd, ts)
const configDiagnostics = formatDiagnostics(config.errors, options, cwd, ts)
const cachedir = join(resolve(cwd, options.cacheDirectory), getCompilerDigest(ts, options, config))
const ts: typeof TS = require(compiler)
const config = readConfig(compilerOptions, options.project, cwd, ts)
const configDiagnostics = formatDiagnostics(config.errors, ignoreWarnings, disableWarnings, cwd, ts)

const cachedir = join(
resolve(cwd, options.cacheDirectory),
getCompilerDigest({ version: ts.version, fast, ignoreWarnings, disableWarnings, config, compiler })
)

// Make sure the temp cache directory exists.
mkdirp.sync(cachedir)
Expand Down Expand Up @@ -179,24 +194,24 @@ export function register (opts?: Options): () => Register {
})

const diagnosticList = result.diagnostics ?
formatDiagnostics(result.diagnostics, options, cwd, ts) :
formatDiagnostics(result.diagnostics, ignoreWarnings, disableWarnings, cwd, ts) :
[]

if (diagnosticList.length) {
throw new TSError(diagnosticList)
}

return [result.outputText, result.sourceMapText]
return [result.outputText, result.sourceMapText as string]
}

let compile = readThrough(cachedir, options, project, getOutput)
let compile = readThrough(cachedir, cache, getFile, fileExists, project, getOutput)

let getTypeInfo = function (fileName: string, position: number): TypeInfo {
throw new TypeError(`No type information available under "--fast" mode`)
}

// Use full language services when the fast option is disabled.
if (!options.fast) {
if (!fast) {
// Add the file to the project.
const addVersion = function (fileName: string) {
if (!project.versions.hasOwnProperty(fileName)) {
Expand All @@ -216,11 +231,11 @@ export function register (opts?: Options): () => Register {
getScriptVersion: (fileName: string) => String(project.versions[fileName]),
getScriptSnapshot (fileName: string) {
if (!project.cache.hasOwnProperty(fileName)) {
if (!options.fileExists(fileName)) {
if (!fileExists(fileName)) {
return undefined
}

project.cache[fileName] = options.getFile(fileName)
project.cache[fileName] = getFile(fileName)
}

return ts.ScriptSnapshot.fromString(project.cache[fileName])
Expand All @@ -243,7 +258,7 @@ export function register (opts?: Options): () => Register {
.concat(service.getSyntacticDiagnostics(fileName))
.concat(service.getSemanticDiagnostics(fileName))

const diagnosticList = formatDiagnostics(diagnostics, options, cwd, ts)
const diagnosticList = formatDiagnostics(diagnostics, ignoreWarnings, disableWarnings, cwd, ts)

if (output.emitSkipped) {
diagnosticList.push(`${relative(cwd, fileName)}: Emit skipped`)
Expand All @@ -258,15 +273,15 @@ export function register (opts?: Options): () => Register {
throw new TypeError(
'Unable to require `.d.ts` file.\n' +
'This is usually the result of a faulty configuration or import. ' +
'Make sure there\'s a `.js` (or another extension with matching node ' +
`loader attached before \`ts-node\`) available alongside \`${fileName}\`.`
'Make sure there is a `.js`, `.json` or another executable extension and ' +
`loader (attached before \`ts-node\`) available alongside \`${fileName}\`.`
)
}

return [output.outputFiles[1].text, output.outputFiles[0].text]
}

compile = readThrough(cachedir, options, project, function (code: string, fileName: string) {
compile = readThrough(cachedir, cache, getFile, fileExists, project, function (code: string, fileName: string) {
addVersion(fileName)
addCache(code, fileName)

Expand Down Expand Up @@ -328,16 +343,16 @@ export function register (opts?: Options): () => Register {
/**
* Load TypeScript configuration.
*/
function readConfig (options: Options, cwd: string, ts: TSCommon) {
const result = loadSync(cwd, options.project)
function readConfig (compilerOptions: any, project: string | boolean | undefined, cwd: string, ts: TSCommon) {
const result = loadSync(cwd, typeof project === 'string' ? project : undefined)

result.config.compilerOptions = extend(
{
target: 'es5',
module: 'commonjs'
},
result.config.compilerOptions,
options.compilerOptions,
compilerOptions,
{
sourceMap: true,
inlineSourceMap: false,
Expand All @@ -359,7 +374,11 @@ function readConfig (options: Options, cwd: string, ts: TSCommon) {
return ts.parseConfigFile(result.config, ts.sys, basePath)
}

return ts.parseJsonConfigFileContent(result.config, ts.sys, basePath, null, result.path)
if (typeof ts.parseJsonConfigFileContent === 'function') {
return ts.parseJsonConfigFileContent(result.config, ts.sys, basePath, null, result.path as string)
}

throw new TypeError('Could not find a compatible `parseConfigFile` function')
}

/**
Expand All @@ -372,11 +391,13 @@ type SourceOutput = [string, string]
*/
function readThrough (
cachedir: string,
options: Options,
cache: boolean,
getFile: (fileName: string) => string,
fileExists: (fileName: string) => boolean,
project: Project,
compile: (code: string, fileName: string) => SourceOutput
) {
if (options.cache === false) {
if (cache === false) {
return function (code: string, fileName: string) {
const cachePath = join(cachedir, getCacheName(code, fileName))
const sourceMapPath = `${cachePath}.js.map`
Expand All @@ -401,8 +422,8 @@ function readThrough (
project.sourceMaps[fileName] = sourceMapPath

// Use the cache when available.
if (options.fileExists(outputPath)) {
return options.getFile(outputPath)
if (fileExists(outputPath)) {
return getFile(outputPath)
}

const out = compile(code, fileName)
Expand Down Expand Up @@ -453,19 +474,8 @@ function getCacheName (sourceCode: string, fileName: string) {
/**
* Create a hash of the current configuration.
*/
function getCompilerDigest (ts: TSCommon, options: Options, config: any) {
return join(
crypto.createHash('sha1')
// TypeScript version.
.update(ts.version, 'utf8')
.update('\0', 'utf8')
// Configuration options.
.update(JSON.stringify(options), 'utf8')
.update('\0', 'utf8')
// Compiler options.
.update(JSON.stringify(config), 'utf8')
.digest('hex')
)
function getCompilerDigest (opts: any) {
return crypto.createHash('sha1').update(JSON.stringify(opts), 'utf8').digest('hex')
}

/**
Expand Down Expand Up @@ -509,14 +519,20 @@ export function getFile (fileName: string): string {
/**
* Format an array of diagnostics.
*/
function formatDiagnostics (diagnostics: TS.Diagnostic[], options: Options, cwd: string, ts: TSCommon) {
if (options.disableWarnings) {
function formatDiagnostics (
diagnostics: TS.Diagnostic[],
ignore: number[],
disable: boolean,
cwd: string,
ts: TSCommon
) {
if (disable) {
return []
}

return diagnostics
.filter(function (diagnostic) {
return options.ignoreWarnings.indexOf(diagnostic.code) === -1
return ignore.indexOf(diagnostic.code) === -1
})
.map(function (diagnostic) {
return formatDiagnostic(diagnostic, cwd, ts)
Expand Down
5 changes: 5 additions & 0 deletions tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files": [
"../typings/index.d.ts"
]
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"module": "commonjs",
"declaration": true,
"noImplicitAny": true,
"strictNullChecks": true,
"removeComments": true,
"moduleResolution": "node",
"sourceMap": true,
Expand Down
7 changes: 4 additions & 3 deletions typings.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"dependencies": {
"arrify": "registry:npm/arrify#1.0.0+20160211003958",
"arrify": "registry:npm/arrify#1.0.0+20160723033700",
"chalk": "registry:npm/chalk#1.0.0+20160211003958",
"diff": "registry:npm/diff#2.0.0+20160211003958",
"make-error": "registry:npm/make-error#1.0.0+20160211003958",
"minimist": "registry:npm/minimist#1.0.0+20160229232932",
"mkdirp": "registry:npm/mkdirp#0.5.0+20160222053049",
"proxyquire": "registry:npm/proxyquire#1.0.0+20160211003958",
"source-map-support": "registry:npm/source-map-support#0.3.0+20160413183746",
"source-map-support": "registry:npm/source-map-support#0.3.0+20161006200546",
"tsconfig": "npm:tsconfig",
"xtend": "registry:npm/xtend#4.0.0+20160211003958"
"xtend": "registry:npm/xtend#4.0.0+20160211003958",
"yn": "registry:npm/yn#1.2.0+20161006191459"
},
"globalDependencies": {
"node": "github:borisyankov/DefinitelyTyped/node/node.d.ts#b37afda34daa6186c3f143609555fcd6d70b249f",
Expand Down

0 comments on commit 7e3d6f4

Please sign in to comment.