all files / oak/ index.js

19.72% Statements 14/71
7.41% Branches 2/27
25% Functions 1/4
20.29% Lines 14/69
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241                                                                                                                                                                                                                                                                                                                            59×                                                                                                                                          
#!/usr/bin/env node
 
const { resolve, join, basename } = require('path')
const Module = require('module')
const _ = require('lodash')
 
require(join(__dirname, 'lib', 'util'))
 
const program = require('commander')
 
const {
  version: oakVersion,
  engines: {
    node: nodeVersion
  },
  dependencies: {
    electron: electronVersion
  }
} = require(join(__dirname, 'package.json'))
 
let opts = {}
 
program
  .version(oakVersion)
  .description('If you load oak with a script path, no commandline options will apply automatically.')
  .option(
    '-b, --background [String]',
    'Hex background color for initial window. Example: #f0f0f0',
    '#000000'
  )
  .option(
    '-f, --fullscreen [Boolean]',
    'Set the window to full width and height. This overrides the --size option',
    _.toBoolean, true
  )
  .option(
    '-k, --kiosk [Boolean]',
    'Kiosk mode, which is fullscreen by default. On OSX this will cause the workspace to shift to a whole new one',
    _.toBoolean, false
  )
  .option(
    '-s, --size [String]',
    'Window size in WIDTHxHEIGHT format. Example: 1024x768. This will over ride both --kiosk and --fullscreen',
    /(\d+)x(\d+)/
  )
  .option(
    '-x, --x [Number]',
    'Window X position',
    _.toInteger, 0
  )
  .option(
    '-y, --y [Number]',
    'Window Y position',
    _.toInteger, 0
  )
  .option(
    '-t, --title [String]',
    'Window title',
    _.toString, 'Oak'
  )
  .option(
    '-t, --ontop [Boolean]',
    'Start window ontop of others',
    _.toBoolean, true
  )
  .option(
    '-D, --display [Number]',
    'Display to use',
    _.toInteger, 0
  )
  .option(
    '-S, --shortcut [List]',
    'Register shortcuts, comma separated. reload,quit',
    v => v.split(','), []
  )
  .option(
    '-u, --useragent [String]',
    'User-Agent string',
    _.toString
  )
  .option(
    '-F, --frame [Boolean]',
    'Show window frame',
    _.toBoolean, false
  )
  .option(
    '--show [Boolean]',
    'Show window on start',
    _.toBoolean, true
  )
  .option(
    '-n, --node [Boolean]',
    'Enable node integration',
    _.toBoolean, false
  )
  .option(
    '-i, --insecure [Boolean]',
    'Allow insecure connections (not recommended)',
    _.toBoolean, false
  )
  .option(
    '-c, --cache [Boolean]',
    'Use standard caching, setting this to false has the same effect as the --disable-http-cache chrome flag',
    _.toBoolean, true
  )
  .option(
    '-d, --debugger [Boolean]',
    'Open chrome dev tools on load',
    _.toBoolean, false
  )
  .option(
    '--sslExceptions [Array]',
    'Bypass SSL security for specific hosts. This uses a host pattern. Example: *.mysite.com',
    v => v.split(','), []
  )
 
  .arguments('<uri>')
  .action(function (uri, options) {
    if (uri) {
      opts.url = uri
    }
  })
 
program
  .command('version [type]')
  .description('Prints version, options are are `all`, `oak`, `electron`, `node`')
  .option('-j, --json', 'Output in JSON format', false)
  .action(function (type = 'oak', opts) {
    let exitVal = 0
    let all = {
      oak: oakVersion,
      electron: electronVersion,
      node: nodeVersion
    }
    let out = all.oak
    switch (type) {
      case 'oak':
      case 'electron':
      case 'node': {
        out = {}
        out[type] = all[type]
        if (!_.isUndefined(opts.json)) {
          out = JSON.stringify(out, null, 2)
          break
        } else {
          out = out[type]
        }
        out[type] = all[type]
        break
      }
      case 'all': {
        out = JSON.stringify(all, null, 2)
        break
      }
      default: {
        out = 'Invalid name for version'
        exitVal = 1
        break
      }
    }
    console.log(out)
    process.exit(exitVal)
  })
 
// oak gets loaded from this path
const oakPath = join(__dirname, 'lib', 'index.js')
 
// resolve future require('oak') to our core path
const origResolve = Module._resolveFilename
Module._resolveFilename = function (request) {
  return request === 'oak' ? oakPath : origResolve(...[...arguments])
}
 
const oak = require('oak')
 
// Attaches oak property to |exports|
exports.defineProperties = function (exports) {
  return Object.defineProperties(exports, {
    oak: {
      enumerable: false,
      get: () => require('oak')
    }
  })
}
 
// setting temp argv for commander to use if we are inside our compiled app
let tmpArgv = process.argv
 
if (_.get(process.env, 'CHROME_DESKTOP') === 'oak.desktop' || basename(process.argv[0]).indexOf('oak') !== -1) {
  tmpArgv = ['', ...process.argv]
}
 
program.parse(tmpArgv)
 
if (!opts.url) {
  program.help()
}
 
opts = _(program._events)
  .omit('*', 'version')
  .mapValues((v, k) => program[k])
  .omitBy(_.isUndefined)
  .merge(opts)
  .value()
 
if (require('url').parse(opts.url).protocol !== null) {
  // if the url argument is a valid URI, load that directly
  oak.on('ready', () => oak.load(opts))
} else {
  let resolvedURL = resolve(opts.url.replace(/~\//g, process.env.HOME))
  // check to see if it's a JSON file
  if (resolvedURL.split('.').pop().toLowerCase() === 'json') {
    try {
      oak.on('ready', () => oak.load(require(resolvedURL)))
    } catch (e) {
      console.error('Error (Invalid JSON):', e.message)
      process.exit(1)
    }
  } else {
    // if none of those, require it as a file
    try {
      require(resolvedURL)
    } catch (e) {
      if (e.constructor.name === 'SyntaxError') {
        console.error('\nYou have a SyntaxError, but you might have specified a file that cannot be imported using require(). Please check your file type to make sure it is requireable.\n\n', e)
        process.exit(1)
      }
      if (e.code === 'MODULE_NOT_FOUND') {
        console.error('Error: Not a valid URL or file path. Make sure you specify a valid URI with a protocol prefix (i.e. http:// or file://)', e.message)
        process.exit(1)
      }
      if (e.message.indexOf('NODE_MODULE_VERSION') !== -1) {
        console.error(`Error: Wrong node modules version for electron@${electronVersion}.\nPlease use oak-rebuild, or use electron-rebuild and specify node v${nodeVersion}`)
        process.exit(1)
      }
      console.error(e)
      process.exit(1)
    }
  }
}