forked from enviPath/enviPy
Current Dev State
This commit is contained in:
308
static/js/ketcher2/node_modules/budo/lib/budo.js
generated
vendored
Normal file
308
static/js/ketcher2/node_modules/budo/lib/budo.js
generated
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
var bole = require('bole')
|
||||
var xtend = require('xtend')
|
||||
var once = require('once')
|
||||
var path = require('path')
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
var isMatch = require('micromatch')
|
||||
var openUrl = require('opn')
|
||||
var internalIp = require('internal-ip')
|
||||
var garnish = require('garnish')
|
||||
|
||||
var defaults = require('./parse-args').defaults
|
||||
var getPorts = require('./get-ports')
|
||||
var createServer = require('./server')
|
||||
var createBundler = require('./bundler')
|
||||
var createFileWatch = require('./file-watch')
|
||||
var createReloadServer = require('./reload/server')
|
||||
var mapEntry = require('./map-entry')
|
||||
|
||||
var noop = function () {}
|
||||
|
||||
module.exports = createBudo
|
||||
function createBudo (entries, opts) {
|
||||
var log = bole('budo')
|
||||
|
||||
// if no entries are specified, just options
|
||||
if (entries && !Array.isArray(entries) && typeof entries === 'object') {
|
||||
opts = entries
|
||||
entries = []
|
||||
}
|
||||
|
||||
// do not mutate user options
|
||||
opts = xtend({}, defaults, { stream: false }, opts)
|
||||
entries = entries || []
|
||||
|
||||
// perhaps later this will be configurable
|
||||
opts.cwd = process.cwd()
|
||||
|
||||
// log to output stream
|
||||
if (opts.stream) {
|
||||
// by default, pretty-print to the stream with info logging
|
||||
if (!opts.ndjson) {
|
||||
var pretty = garnish({
|
||||
level: opts.verbose ? 'debug' : 'info',
|
||||
name: 'budo'
|
||||
})
|
||||
pretty.pipe(opts.stream)
|
||||
opts.stream = pretty
|
||||
}
|
||||
|
||||
bole.output({
|
||||
stream: opts.stream,
|
||||
level: 'debug'
|
||||
})
|
||||
}
|
||||
|
||||
// optionally allow as arrays
|
||||
entries = [].concat(entries).filter(Boolean)
|
||||
|
||||
var entryObjects = entries.map(mapEntry)
|
||||
var entryFiles = entryObjects.map(function (entry) {
|
||||
return entry.from
|
||||
})
|
||||
|
||||
if (opts.serve && typeof opts.serve !== 'string') {
|
||||
throw new TypeError('opts.serve must be a string or undefined')
|
||||
} else if (!opts.serve && entries.length > 0) {
|
||||
opts.serve = entryObjects[0].url
|
||||
}
|
||||
|
||||
// default to cwd
|
||||
if (!opts.dir || opts.dir.length === 0) {
|
||||
opts.dir = opts.cwd
|
||||
}
|
||||
|
||||
var emitter = new EventEmitter()
|
||||
var bundler, middleware
|
||||
|
||||
if (entries.length > 0 || (opts.browserify && opts.browserify.entries)) {
|
||||
bundler = createBundler(entryFiles, opts)
|
||||
middleware = bundler.middleware
|
||||
|
||||
bundler.on('log', function (ev) {
|
||||
if (ev.type === 'bundle') {
|
||||
var time = ev.elapsed
|
||||
ev.elapsed = time
|
||||
ev.name = 'browserify'
|
||||
ev.type = undefined
|
||||
ev.colors = {
|
||||
elapsed: time > 1000 ? 'yellow' : 'dim',
|
||||
message: 'dim '
|
||||
}
|
||||
log.info(ev)
|
||||
}
|
||||
})
|
||||
|
||||
// uncaught syntax errors should not stop the server
|
||||
// this only happens when errorHandler: false
|
||||
bundler.on('error', function (err) {
|
||||
console.error('Error:', err.message ? err.message : err)
|
||||
})
|
||||
bundler.on('bundle-error', emitter.emit.bind(emitter, 'bundle-error'))
|
||||
bundler.on('update', emitter.emit.bind(emitter, 'update'))
|
||||
bundler.on('pending', emitter.emit.bind(emitter, 'pending'))
|
||||
|
||||
emitter.on('update', function (contents, deps) {
|
||||
if (deps.length > 1) {
|
||||
log.debug({
|
||||
name: 'browserify',
|
||||
message: deps.length + ' files changed'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var defaultWatchGlob = opts.watchGlob || '**/*.{html,css}'
|
||||
var server = null
|
||||
var closed = false
|
||||
var started = false
|
||||
var fileWatcher = null
|
||||
var reloader = null
|
||||
var deferredWatch = noop
|
||||
var deferredLive = noop
|
||||
|
||||
// public API
|
||||
emitter.close = once(close)
|
||||
emitter.reload = reload
|
||||
emitter.live = live
|
||||
emitter.watch = watch
|
||||
|
||||
// setup defaults for live reload / watchify
|
||||
if (opts.live) {
|
||||
var initialLiveOpts = typeof opts.live === 'object' ? opts.live : undefined
|
||||
emitter
|
||||
.watch()
|
||||
.live(initialLiveOpts)
|
||||
.on('watch', function (ev, file) {
|
||||
if (ev !== 'change' && ev !== 'add') {
|
||||
return
|
||||
}
|
||||
defaultFileEvent(file)
|
||||
})
|
||||
.on('pending', function () {
|
||||
defaultFileEvent(opts.serve)
|
||||
})
|
||||
}
|
||||
|
||||
// First, setup a server
|
||||
createServer(middleware, opts, function (err, serverInstance) {
|
||||
if (err) {
|
||||
emitter.emit('error', err)
|
||||
return
|
||||
}
|
||||
|
||||
server = serverInstance
|
||||
|
||||
// start portfinding + connect
|
||||
getPorts(opts, handlePorts)
|
||||
})
|
||||
|
||||
return emitter
|
||||
|
||||
function defaultFileEvent (file) {
|
||||
var filename = path.basename(file)
|
||||
if ((Array.isArray(opts.live) || typeof opts.live === 'string') &&
|
||||
isMatch(filename, opts.live).length === 0) {
|
||||
return
|
||||
}
|
||||
emitter.reload(file)
|
||||
}
|
||||
|
||||
function reload (file) {
|
||||
process.nextTick(emitter.emit.bind(emitter, 'reload', file))
|
||||
if (reloader) {
|
||||
reloader.reload(file)
|
||||
}
|
||||
}
|
||||
|
||||
// enable file watch capabilities
|
||||
function watch (glob, watchOpt) {
|
||||
if (!started) {
|
||||
deferredWatch = emitter.watch.bind(null, glob, watchOpt)
|
||||
} else {
|
||||
// destroy previous
|
||||
if (fileWatcher) fileWatcher.close()
|
||||
glob = glob && glob.length > 0 ? glob : defaultWatchGlob
|
||||
glob = Array.isArray(glob) ? glob : [ glob ]
|
||||
watchOpt = xtend({ poll: opts.poll }, watchOpt)
|
||||
|
||||
fileWatcher = createFileWatch(glob, watchOpt)
|
||||
fileWatcher.on('watch', emitter.emit.bind(emitter, 'watch'))
|
||||
}
|
||||
return emitter
|
||||
}
|
||||
|
||||
// enables LiveReload capabilities
|
||||
function live (liveOpts) {
|
||||
if (!started) {
|
||||
deferredLive = emitter.live.bind(null, liveOpts)
|
||||
} else {
|
||||
// destroy previous
|
||||
if (reloader) reloader.close()
|
||||
|
||||
// pass some options for the server middleware
|
||||
server.setLiveOptions(xtend(liveOpts))
|
||||
|
||||
// create a web socket server for live reload
|
||||
reloader = createReloadServer(server, opts)
|
||||
}
|
||||
return emitter
|
||||
}
|
||||
|
||||
function getHostAddress (host) {
|
||||
// user can specify "::" or "0.0.0.0" as host exactly
|
||||
// or if undefined, default to internal-ip
|
||||
if (!host) {
|
||||
host = server.address().address
|
||||
if (host === '0.0.0.0') {
|
||||
// node 0.10 returns this when no host is specified
|
||||
// node 0.12 returns internal-ip
|
||||
host = '::'
|
||||
}
|
||||
}
|
||||
if (host === '::') {
|
||||
host = internalIp()
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
function handlePorts (err, result) {
|
||||
if (closed) return
|
||||
if (err) {
|
||||
emitter.emit('error', err)
|
||||
return
|
||||
}
|
||||
|
||||
opts.port = result.port
|
||||
|
||||
// improve error messaging
|
||||
server.on('error', function (err) {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
err.message = 'port ' + opts.port + ' is in use'
|
||||
emitter.emit('error', err)
|
||||
} else {
|
||||
emitter.emit('error', err)
|
||||
}
|
||||
})
|
||||
|
||||
// start server
|
||||
// no host -> use localhost + internal-ip
|
||||
server.listen(opts.port, opts.host || undefined, connect)
|
||||
}
|
||||
|
||||
function connect () {
|
||||
if (closed) return
|
||||
started = true
|
||||
|
||||
// default host is internal IP
|
||||
opts.host = getHostAddress(opts.host)
|
||||
|
||||
var port = opts.port
|
||||
var protocol = opts.ssl ? 'https' : 'http'
|
||||
var uri = protocol + '://' + opts.host + ':' + port + '/'
|
||||
|
||||
log.info({ message: 'Server running at', url: uri, type: 'connect' })
|
||||
|
||||
// if live() or watch() was called before connection
|
||||
deferredWatch()
|
||||
deferredLive()
|
||||
|
||||
// provide info on server connection
|
||||
emitter.emit('connect', {
|
||||
uri: uri,
|
||||
port: port,
|
||||
host: opts.host,
|
||||
serve: opts.serve,
|
||||
entries: entryFiles,
|
||||
server: server,
|
||||
webSocketServer: reloader ? reloader.webSocketServer : undefined,
|
||||
dir: opts.dir
|
||||
})
|
||||
|
||||
// initial bundle should come after
|
||||
// connect event!
|
||||
if (bundler) bundler.bundle()
|
||||
|
||||
// launch browser
|
||||
if (opts.open) {
|
||||
openUrl(uri)
|
||||
}
|
||||
}
|
||||
|
||||
function close () {
|
||||
var next = emitter.emit.bind(emitter, 'exit')
|
||||
if (started) {
|
||||
server.once('close', next)
|
||||
} else {
|
||||
process.nextTick(next)
|
||||
}
|
||||
|
||||
if (started) bole.reset()
|
||||
if (started) server.close()
|
||||
if (reloader) reloader.close()
|
||||
if (bundler) bundler.close()
|
||||
if (fileWatcher) fileWatcher.close()
|
||||
closed = true
|
||||
started = false
|
||||
}
|
||||
}
|
||||
50
static/js/ketcher2/node_modules/budo/lib/bundler.js
generated
vendored
Normal file
50
static/js/ketcher2/node_modules/budo/lib/bundler.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
var xtend = require('xtend')
|
||||
var createMiddleware = require('watchify-middleware').emitter
|
||||
var fromArgs = require('browserify/bin/args')
|
||||
var browserify = require('browserify')
|
||||
var path = require('path')
|
||||
var defaultErrorHandler = require('./error-handler')
|
||||
|
||||
module.exports = createBundler
|
||||
function createBundler (files, opts) {
|
||||
var bOpts = xtend({
|
||||
cache: {},
|
||||
packageCache: {},
|
||||
debug: opts.debug
|
||||
}, opts.browserify)
|
||||
|
||||
var bundler
|
||||
var args = opts.browserifyArgs
|
||||
if (args && Array.isArray(args)) {
|
||||
// CLI args for browserify
|
||||
bundler = fromArgs(args, bOpts)
|
||||
} else {
|
||||
// just assume JS only options
|
||||
bundler = browserify(bOpts)
|
||||
}
|
||||
|
||||
files.forEach(function (file) {
|
||||
bundler.add(path.resolve(file))
|
||||
})
|
||||
|
||||
var errorHandler = opts.errorHandler
|
||||
if (typeof errorHandler !== 'function' && errorHandler !== false) {
|
||||
errorHandler = defaultErrorHandler
|
||||
}
|
||||
|
||||
var cwd = opts.cwd
|
||||
var rootDirName
|
||||
if (cwd) {
|
||||
cwd = path.normalize(cwd)
|
||||
rootDirName = path.basename(cwd) + path.sep
|
||||
}
|
||||
return createMiddleware(bundler, {
|
||||
delay: opts.delay || 0,
|
||||
initialBundle: false,
|
||||
errorHandler: typeof errorHandler === 'function'
|
||||
? function (err) { // pass along directories as well
|
||||
return errorHandler(err, cwd, rootDirName)
|
||||
}
|
||||
: errorHandler // pass undefined / false / etc
|
||||
})
|
||||
}
|
||||
241
static/js/ketcher2/node_modules/budo/lib/error-handler.js
generated
vendored
Normal file
241
static/js/ketcher2/node_modules/budo/lib/error-handler.js
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
var stripAnsi = require('strip-ansi')
|
||||
|
||||
module.exports = errorHandler
|
||||
module.exports.render = bundleError
|
||||
|
||||
function bundleError (message, cwd, rootDirName) {
|
||||
// Everything has to be contained inside this function
|
||||
// for it to get stringified correctly. i.e. no require()!
|
||||
console.error(message)
|
||||
|
||||
if (typeof document === 'undefined') {
|
||||
return
|
||||
} else if (!document.body) {
|
||||
document.addEventListener('DOMContentLoaded', createErrorBox)
|
||||
} else {
|
||||
createErrorBox()
|
||||
}
|
||||
|
||||
function createErrorBox () {
|
||||
var parsed = parseError(message)
|
||||
|
||||
var overlayBox = document.createElement('div')
|
||||
css(overlayBox, {
|
||||
position: 'fixed',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
zIndex: '100000000',
|
||||
top: '0',
|
||||
left: '0',
|
||||
padding: '20px',
|
||||
margin: '0px',
|
||||
'box-sizing': 'border-box',
|
||||
background: '#fff',
|
||||
display: 'block',
|
||||
'font-size': '14px',
|
||||
'font-weight': 'normal',
|
||||
'font-family': 'monospace'
|
||||
})
|
||||
|
||||
if (!parsed.format) {
|
||||
var pre = document.createElement('pre')
|
||||
pre.textContent = message
|
||||
css(pre, {
|
||||
'word-wrap': 'break-word',
|
||||
'white-space': 'pre-wrap',
|
||||
'box-sizing': 'border-box',
|
||||
margin: '0',
|
||||
color: '#ff0000'
|
||||
})
|
||||
overlayBox.appendChild(pre)
|
||||
} else {
|
||||
var commonElements = []
|
||||
|
||||
var messageDiv = document.createElement('div')
|
||||
commonElements.push(messageDiv)
|
||||
messageDiv.textContent = parsed.message
|
||||
overlayBox.appendChild(messageDiv)
|
||||
css(messageDiv, {
|
||||
color: '#ff2e2e',
|
||||
'font-size': '16px'
|
||||
})
|
||||
|
||||
var pathLocContainer = document.createElement('div')
|
||||
css(pathLocContainer, { 'padding-top': '10px' })
|
||||
|
||||
if (isFinite(parsed.line)) {
|
||||
var location = document.createElement('div')
|
||||
commonElements.push(location)
|
||||
var colStr = isFinite(parsed.column) ? (', column ' + parsed.column) : ''
|
||||
location.textContent = ('line ' + parsed.line + colStr).trim()
|
||||
css(location, {
|
||||
color: 'hsl(0, 0%, 50%)',
|
||||
'padding-bottom': '0px',
|
||||
'font-size': '12px',
|
||||
'font-weight': 'bold'
|
||||
})
|
||||
pathLocContainer.appendChild(location)
|
||||
}
|
||||
|
||||
var path = document.createElement('div')
|
||||
path.textContent = trimPath(parsed.path)
|
||||
commonElements.push(path)
|
||||
css(path, { 'font-style': 'italic' })
|
||||
pathLocContainer.appendChild(path)
|
||||
overlayBox.appendChild(pathLocContainer)
|
||||
|
||||
if (parsed.code) {
|
||||
var sourceContainer = document.createElement('div')
|
||||
var source = document.createElement('div')
|
||||
var hr = document.createElement('div')
|
||||
css(hr, {
|
||||
background: 'hsl(0, 0%, 90%)',
|
||||
width: '100%',
|
||||
height: '2px',
|
||||
padding: '0',
|
||||
'margin-bottom': '10px',
|
||||
'margin-top': '10px'
|
||||
})
|
||||
commonElements.push(source)
|
||||
source.textContent = parsed.code
|
||||
css(source, {
|
||||
color: 'black',
|
||||
'font-weight': 'bold',
|
||||
'font-size': '14px',
|
||||
'padding-left': '0px'
|
||||
})
|
||||
|
||||
sourceContainer.appendChild(hr)
|
||||
sourceContainer.appendChild(source)
|
||||
overlayBox.appendChild(sourceContainer)
|
||||
}
|
||||
|
||||
// apply common styles
|
||||
commonElements.forEach(function (e) {
|
||||
css(e, {
|
||||
'word-wrap': 'break-word',
|
||||
'white-space': 'pre-wrap',
|
||||
'box-sizing': 'border-box',
|
||||
display: 'block',
|
||||
margin: '0',
|
||||
'vertical-align': 'bottom'
|
||||
})
|
||||
})
|
||||
}
|
||||
document.body.appendChild(overlayBox)
|
||||
}
|
||||
|
||||
function trimPath (filePath) {
|
||||
if (filePath.indexOf(cwd) === 0) {
|
||||
filePath = rootDirName + filePath.substring(cwd.length + 1)
|
||||
}
|
||||
return filePath
|
||||
}
|
||||
|
||||
function css (element, style) {
|
||||
Object.keys(style).forEach(function (k) {
|
||||
element.style[k] = style[k]
|
||||
})
|
||||
}
|
||||
|
||||
// parse an error message into pieces
|
||||
function parseError (err) {
|
||||
var filePath, lineNum, splitLines
|
||||
var result = {}
|
||||
|
||||
// For root files that syntax-error doesn't pick up:
|
||||
var parseFilePrefix = 'Parsing file '
|
||||
if (err.indexOf(parseFilePrefix) === 0) {
|
||||
var pathWithErr = err.substring(parseFilePrefix.length)
|
||||
filePath = getFilePath(pathWithErr)
|
||||
if (!filePath) return result
|
||||
result.path = filePath
|
||||
var messageAndLine = pathWithErr.substring(filePath.length)
|
||||
lineNum = /\((\d+):(\d+)\)/.exec(messageAndLine)
|
||||
if (!lineNum) return result
|
||||
result.message = messageAndLine.substring(1, lineNum.index).trim()
|
||||
result.line = parseInt(lineNum[1], 10)
|
||||
result.column = parseInt(lineNum[2], 10)
|
||||
result.format = true
|
||||
return result
|
||||
}
|
||||
|
||||
// if module not found
|
||||
var cannotFindModule = /^Cannot find module '(.+)' from '(.+)'(?:$| while parsing file: (.*)$)/.exec(err.trim())
|
||||
if (cannotFindModule) {
|
||||
result.missingModule = cannotFindModule[1]
|
||||
result.path = cannotFindModule[3] || cannotFindModule[2]
|
||||
result.message = "Cannot find module '" + result.missingModule + "'"
|
||||
result.format = true
|
||||
return result
|
||||
}
|
||||
|
||||
// syntax-error returns the path and line number, also a \n at start
|
||||
err = err.trim()
|
||||
filePath = getFilePath(err)
|
||||
if (!filePath) return result
|
||||
result.path = filePath
|
||||
|
||||
var restOfMessage = err.substring(filePath.length)
|
||||
var parsedSyntaxError = /^:(\d+)/.exec(restOfMessage)
|
||||
if (parsedSyntaxError) { // this is a syntax-error
|
||||
lineNum = parseInt(parsedSyntaxError[1], 10)
|
||||
if (isFinite(lineNum)) result.line = lineNum
|
||||
splitLines = restOfMessage.split('\n')
|
||||
var code = splitLines.slice(1, splitLines.length - 1).join('\n')
|
||||
result.code = code
|
||||
result.message = splitLines[splitLines.length - 1]
|
||||
result.format = true
|
||||
return result
|
||||
}
|
||||
|
||||
// remove colon
|
||||
restOfMessage = restOfMessage.substring(1).trim()
|
||||
var whileParsing = 'while parsing file: '
|
||||
var whileParsingIdx = restOfMessage.indexOf(whileParsing)
|
||||
if (whileParsingIdx >= 0) {
|
||||
var beforeWhile = restOfMessage.substring(0, whileParsingIdx)
|
||||
lineNum = /\((\d+):(\d+)\)/.exec(beforeWhile.split('\n')[0])
|
||||
var messageStr = beforeWhile
|
||||
if (lineNum) {
|
||||
var line = parseInt(lineNum[1], 10)
|
||||
var col = parseInt(lineNum[2], 10)
|
||||
if (isFinite(line)) result.line = line
|
||||
if (isFinite(col)) result.column = col
|
||||
messageStr = messageStr.substring(0, lineNum.index)
|
||||
}
|
||||
result.message = messageStr.trim()
|
||||
splitLines = restOfMessage.split('\n')
|
||||
result.code = splitLines.slice(2).join('\n')
|
||||
result.format = true
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// get a file path from the error message
|
||||
function getFilePath (str) {
|
||||
var hasRoot = /^[a-z]:/i.exec(str)
|
||||
var colonLeftIndex = 0
|
||||
if (hasRoot) {
|
||||
colonLeftIndex = hasRoot[0].length
|
||||
}
|
||||
var pathEnd = str.split('\n')[0].indexOf(':', colonLeftIndex)
|
||||
if (pathEnd === -1) {
|
||||
// invalid string, return non-formattable result
|
||||
return null
|
||||
}
|
||||
return str.substring(0, pathEnd)
|
||||
}
|
||||
}
|
||||
|
||||
function errorHandler (err, cwd, rootDirName) {
|
||||
console.error('%s', err)
|
||||
var msgStr = stripAnsi(err.message)
|
||||
var params = [
|
||||
JSON.stringify(msgStr),
|
||||
JSON.stringify(cwd),
|
||||
JSON.stringify(rootDirName)
|
||||
].join(',')
|
||||
return ';(' + bundleError + ')(' + params + ');'
|
||||
}
|
||||
45
static/js/ketcher2/node_modules/budo/lib/file-watch.js
generated
vendored
Normal file
45
static/js/ketcher2/node_modules/budo/lib/file-watch.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// a thin wrapper around chokidar file watching HTML / CSS
|
||||
var watch = require('chokidar').watch
|
||||
var xtend = require('xtend')
|
||||
var Emitter = require('events/')
|
||||
|
||||
var ignores = [
|
||||
'node_modules/**', 'bower_components/**',
|
||||
'.git', '.hg', '.svn', '.DS_Store',
|
||||
'*.swp', 'thumbs.db', 'desktop.ini'
|
||||
]
|
||||
|
||||
module.exports = function (glob, opt) {
|
||||
opt = xtend({
|
||||
usePolling: opt && opt.poll,
|
||||
ignored: ignores,
|
||||
ignoreInitial: true
|
||||
}, opt)
|
||||
|
||||
var emitter = new Emitter()
|
||||
var closed = false
|
||||
var ready = false
|
||||
|
||||
var watcher = watch(glob, opt)
|
||||
watcher.on('add', onWatch.bind(null, 'add'))
|
||||
watcher.on('change', onWatch.bind(null, 'change'))
|
||||
|
||||
// chokidar@1.0.0-r6 only allows close after ready event
|
||||
watcher.once('ready', function () {
|
||||
ready = true
|
||||
if (closed) watcher.close()
|
||||
})
|
||||
|
||||
function onWatch (event, path) {
|
||||
emitter.emit('watch', event, path)
|
||||
}
|
||||
|
||||
emitter.close = function () {
|
||||
if (closed) return
|
||||
if (ready) watcher.close()
|
||||
closed = true
|
||||
}
|
||||
return emitter
|
||||
}
|
||||
|
||||
module.exports.ignores = ignores
|
||||
24
static/js/ketcher2/node_modules/budo/lib/get-ports.js
generated
vendored
Normal file
24
static/js/ketcher2/node_modules/budo/lib/get-ports.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
var xtend = require('xtend')
|
||||
var getPorts = require('get-ports')
|
||||
|
||||
module.exports = getServerPorts
|
||||
function getServerPorts (opt, cb) {
|
||||
opt = xtend({ port: 9966 }, opt)
|
||||
|
||||
// try to use exact port specified or the defaults
|
||||
if (!opt.portfind) {
|
||||
return process.nextTick(function () {
|
||||
cb(null, {
|
||||
port: opt.port
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// find available ports
|
||||
getPorts([ opt.port ], function (err, ports) {
|
||||
if (err) return cb(err)
|
||||
cb(null, {
|
||||
port: ports[0]
|
||||
})
|
||||
})
|
||||
}
|
||||
43
static/js/ketcher2/node_modules/budo/lib/map-entry.js
generated
vendored
Normal file
43
static/js/ketcher2/node_modules/budo/lib/map-entry.js
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
var path = require('path')
|
||||
var url = require('url')
|
||||
var resolve = require('resolve')
|
||||
|
||||
module.exports = mapEntry
|
||||
function mapEntry (file) {
|
||||
if (file === '.') {
|
||||
file = entry()
|
||||
}
|
||||
|
||||
var parts
|
||||
// absolute path with letter drive, eg C:/
|
||||
if (/^[A-Z]:[/\\]+/.test(file)) {
|
||||
parts = file.split(/:(?:(?=[^/\\]))/)
|
||||
} else {
|
||||
parts = file.split(':')
|
||||
}
|
||||
|
||||
var pathFrom, pathUrl
|
||||
|
||||
if (parts.length > 1 && parts[1].length > 0) {
|
||||
pathFrom = parts[0]
|
||||
pathUrl = parts[1]
|
||||
|
||||
if (pathFrom === '.') {
|
||||
pathFrom = entry()
|
||||
}
|
||||
} else {
|
||||
pathFrom = file
|
||||
pathUrl = url.parse(path.basename(pathFrom)).pathname
|
||||
}
|
||||
|
||||
return {
|
||||
url: pathUrl,
|
||||
from: pathFrom
|
||||
}
|
||||
}
|
||||
|
||||
function entry () {
|
||||
var cwd = process.cwd()
|
||||
var file = resolve.sync('.', { basedir: cwd })
|
||||
return file || 'index.js'
|
||||
}
|
||||
248
static/js/ketcher2/node_modules/budo/lib/middleware.js
generated
vendored
Normal file
248
static/js/ketcher2/node_modules/budo/lib/middleware.js
generated
vendored
Normal file
@ -0,0 +1,248 @@
|
||||
// TODO: Expose this like webpack-dev-server middleware
|
||||
var stacked = require('stacked')
|
||||
var serveStatic = require('serve-static')
|
||||
var defaultIndex = require('simple-html-index')
|
||||
var logger = require('./simple-http-logger')
|
||||
var urlLib = require('url')
|
||||
var xtend = require('xtend')
|
||||
var pushState = require('connect-pushstate')
|
||||
var liveReload = require('inject-lr-script')
|
||||
var urlTrim = require('url-trim')
|
||||
var escapeHtml = require('escape-html')
|
||||
|
||||
var fs = require('fs')
|
||||
var browserify = require('browserify')
|
||||
var path = require('path')
|
||||
var liveReloadClientFile = path.resolve(__dirname, 'reload', 'client.js')
|
||||
var bundledReloadClientFile = path.resolve(__dirname, '..', 'build', 'bundled-livereload-client.js')
|
||||
|
||||
module.exports = budoMiddleware
|
||||
function budoMiddleware (entryMiddleware, opts) {
|
||||
opts = opts || {}
|
||||
var staticPaths = [].concat(opts.dir).filter(Boolean)
|
||||
if (staticPaths.length === 0) {
|
||||
staticPaths = [ process.cwd() ]
|
||||
}
|
||||
|
||||
var entrySrc = opts.serve
|
||||
var live = opts.live
|
||||
var cors = opts.cors
|
||||
var handler = stacked()
|
||||
var middlewares = [].concat(opts.middleware).filter(Boolean)
|
||||
|
||||
// Everything is logged except favicon.ico
|
||||
var logHandler = logger({
|
||||
ignores: [ '/favicon.ico' ]
|
||||
})
|
||||
handler.use(function (req, res, next) {
|
||||
if (cors) {
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With')
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, PUT, POST')
|
||||
res.setHeader('Access-Control-Allow-Origin', '*')
|
||||
}
|
||||
logHandler(req, res, next)
|
||||
})
|
||||
|
||||
// User middleware(s) can override others
|
||||
middlewares.forEach(function (middleware) {
|
||||
if (typeof middleware !== 'function') {
|
||||
throw new Error('middleware options must be functions')
|
||||
}
|
||||
handler.use(function (req, res, next) {
|
||||
logHandler.type = 'middleware'
|
||||
middleware(req, res, next)
|
||||
})
|
||||
})
|
||||
|
||||
// Re-route for pushState support
|
||||
if (opts.pushstate) {
|
||||
if (typeof opts.pushstate === 'string') {
|
||||
throw new Error('--pushstate is a string, you shouold use subarg options instead')
|
||||
}
|
||||
var pushStateOpts = xtend(typeof opts.pushstate === 'boolean' ? {} : opts.pushstate)
|
||||
delete pushStateOpts._ // added by subarg
|
||||
handler.use(pushState(pushStateOpts))
|
||||
}
|
||||
|
||||
// Inject liveReload snippet on response
|
||||
var liveInjector = liveReload({
|
||||
local: true
|
||||
})
|
||||
// this is lazily set and cannot be changed dynamically
|
||||
var liveScriptUrl
|
||||
// By default, attempt to optimize the response
|
||||
var shouldUseBundledLiveReload = true
|
||||
// Cache the client by default to optimize the response
|
||||
var liveReloadClient
|
||||
handler.use(liveReloadHandler)
|
||||
|
||||
// Entry (watchify) middleware
|
||||
if (entryMiddleware) {
|
||||
var entryRoute = '/' + urlLib.parse(entrySrc).pathname
|
||||
handler.use(function (req, res, next) {
|
||||
if (urlTrim(req.url) === urlTrim(entryRoute)) {
|
||||
entryMiddleware(req, res, next)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Ignore favicon clutter
|
||||
handler.mount('/favicon.ico', favicon)
|
||||
|
||||
// If the user wishes to *always* serve
|
||||
// a generated index instead of a static one.
|
||||
if (opts.forceDefaultIndex) {
|
||||
handler.use(indexHandler)
|
||||
}
|
||||
|
||||
// Static assets (html/images/etc)
|
||||
staticPaths.forEach(function (rootFile) {
|
||||
var staticOpts = xtend({
|
||||
cacheControl: false
|
||||
}, opts.staticOptions)
|
||||
delete staticOpts._ // from subarg
|
||||
var staticHandler = serveStatic(rootFile, staticOpts)
|
||||
handler.use(function (req, res, next) {
|
||||
logHandler.type = 'static'
|
||||
staticHandler(req, res, next)
|
||||
})
|
||||
})
|
||||
|
||||
// Generates a default index.html
|
||||
// when none is found locally.
|
||||
handler.use(indexHandler)
|
||||
|
||||
// Handle errors
|
||||
handler.use(function (req, res) {
|
||||
res.statusCode = 404
|
||||
res.end('404 not found: ' + escapeHtml(req.url))
|
||||
})
|
||||
|
||||
// Allow live options to be changed at runtime
|
||||
handler.setLiveOptions = setLiveOptions
|
||||
return handler
|
||||
|
||||
function setLiveOptions (opts) {
|
||||
live = opts
|
||||
}
|
||||
|
||||
function favicon (req, res) {
|
||||
var maxAge = 345600 // 4 days
|
||||
res.setHeader('Cache-Control', 'public, max-age=' + Math.floor(maxAge / 1000))
|
||||
res.setHeader('Content-Type', 'image/x-icon')
|
||||
res.statusCode = 200
|
||||
res.end()
|
||||
}
|
||||
|
||||
function indexHandler (req, res, next) {
|
||||
if (urlLib.parse(req.url).pathname === '/' || /\/index.html?/i.test(req.url)) {
|
||||
// If we reach this, our response will be generated
|
||||
// (not static from local file system)
|
||||
logHandler.type = 'generated'
|
||||
res.setHeader('content-type', 'text/html')
|
||||
|
||||
var stream = opts.defaultIndex || defaultIndex
|
||||
stream({
|
||||
entry: entrySrc,
|
||||
title: opts.title,
|
||||
css: opts.css,
|
||||
base: opts.base === true ? '/' : (opts.base || null)
|
||||
}, req).pipe(res)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
function serveBundledLiveReload (res, successCallback) {
|
||||
if (liveReloadClient) {
|
||||
res.end(liveReloadClient)
|
||||
successCallback(true)
|
||||
} else {
|
||||
fs.readFile(bundledReloadClientFile, function (err, src) {
|
||||
if (err) {
|
||||
if (shouldUseBundledLiveReload) {
|
||||
console.error([
|
||||
'NOTE: The bundled LiveReload client could not be found, so budo will',
|
||||
'generate this on the fly.',
|
||||
'This is most likely because you are using a git cloned version of budo',
|
||||
'instead of installing it from npm.',
|
||||
'You can run this from your cloned budo folder to create a build:',
|
||||
' npm run bundle-live-client'
|
||||
].join('\n'))
|
||||
}
|
||||
shouldUseBundledLiveReload = false
|
||||
successCallback(false)
|
||||
} else {
|
||||
liveReloadClient = src
|
||||
res.end(src)
|
||||
successCallback(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function serveBrowserifyLiveReload (cache, debug, liveScripts, res) {
|
||||
// Browserify the client file, e.g. if user has a script to include
|
||||
if (cache && liveReloadClient) {
|
||||
res.end(liveReloadClient)
|
||||
} else {
|
||||
var b = browserify({ debug: debug })
|
||||
b.add(liveReloadClientFile)
|
||||
if (live.expose) {
|
||||
b.require(liveReloadClientFile, { expose: 'budo-livereload' })
|
||||
}
|
||||
|
||||
liveScripts.forEach(function (file) {
|
||||
b.add(path.resolve(file))
|
||||
})
|
||||
b.bundle(function (err, src) {
|
||||
if (err) {
|
||||
console.error('Error bundling LiveReload client:\n' + err.message)
|
||||
res.statusCode = 500
|
||||
res.end('Error bundling LiveReload client: ' + err)
|
||||
} else {
|
||||
liveReloadClient = src
|
||||
res.end(src)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function liveReloadHandler (req, res, next) {
|
||||
if (!live || live.plugin) return next()
|
||||
if (!liveScriptUrl) {
|
||||
liveScriptUrl = live.path || '/budo/livereload.js'
|
||||
logHandler.ignores.push(liveScriptUrl)
|
||||
} else if (liveScriptUrl && live.path && liveScriptUrl !== live.path) {
|
||||
var errMessage = 'Error: The LiveReload path field cannot be changed dynamically.\n' +
|
||||
'Please open an issue in budo if you have a specific use case for this.'
|
||||
console.error(errMessage)
|
||||
res.statusCode = 500
|
||||
res.end(errMessage)
|
||||
return
|
||||
}
|
||||
|
||||
if (req.url === liveScriptUrl) {
|
||||
res.statusCode = 200
|
||||
res.setHeader('Content-Type', 'application/javascript')
|
||||
var liveScripts = (Array.isArray(live.include) ? live.include : [ live.include ]).filter(Boolean)
|
||||
var cache = live.cache !== false
|
||||
var debug = live.debug
|
||||
|
||||
// Default setup - use a bundled JS file for LiveReload client
|
||||
if (shouldUseBundledLiveReload && cache && !debug && liveScripts.length === 0) {
|
||||
serveBundledLiveReload(res, function (success) {
|
||||
// fall back to browserify on the fly
|
||||
if (!success) serveBrowserifyLiveReload(cache, debug, liveScripts, res)
|
||||
})
|
||||
} else {
|
||||
serveBrowserifyLiveReload(cache, debug, liveScripts, res)
|
||||
}
|
||||
} else {
|
||||
liveInjector.path = liveScriptUrl
|
||||
liveInjector(req, res, next)
|
||||
}
|
||||
}
|
||||
}
|
||||
70
static/js/ketcher2/node_modules/budo/lib/parse-args.js
generated
vendored
Normal file
70
static/js/ketcher2/node_modules/budo/lib/parse-args.js
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
var subarg = require('subarg')
|
||||
var xtend = require('xtend')
|
||||
|
||||
module.exports = parseArgs
|
||||
function parseArgs (args, opt) {
|
||||
// before parsing subarg, remove the bundler arguments
|
||||
var bundlerFlags = []
|
||||
var stopIndex = args.indexOf('--')
|
||||
if (stopIndex >= 0) {
|
||||
bundlerFlags = args.slice(stopIndex + 1)
|
||||
args = args.slice(0, stopIndex)
|
||||
}
|
||||
var argv = subarg(args, {
|
||||
boolean: [
|
||||
'stream',
|
||||
'debug',
|
||||
'errorHandler',
|
||||
'forceDefaultIndex',
|
||||
'open',
|
||||
'portfind',
|
||||
'ndjson',
|
||||
'verbose',
|
||||
'cors',
|
||||
'ssl'
|
||||
],
|
||||
string: [
|
||||
'host',
|
||||
'port',
|
||||
'dir',
|
||||
'onupdate',
|
||||
'serve',
|
||||
'title',
|
||||
'watchGlob',
|
||||
'cert',
|
||||
'key'
|
||||
],
|
||||
default: module.exports.defaults,
|
||||
alias: {
|
||||
port: 'p',
|
||||
ssl: 'S',
|
||||
serve: 's',
|
||||
cert: 'C',
|
||||
key: 'K',
|
||||
verbose: 'v',
|
||||
help: 'h',
|
||||
host: 'H',
|
||||
dir: 'd',
|
||||
live: 'l',
|
||||
open: 'o',
|
||||
staticOptions: [ 'static-options' ],
|
||||
watchGlob: [ 'wg', 'watch-glob' ],
|
||||
errorHandler: 'error-handler',
|
||||
forceDefaultIndex: 'force-default-index',
|
||||
pushstate: 'P'
|
||||
},
|
||||
'--': true
|
||||
})
|
||||
// add back in the bundler flags
|
||||
argv['--'] = bundlerFlags
|
||||
return xtend(argv, opt)
|
||||
}
|
||||
|
||||
module.exports.defaults = {
|
||||
title: 'budo',
|
||||
port: 9966,
|
||||
debug: true,
|
||||
stream: true,
|
||||
errorHandler: true,
|
||||
portfind: true
|
||||
}
|
||||
134
static/js/ketcher2/node_modules/budo/lib/reload/client.js
generated
vendored
Normal file
134
static/js/ketcher2/node_modules/budo/lib/reload/client.js
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
var reloadCSS = require('reload-css')
|
||||
module.exports = connect()
|
||||
|
||||
function connect () {
|
||||
var reconnectPoll = 1000
|
||||
var maxRetries = 50
|
||||
var retries = 0
|
||||
var reconnectInterval
|
||||
var isReconnecting = false
|
||||
var protocol = document.location.protocol
|
||||
var hostname = document.location.hostname
|
||||
var port = document.location.port
|
||||
var host = hostname + ':' + port
|
||||
|
||||
var isIOS = /(iOS|iPhone|iPad|iPod)/i.test(navigator.userAgent)
|
||||
var isSSL = /^https:/i.test(protocol)
|
||||
var queued = []
|
||||
var socket = createWebSocket()
|
||||
var listeners = []
|
||||
|
||||
var api = {
|
||||
send: function (message) {
|
||||
message = JSON.stringify(message)
|
||||
if (socket && socket.readyState === 1) {
|
||||
socket.send(message)
|
||||
} else {
|
||||
queued.push(message)
|
||||
}
|
||||
},
|
||||
listen: function (cb) {
|
||||
if (typeof cb !== 'function') {
|
||||
throw new TypeError('cb must be a function!')
|
||||
}
|
||||
listeners.push(cb)
|
||||
},
|
||||
reloadPage: reloadPage,
|
||||
reloadCSS: reloadCSS
|
||||
}
|
||||
|
||||
return api
|
||||
|
||||
function scheduleReconnect () {
|
||||
if (isIOS && isSSL) {
|
||||
// Special case for iOS with a self-signed certificate.
|
||||
console.warn('[budo] LiveReload disconnected. You may need to generate and ' +
|
||||
'trust a self-signed certificate, see here:\n' +
|
||||
'https://github.com/mattdesl/budo/blob/master/docs/' +
|
||||
'command-line-usage.md#ssl-on-ios')
|
||||
return
|
||||
}
|
||||
if (isSSL) {
|
||||
// Don't attempt to re-connect in SSL since it will likely be insecure
|
||||
console.warn('[budo] LiveReload disconnected. Please reload the page to retry.')
|
||||
return
|
||||
}
|
||||
if (retries >= maxRetries) {
|
||||
console.warn('[budo] LiveReload disconnected, exceeded retry count. Please reload the page to retry.')
|
||||
return
|
||||
}
|
||||
if (!isReconnecting) {
|
||||
isReconnecting = true
|
||||
console.warn('[budo] LiveReload disconnected, retrying...')
|
||||
}
|
||||
retries++
|
||||
clearTimeout(reconnectInterval)
|
||||
reconnectInterval = setTimeout(reconnect, reconnectPoll)
|
||||
}
|
||||
|
||||
function reconnect () {
|
||||
if (socket) {
|
||||
// force close the existing socket
|
||||
socket.onclose = function () {}
|
||||
socket.close()
|
||||
}
|
||||
socket = createWebSocket()
|
||||
}
|
||||
|
||||
function createWebSocket () {
|
||||
var wsProtocol = isSSL ? 'wss://' : 'ws://'
|
||||
var wsUrl = wsProtocol + host + '/livereload'
|
||||
var ws = new window.WebSocket(wsUrl)
|
||||
ws.onmessage = function (event) {
|
||||
var data
|
||||
try {
|
||||
data = JSON.parse(event.data)
|
||||
} catch (err) {
|
||||
console.warn('Error parsing LiveReload server data: ' + event.data)
|
||||
return
|
||||
}
|
||||
|
||||
if (data.event === 'reload') {
|
||||
if (/^\.?css$/i.test(data.ext)) {
|
||||
reloadCSS(data.url)
|
||||
} else {
|
||||
reloadPage()
|
||||
}
|
||||
}
|
||||
|
||||
// let listeners receive data
|
||||
listeners.forEach(function (listener) {
|
||||
listener(data)
|
||||
})
|
||||
}
|
||||
ws.onclose = function (ev) {
|
||||
if (ev.code === 1000 || ev.code === 1001) {
|
||||
// Browser is navigating away.
|
||||
return
|
||||
}
|
||||
scheduleReconnect()
|
||||
}
|
||||
ws.onopen = function () {
|
||||
if (isReconnecting) {
|
||||
isReconnecting = false
|
||||
retries = 0
|
||||
console.warn('[budo] LiveReload reconnected.')
|
||||
}
|
||||
if (queued.length && ws.readyState === 1) {
|
||||
queued.forEach(function (message) {
|
||||
ws.send(message)
|
||||
})
|
||||
queued.length = 0
|
||||
}
|
||||
}
|
||||
ws.onerror = function () {
|
||||
return false
|
||||
}
|
||||
return ws
|
||||
}
|
||||
}
|
||||
|
||||
function reloadPage () {
|
||||
window.location.reload(true)
|
||||
}
|
||||
|
||||
78
static/js/ketcher2/node_modules/budo/lib/reload/server.js
generated
vendored
Normal file
78
static/js/ketcher2/node_modules/budo/lib/reload/server.js
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
var WebSocketServer = require('ws').Server
|
||||
var log = require('bole')('budo')
|
||||
var path = require('path')
|
||||
var isAbsolute = require('path-is-absolute')
|
||||
var color = require('term-color')
|
||||
|
||||
module.exports = function (server, opts) {
|
||||
opts = opts || {}
|
||||
log.info({ message: 'LiveReload running' })
|
||||
|
||||
// get a list of static folders to use as base dirs
|
||||
var cwd = path.resolve(opts.cwd || process.cwd())
|
||||
var staticDirs = Array.isArray(opts.dir) ? opts.dir : [ opts.dir ]
|
||||
staticDirs = staticDirs.map(function (dir) {
|
||||
return path.resolve(dir)
|
||||
})
|
||||
if (staticDirs.indexOf(cwd) === -1) staticDirs.push(cwd)
|
||||
|
||||
var closed = false
|
||||
var wss = new WebSocketServer({
|
||||
server: server,
|
||||
perMessageDeflate: false
|
||||
})
|
||||
|
||||
return {
|
||||
webSocketServer: wss,
|
||||
reload: reload,
|
||||
close: function () {
|
||||
if (closed) return
|
||||
wss.close()
|
||||
closed = true
|
||||
}
|
||||
}
|
||||
|
||||
function reload (file) {
|
||||
if (closed) return
|
||||
var url, ext
|
||||
|
||||
if (file && typeof file === 'string') {
|
||||
// absolute file path
|
||||
file = isAbsolute(file) ? path.normalize(file) : path.resolve(cwd, file)
|
||||
|
||||
// make it relative, removing the static folder parts
|
||||
for (var i = 0; i < staticDirs.length; i++) {
|
||||
var dir = staticDirs[i]
|
||||
url = path.relative(dir, file)
|
||||
// if the path doesn't starts with "../", then
|
||||
// it should be relative to this folder
|
||||
if (!/^(\.\.[/\\]|[/\\])/.test(url)) break
|
||||
}
|
||||
|
||||
// turn it into a URL
|
||||
url = url.replace(/\\/g, '/')
|
||||
|
||||
// ensure it starts at root of app
|
||||
if (url.charAt(0) !== '/') url = '/' + url
|
||||
|
||||
ext = path.extname(file)
|
||||
}
|
||||
|
||||
broadcast({ event: 'reload', ext: ext, url: url })
|
||||
}
|
||||
|
||||
function broadcast (data) {
|
||||
if (closed) return
|
||||
data = JSON.stringify(data)
|
||||
try {
|
||||
wss.clients.forEach(function (client) {
|
||||
client.send(data, {
|
||||
binary: false
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(color.red('ERROR'), 'Error sending LiveReload event to client:')
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
49
static/js/ketcher2/node_modules/budo/lib/server.js
generated
vendored
Normal file
49
static/js/ketcher2/node_modules/budo/lib/server.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
var http = require('http')
|
||||
var https = require('https')
|
||||
var pem = require('pem')
|
||||
var createMiddleware = require('./middleware')
|
||||
var fs = require('fs')
|
||||
|
||||
module.exports = function createServer (entryMiddleware, opts, cb) {
|
||||
var handler = createMiddleware(entryMiddleware, opts)
|
||||
var ssl = opts.ssl
|
||||
|
||||
if (ssl && (!opts.cert && opts.key) || (!opts.key && opts.cert)) {
|
||||
throw new TypeError('If you specify a cert, you must specify a key and vice versa.\n' +
|
||||
'Or, you can omit the "cert" and "key" options to generate a new self-signed certificate.')
|
||||
}
|
||||
|
||||
if (opts.ssl) {
|
||||
if (opts.cert && opts.key) {
|
||||
// user specified their own cert/key pair
|
||||
create({
|
||||
cert: fs.readFileSync(opts.cert),
|
||||
key: fs.readFileSync(opts.key)
|
||||
})
|
||||
} else {
|
||||
// generate a self-signed cert
|
||||
pem.createCertificate({ days: 1, selfSigned: true }, function (err, keys) {
|
||||
if (err) return cb(err)
|
||||
create({
|
||||
key: keys.serviceKey,
|
||||
cert: keys.certificate
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// no HTTPS, handle normally
|
||||
create()
|
||||
}
|
||||
|
||||
function create (httpsOpts) {
|
||||
var server = ssl
|
||||
? https.createServer(httpsOpts, handler)
|
||||
: http.createServer(handler)
|
||||
server.setLiveOptions = handler.setLiveOptions
|
||||
|
||||
// TODO: Perhaps --ssl should support some sort of HTTP -> HTTPS redirect
|
||||
process.nextTick(function () {
|
||||
cb(null, server)
|
||||
})
|
||||
}
|
||||
}
|
||||
75
static/js/ketcher2/node_modules/budo/lib/simple-http-logger.js
generated
vendored
Normal file
75
static/js/ketcher2/node_modules/budo/lib/simple-http-logger.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
var log = require('bole')('budo')
|
||||
var onResHeaders = require('on-headers')
|
||||
var onResFinished = require('on-finished')
|
||||
|
||||
module.exports = simpleHttpLoggerMiddleware
|
||||
function simpleHttpLoggerMiddleware (opts) {
|
||||
opts = opts || {}
|
||||
|
||||
var httpLogger = function simpleHttpLogger (req, res, next) {
|
||||
if (httpLogger.ignores.indexOf(req.url) >= 0) return next()
|
||||
if (!req.url) return next()
|
||||
|
||||
// request data
|
||||
req._startAt = undefined
|
||||
|
||||
// response data
|
||||
res._startAt = undefined
|
||||
|
||||
// record request start
|
||||
recordStartTime.call(req)
|
||||
|
||||
var byteLength = 0
|
||||
var logRequest = function () {
|
||||
if (!req._startAt || !res._startAt) {
|
||||
// missing request and/or response start time
|
||||
return
|
||||
}
|
||||
|
||||
// calculate diff
|
||||
var ms = (res._startAt[0] - req._startAt[0]) * 1000 +
|
||||
(res._startAt[1] - req._startAt[1]) * 1e-6
|
||||
|
||||
log.info({
|
||||
elapsed: ms,
|
||||
contentLength: byteLength,
|
||||
method: (req.method || 'GET').toUpperCase(),
|
||||
url: req.url,
|
||||
statusCode: res.statusCode,
|
||||
type: httpLogger.type === 'static' ? undefined : httpLogger.type,
|
||||
colors: {
|
||||
elapsed: ms > 1000 ? 'yellow' : 'dim'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var isAlreadyLogging = res._simpleHttpLogger
|
||||
res._simpleHttpLogger = true
|
||||
|
||||
if (!isAlreadyLogging) {
|
||||
// record response start
|
||||
onResHeaders(res, recordStartTime)
|
||||
|
||||
// log when response finished
|
||||
onResFinished(res, logRequest)
|
||||
|
||||
var writeFn = res.write
|
||||
|
||||
// catch content-length of payload
|
||||
res.write = function (payload) {
|
||||
if (payload) byteLength += payload.length
|
||||
return writeFn.apply(res, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
httpLogger.ignores = [].concat(opts.ignores).filter(Boolean)
|
||||
httpLogger.type = 'static'
|
||||
return httpLogger
|
||||
}
|
||||
|
||||
function recordStartTime () {
|
||||
this._startAt = process.hrtime()
|
||||
}
|
||||
Reference in New Issue
Block a user