PageRenderTime 22ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/index.coffee

http://github.com/jashkenas/coffee-script
CoffeeScript | 139 lines | 91 code | 23 blank | 25 comment | 18 complexity | 9b640a8d51af8503efd72eb551554b5b MD5 | raw file
  1# Node.js Implementation
  2CoffeeScript  = require './coffeescript'
  3fs            = require 'fs'
  4vm            = require 'vm'
  5path          = require 'path'
  6
  7helpers       = CoffeeScript.helpers
  8
  9CoffeeScript.transpile = (js, options) ->
 10  try
 11    babel = require '@babel/core'
 12  catch
 13    try
 14      babel = require 'babel-core'
 15    catch
 16      # This error is only for Node, as CLI users will see a different error
 17      # earlier if they don’t have Babel installed.
 18      throw new Error 'To use the transpile option, you must have the \'@babel/core\' module installed'
 19  babel.transform js, options
 20
 21# The `compile` method shared by the CLI, Node and browser APIs.
 22universalCompile = CoffeeScript.compile
 23# The `compile` method particular to the Node API.
 24CoffeeScript.compile = (code, options) ->
 25  # Pass a reference to Babel into the compiler, so that the transpile option
 26  # is available in the Node API. We need to do this so that tools like Webpack
 27  # can `require('coffeescript')` and build correctly, without trying to
 28  # require Babel.
 29  if options?.transpile
 30    options.transpile.transpile = CoffeeScript.transpile
 31  universalCompile.call CoffeeScript, code, options
 32
 33# Compile and execute a string of CoffeeScript (on the server), correctly
 34# setting `__filename`, `__dirname`, and relative `require()`.
 35CoffeeScript.run = (code, options = {}) ->
 36  mainModule = require.main
 37
 38  # Set the filename.
 39  mainModule.filename = process.argv[1] =
 40    if options.filename then fs.realpathSync(options.filename) else '<anonymous>'
 41
 42  # Clear the module cache.
 43  mainModule.moduleCache and= {}
 44
 45  # Assign paths for node_modules loading
 46  dir = if options.filename?
 47    path.dirname fs.realpathSync options.filename
 48  else
 49    fs.realpathSync '.'
 50  mainModule.paths = require('module')._nodeModulePaths dir
 51
 52  # Save the options for compiling child imports.
 53  mainModule.options = options
 54
 55  # Compile.
 56  if not helpers.isCoffee(mainModule.filename) or require.extensions
 57    answer = CoffeeScript.compile code, options
 58    code = answer.js ? answer
 59
 60  mainModule._compile code, mainModule.filename
 61
 62# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
 63# The CoffeeScript REPL uses this to run the input.
 64CoffeeScript.eval = (code, options = {}) ->
 65  return unless code = code.trim()
 66  createContext = vm.Script.createContext ? vm.createContext
 67
 68  isContext = vm.isContext ? (ctx) ->
 69    options.sandbox instanceof createContext().constructor
 70
 71  if createContext
 72    if options.sandbox?
 73      if isContext options.sandbox
 74        sandbox = options.sandbox
 75      else
 76        sandbox = createContext()
 77        sandbox[k] = v for own k, v of options.sandbox
 78      sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
 79    else
 80      sandbox = global
 81    sandbox.__filename = options.filename || 'eval'
 82    sandbox.__dirname  = path.dirname sandbox.__filename
 83    # define module/require only if they chose not to specify their own
 84    unless sandbox isnt global or sandbox.module or sandbox.require
 85      Module = require 'module'
 86      sandbox.module  = _module  = new Module(options.modulename || 'eval')
 87      sandbox.require = _require = (path) ->  Module._load path, _module, true
 88      _module.filename = sandbox.__filename
 89      for r in Object.getOwnPropertyNames require when r not in ['paths', 'arguments', 'caller']
 90        _require[r] = require[r]
 91      # use the same hack node currently uses for their own REPL
 92      _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
 93      _require.resolve = (request) -> Module._resolveFilename request, _module
 94  o = {}
 95  o[k] = v for own k, v of options
 96  o.bare = on # ensure return value
 97  js = CoffeeScript.compile code, o
 98  if sandbox is global
 99    vm.runInThisContext js
100  else
101    vm.runInContext js, sandbox
102
103CoffeeScript.register = -> require './register'
104
105# Throw error with deprecation warning when depending upon implicit `require.extensions` registration
106if require.extensions
107  for ext in CoffeeScript.FILE_EXTENSIONS then do (ext) ->
108    require.extensions[ext] ?= ->
109      throw new Error """
110      Use CoffeeScript.register() or require the coffeescript/register module to require #{ext} files.
111      """
112
113CoffeeScript._compileRawFileContent = (raw, filename, options = {}) ->
114
115  # Strip the Unicode byte order mark, if this file begins with one.
116  stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
117
118  options = Object.assign {}, options,
119    filename: filename
120    literate: helpers.isLiterate filename
121    sourceFiles: [filename]
122    inlineMap: yes # Always generate a source map, so that stack traces line up.
123
124  try
125    answer = CoffeeScript.compile stripped, options
126  catch err
127    # As the filename and code of a dynamically loaded file will be different
128    # from the original file compiled with CoffeeScript.run, add that
129    # information to error so it can be pretty-printed later.
130    throw helpers.updateSyntaxError err, stripped, filename
131
132  answer
133
134CoffeeScript._compileFile = (filename, options = {}) ->
135  raw = fs.readFileSync filename, 'utf8'
136
137  CoffeeScript._compileRawFileContent raw, filename, options
138
139module.exports = CoffeeScript