UNPKG

oj

Version:

A unified templating language for the people. Thirsty people.

1,499 lines (1,335 loc) 46.3 kB
// Generated by CoffeeScript 1.6.2 (function() { var basenameForExtensions, coffee, commonPath, compileDir, compileFile, compileJS, compilePath, csso, error, fileIsOutdated, findFile, fullPaths, isAppModule, isDirectory, isFile, isHiddenFile, isNodeModule, isOJDir, isOJFile, isOJPage, isRelativeModule, isUnsupportedNodeModule, isWatchFile, isWatched, jsdom, ls, lsOJ, lsWatch, m, mkdirp, nodeModulePaths, nodeModulesLinkMap, oj, pass, readFileSync, relativePathWithEscaping, resolveLink, spaces, stripBOM, success, tabs, triggerWatched, trimArgList, uglifyjs, unwatchAll, unwatchDir, url, verbose, verbosity, wait, watchCache, watchDir, watchFile, watchParents, wrapCSMessage, wrapJS, wrapJSMessage, _, _buildFileCache, _buildNativeCache, _buildNativeCacheFromModuleList, _buildRequireCache, _clearRequireCacheRecord, _createHook, _escapeSingleQuotes, _first, _getRequiresInSource, _hookRequire, _i, _insertAt, _len, _length, _nativeModuleCode, _nodeModuleUnsupported, _nodeModulesSupported, _ojModuleCode, _optionsForPath, _outputCombinedHtml, _outputCss, _outputDataToFileOrCallback, _outputFile, _outputHtml, _outputJs, _ref, _rememberModule, _rememberModuleDependencies, _requireCache, _requireCacheToHtml, _requireCacheToJS, _restoreRequireCache, _saveRequireCache, _startsWith, _timeStampFromStartTime, _trim, _unhookRequire; _ref = ['path', 'fs', 'vm']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { m = _ref[_i]; global[m] = require(m); } _ = require('underscore'); coffee = require('coffee-script'); url = require('url'); mkdirp = require('mkdirp'); csso = require('csso'); uglifyjs = require('uglify-js'); jsdom = (require('jsdom')).jsdom; global.jQuery = global.$ = require('jquery'); global.document = jsdom("<html><head></head><body></body></html>"); global.window = document.createWindow(); oj = require('../oj'); oj.isClient = false; module.exports = oj; oj.$ = global.$; oj.codes = { reset: '\u001b[0m', black: '\u001b[30m', red: '\u001b[31m', green: '\u001b[32m', yellow: '\u001b[33m', blue: '\u001b[34m', magenta: '\u001b[35m', cyan: '\u001b[36m', gray: '\u001b[37m' }; if (require.extensions) { coffee = require('coffee-script'); stripBOM = function(c) { if (c.charCodeAt(0) === 0xFEFF) { return c.slice(1); } else { return c; } }; wrapJS = function(code) { return "(function(){with(oj.sandbox){" + code + "}}).call(this);"; }; wrapCSMessage = function(message, filepath) { var _ref1, _ref2; return "" + ((_ref1 = oj.codes) != null ? _ref1.red : void 0) + "coffee-script error in " + filepath + ": " + message + ((_ref2 = oj.codes) != null ? _ref2.reset : void 0); }; wrapJSMessage = function(message, filepath) { var _ref1, _ref2; return "" + ((_ref1 = oj.codes) != null ? _ref1.red : void 0) + "javascript error in " + filepath + ": " + message + ((_ref2 = oj.codes) != null ? _ref2.reset : void 0); }; compileJS = function(module, code, filepath) { code = wrapJS(code); global.oj = oj; module._compile(code, filepath); return delete global.oj; }; require.extensions['.oj'] = function(module, filepath) { var code, eJS; code = stripBOM(fs.readFileSync(filepath, 'utf8')); try { return compileJS(module, code, filepath); } catch (_error) { eJS = _error; eJS.message = wrapJSMessage(eJS.message, filepath); throw eJS; } }; require.extensions['.ojc'] = function(module, filepath) { var code, eCoffee, eJS; code = stripBOM(fs.readFileSync(filepath, 'utf8')); try { code = coffee.compile(code, { bare: true }); } catch (_error) { eCoffee = _error; eCoffee.message = wrapCSMessage(eCoffee.message, filepath); throw eCoffee; } try { return compileJS(module, code, filepath); } catch (_error) { eJS = _error; eJS.message = wrapJSMessage(eJS.message, filepath); throw eJS; } }; } oj.watch = function(filesOrDirectories, options) { options = _.extend({}, options, { args: filesOrDirectories, watch: true, write: true }); return oj.command(options); }; oj.build = function(filesOrDirectories, options) { options = _.extend({}, options, { args: filesOrDirectories, watch: false, write: true }); return oj.command(options); }; verbosity = null; oj.command = function(options) { var fullPath, _j, _len1, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; if (options == null) { options = {}; } verbosity = options.verbose || 1; if ((_ref1 = options.test) == null) { options.test = false; } if ((_ref2 = options.write) == null) { options.write = !options.test; } if ((_ref3 = options.watch) == null) { options.watch = false; } if ((_ref4 = options.all) == null) { options.all = false; } if ((_ref5 = options.recurse) == null) { options.recurse = true; } if ((_ref6 = options.include) == null) { options.include = []; } if ((_ref7 = options.exclude) == null) { options.exclude = []; } if ((_ref8 = options.output) == null) { options.output = './public'; } options.output = (path.resolve(process.cwd(), options.output)) + '/'; if (!((_.isArray(options.args)) && options.args.length > 0)) { throw new Error('oj: no args found'); } options.args = fullPaths(options.args, process.cwd()); _ref9 = options.args; for (_j = 0, _len1 = _ref9.length; _j < _len1; _j++) { fullPath = _ref9[_j]; compilePath(fullPath, _optionsForPath(fullPath, options), function(err, results) { if (options.test) { return console.log(results); } }); } }; _optionsForPath = function(fullPath, options) { var userSpecifiedInclude; options = _.clone(options); userSpecifiedInclude = (options.modules != null) || (options.html != null) || (options.css != null) || (options.js != null); if (options.modulesDir) { options.modulesDir = (path.resolve(fullPath, options.modulesDir)) + '/'; } if (options.cssDir) { options.cssDir = (path.resolve(fullPath, options.cssDir)) + '/'; } if (!userSpecifiedInclude && fs.existsSync(options.modulesDir)) { options.modules = false; options.js = options.css = options.html = true; } else if (options.all || !userSpecifiedInclude) { options.modules = options.js = options.css = options.html = true; } return options; }; compilePath = function(fullPath, options, cb) { var includeDir; if (options == null) { options = {}; } if (cb == null) { cb = function() {}; } if (isDirectory(fullPath)) { return compileDir(fullPath, options, cb); } includeDir = path.dirname(fullPath); return compileFile(fullPath, includeDir, options, cb); }; compileDir = function(dirPath, options, cb) { var _ref1; if (options == null) { options = {}; } if (cb == null) { cb = function() {}; } options = _.clone(options); if (!options.modulesDir) { options.modulesDir = (path.resolve(dirPath, (_ref1 = options.modulesDir) != null ? _ref1 : './modules')) + '/'; } lsWatch(dirPath, options, function(err, files, dirs) { var d, f, _cb, _j, _k, _len1, _len2; if (options.watch) { for (_j = 0, _len1 = dirs.length; _j < _len1; _j++) { d = dirs[_j]; watchDir(d, dirPath, options); } } _cb = _.after(files.length, cb); for (_k = 0, _len2 = files.length; _k < _len2; _k++) { f = files[_k]; if (isOJPage(f)) { compileFile(f, dirPath, options, _cb); } else if (options.watch) { watchFile(f, dirPath, options); _cb(); } } }); }; nodeModulePaths = function(from) { var dir, joiner, parts, paths, splitRe, tip, _j, _ref1; from = path.resolve(from); splitRe = (process.platform === 'win32' ? /[\/\\]/ : /\//); joiner = (process.platform === 'win32' ? '\\' : '/'); paths = []; parts = from.split(splitRe); for (tip = _j = _ref1 = parts.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; tip = _ref1 <= 0 ? ++_j : --_j) { if (parts[tip] === 'node_modules') { continue; } dir = parts.slice(0, tip + 1).concat('node_modules').join(joiner); paths.push(dir); } return paths; }; resolveLink = function(linkPath, out) { var e, newPath; try { newPath = fs.readlinkSync(linkPath); return resolveLink(newPath, newPath); } catch (_error) { e = _error; } return out; }; nodeModulesLinkMap = function(fileDir) { var dir, dirs, e, linkPath, moduleName, modulePath, modules, out, _j, _k, _len1, _len2; dirs = nodeModulePaths(fileDir); out = {}; for (_j = 0, _len1 = dirs.length; _j < _len1; _j++) { dir = dirs[_j]; try { modules = fs.readdirSync(dir); for (_k = 0, _len2 = modules.length; _k < _len2; _k++) { moduleName = modules[_k]; modulePath = path.join(dir, moduleName); linkPath = resolveLink(modulePath); if (linkPath != null) { out[linkPath + '/'] = modulePath + '/'; } } } catch (_error) { e = _error; } } return out; }; basenameForExtensions = function(p, arrayOfExt) { var ext, out, _j, _len1; if (arrayOfExt == null) { arrayOfExt = []; } out = path.basename(p); for (_j = 0, _len1 = arrayOfExt.length; _j < _len1; _j++) { ext = arrayOfExt[_j]; out = path.basename(out, ext); } return out; }; compileFile = function(filePath, includeDir, options, cb) { var cache, compileOptions, cssOption, eCompile, eRequire, ex, extOut, fileBaseName, fileDir, fileOut, hookCache, hookOriginalCache, htmlOption, includedModules, isMinify, moduleLinkMap, moduleParents, modules, ojml, outputDir, results, rootDir, startTime, subDir, _j, _k, _len1, _len2, _ref1, _ref2, _ref3; if (options == null) { options = {}; } if (cb == null) { cb = function() {}; } options = _.clone(options); startTime = process.hrtime(); _clearRequireCacheRecord('underscore'); if ((_ref1 = options.exclude) == null) { options.exclude = []; } if (!isFile(filePath)) { throw new Error('oj: file not found'); } isMinify = (_ref2 = options.minify) != null ? _ref2 : false; includedModules = options.include || []; includedModules = includedModules.concat(['oj', 'jquery']); rootDir = options.root || path.dirname(filePath); fileDir = path.dirname(filePath); if (options.modulesDir && _startsWith(filePath, options.modulesDir)) { options.modules = true; options.css = false; options.html = false; options.js = false; } else if (options.cssDir && _startsWith(filePath, options.cssDir)) { options.modules = false; options.css = true; options.html = false; options.js = false; } if (!isDirectory(rootDir)) { throw new Error('oj: root is not a directory'); } if (options.watch) { watchFile(filePath, includeDir, options); } verbose(2, "compiling " + filePath); cache = { modules: {}, files: {}, "native": {} }; moduleLinkMap = nodeModulesLinkMap(fileDir); modules = {}; moduleParents = {}; hookCache = {}; hookOriginalCache = {}; _hookRequire(modules, moduleLinkMap, hookCache, hookOriginalCache); _saveRequireCache(); if (_.isArray(options.exclude)) { _ref3 = options.exclude; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { ex = _ref3[_j]; verbose(3, "excluding " + ex); } includedModules = _.difference(includedModules, options.exclude); } try { for (_k = 0, _len2 = includedModules.length; _k < _len2; _k++) { m = includedModules[_k]; if (isNodeModule(m)) { _buildNativeCacheFromModuleList(cache["native"], [m], isMinify); } else { verbose(3, "including " + m); require(m); } } ojml = require(filePath); } catch (_error) { eRequire = _error; verbose(1, eRequire.message); _restoreRequireCache(); _unhookRequire(modules, hookCache, hookOriginalCache); return; } _restoreRequireCache(); _unhookRequire(modules, hookCache, hookOriginalCache); _rememberModuleDependencies(modules); cssOption = !!options.css; htmlOption = !!options.html; compileOptions = { minify: isMinify, html: htmlOption, cssMap: cssOption, css: cssOption, dom: false, data: options.data }; try { results = oj.compile(compileOptions, ojml); } catch (_error) { eCompile = _error; error("runtime error in " + filePath + ": " + eCompile.message); return; } verbose(3, "caching " + filePath + " (" + (_length(modules)) + " files)"); cache = _buildRequireCache(modules, cache, isMinify); fileBaseName = basenameForExtensions(filePath, ['.oj', '.ojc', 'ojlc']); outputDir = options.output || process.cwd(); fileDir = path.dirname(filePath); subDir = path.relative(includeDir, fileDir); extOut = '.html'; if (options.css && !(options.html || options.js || options.modules)) { extOut = '.css'; } else if ((options.js || options.modules) && !(options.html || options.css)) { extOut = '.js'; } fileOut = path.join(outputDir, subDir, fileBaseName + extOut); options.info = _.extend({}, { includeDir: includeDir, startTime: startTime, results: results, cache: cache, filePath: filePath, fileDir: fileDir, fileBaseName: fileBaseName, outputDir: outputDir, subDir: subDir, extOut: extOut, fileOut: fileOut, isMinify: isMinify }); _outputFile(options, cb); }; _outputFile = function(options, cb) { if (options.html && !(options.css || options.js || options.modules)) { return _outputHtml(options, cb); } else if (options.css && !(options.html || options.js || options.modules)) { return _outputCss(options, cb); } else if ((options.js || options.modules) && !(options.html || options.css)) { return _outputJs(options, cb); } else { return _outputCombinedHtml(options, cb); } }; _outputCombinedHtml = function(options, cb) { var cache, cacheLength, cssMap, fileOut, filePath, html, info, mediaMap, plugin, results, scriptHtml, scriptIndex, styleHTML, styleIndex, _ref1, _ref2; info = options.info; results = info.results; filePath = info.filePath; fileOut = info.fileOut; html = results.html; cssMap = results.cssMap; cache = info.cache; cacheLength = _length(cache.files) + _length(cache.modules) + _length(cache["native"]); verbose(3, "serializing " + filePath + " (" + cacheLength + " files)"); scriptHtml = _requireCacheToHtml(cache, filePath, (_ref1 = options.minify) != null ? _ref1 : false, options); if (!results.tags.html) { error("validation error " + filePath + ": <html> tag is missing"); return; } else if (!results.tags.head) { error("validation error " + filePath + ": <head> tag is missing"); return; } else if (!results.tags.body) { error("validation error " + filePath + ": <body> tag is missing"); return; } scriptIndex = html.lastIndexOf('</body>'); html = _insertAt(html, scriptIndex, scriptHtml); styleIndex = html.indexOf('</head>'); styleHTML = ''; _ref2 = results.cssMap; for (plugin in _ref2) { mediaMap = _ref2[plugin]; styleHTML += oj._styleTagFromMediaObject(plugin, mediaMap, options); } html = _insertAt(html, styleIndex, styleHTML); return _outputDataToFileOrCallback(html, options, cb); }; _outputCss = function(options, cb) { return _outputDataToFileOrCallback(options.info.results.css, options, cb); }; _outputHtml = function(options, cb) { return _outputDataToFileOrCallback(options.info.results.html, options, cb); }; _outputJs = function(options, cb) { var info, js; info = options.info; js = _requireCacheToJS(info.cache, info.filePath, info.isMinify, options); return _outputDataToFileOrCallback(js, options, cb); }; _outputDataToFileOrCallback = function(data, options, cb) { var dirOut, fileOut, filePath, info, timeStamp; info = options.info; fileOut = info.fileOut; filePath = info.filePath; fileOut = info.fileOut; dirOut = path.dirname(fileOut); if (mkdirp.sync(dirOut)) { verbose(3, "mkdir " + dirOut); } timeStamp = _timeStampFromStartTime(info.startTime); if (options.write) { return fs.writeFile(fileOut, data, function(err) { if (err) { error("file writing error " + filePath + ": " + err); return; } verbose(1, "compiled " + fileOut + timeStamp, 'cyan'); cb(null, data); }); } else { verbose(1, "compiled " + fileOut + timeStamp, 'cyan'); return cb(null, data); } }; _timeStampFromStartTime = function(startTime) { var deltaTime, timeStamp; deltaTime = process.hrtime(startTime); return timeStamp = " (" + (deltaTime[0] + Math.round(10000 * deltaTime[1] / 1000000000) / 10000) + " sec)"; }; watchCache = {}; isWatched = function(fullPath) { return watchCache[fullPath] != null; }; triggerWatched = function(fullPath) { var _ref1, _ref2; return (_ref1 = watchCache[fullPath]) != null ? (_ref2 = _ref1._events) != null ? typeof _ref2.change === "function" ? _ref2.change() : void 0 : void 0 : void 0; }; watchParents = {}; watchFile = function(filePath, includeDir, options) { var compileTimeout, e, prevStats, timeEpsilon, timeLast, watcher, _onWatch, _rewatch, _unwatch, _watchErr; if (options == null) { options = {}; } if (isWatched(filePath)) { return; } prevStats = null; compileTimeout = null; _watchErr = function(e) { if (e.code === 'ENOENT') { try { _rewatch(); return _compile(); } catch (_error) { e = _error; verbose(2, "unwatching missing file: " + filePath, 'yellow'); return _unwatch(); } } else { throw e; } }; timeLast = new Date(2000); timeEpsilon = 2; _onWatch = function() { var e; try { clearTimeout(compileTimeout); return compileTimeout = wait(0.025, function() { var parent, parents, timeNow, _j, _len1, _results; timeNow = new Date(); if ((timeNow - timeLast) / 1000 < timeEpsilon) { return; } timeLast = timeNow; if (!isOJPage(filePath)) { parents = watchParents[filePath]; if (parents != null) { _results = []; for (_j = 0, _len1 = parents.length; _j < _len1; _j++) { parent = parents[_j]; _results.push(triggerWatched(parent)); } return _results; } } else { return fs.stat(filePath, function(err, stats) { if (err) { return _watchErr(err); } verbose(2, "updating file " + filePath, 'yellow'); return compileFile(filePath, includeDir, options); }); } }); } catch (_error) { e = _error; verbose(1, 'unknown watch error on #{filePath}'); return _unwatch(); } }; try { verbose(2, "watching file " + filePath, 'yellow'); watcher = fs.watch(filePath, _onWatch); watchCache[filePath] = watcher; } catch (_error) { e = _error; _watchErr(e); } _rewatch = function() { verbose(3, "rewatch file " + filePath, 'yellow'); _unwatch(); return watchCache[filePath] = watcher = fs.watch(filePath, _onWatch); }; return _unwatch = function() { if (isWatched(filePath)) { watchCache[filePath].close(); } return watchCache[filePath] = null; }; }; watchDir = function(dir, includeDir, options) { var compileTimeout, watcher; if (isWatched(dir)) { return; } compileTimeout = null; verbose(2, "watching directory " + dir + "/", 'yellow'); watcher = fs.watch(dir, function(err) { verbose(2, "updating directory " + dir + "/", 'yellow'); if (err && !isDirectory(dir)) { return unwatchDir(dir); } return lsOJ(dir, options, function(err, files, dirs) { var d, f, _j, _k, _len1, _len2, _results; for (_j = 0, _len1 = dirs.length; _j < _len1; _j++) { d = dirs[_j]; if (!isWatched(d)) { watchDir(d); } } _results = []; for (_k = 0, _len2 = files.length; _k < _len2; _k++) { f = files[_k]; if (!isWatched(f)) { _results.push(compileFile(f, includeDir, options)); } else { _results.push(void 0); } } return _results; }); }); watchCache[dir] = watcher; }; unwatchDir = function(dir) { verbose(2, "unwatching " + dir + "/", 'yellow'); if (isWatched(dir)) { watchCache[dir].close(); } watchCache[dir] = null; }; unwatchAll = function() { var k, _j, _len1, _ref1, _results; verbose(2, "unwatching all files and directories", 'yellow'); _ref1 = _.keys(watchCache); _results = []; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { k = _ref1[_j]; if (watchCache[k] != null) { watchCache[k].close(); _results.push(watchCache[k] = null); } else { _results.push(void 0); } } return _results; }; process.on('SIGINT', function() { verbose(1, "\n"); unwatchAll(); verbose(1, "oj exited successfully.", 'cyan'); return process.exit(); }); success = function() { return process.exit(0); }; tabs = function(count) { return Array(count + 1).join('\t'); }; spaces = function(count) { return Array(count + 1).join(' '); }; verbose = function(level, message, color) { if (color == null) { color = 'reset'; } if (verbosity >= level) { return console.log(oj.codes[color] + ("" + (spaces(4 * (level - 1))) + message) + oj.codes.reset); } }; error = function(message) { var red, reset, _ref1, _ref2, _ref3, _ref4; red = (_ref1 = (_ref2 = oj.codes) != null ? _ref2.red : void 0) != null ? _ref1 : ''; reset = (_ref3 = (_ref4 = oj.codes) != null ? _ref4.reset : void 0) != null ? _ref3 : ''; console.error("" + red + message + reset); }; isFile = function(filePath) { var e; try { return (fs.statSync(filePath)).isFile(); } catch (_error) { e = _error; return false; } }; isOJFile = function(filePath) { var ext; ext = path.extname(filePath); return ext === '.oj' || ext === '.ojc'; }; isOJPage = function(filePath) { var base, ext; ext = path.extname(filePath); base = path.basename(filePath); return (isOJFile(filePath)) && base[0] !== '_' && base.slice(0, 2) !== 'oj' && !isHiddenFile(filePath); }; isOJDir = function(dirPath, outputDir) { var base; base = path.basename(dirPath); return base[0] !== '_' && base[0] !== '.' && base !== 'node_modules'; }; isWatchFile = function(filePath) { var ext; ext = path.extname(filePath); return (isOJFile(filePath)) || ext === '.js' || ext === '.coffee' || ext === '.json'; }; isHiddenFile = function(file) { return /^\.|~$/.test(file); }; isDirectory = function(dirpath) { var e; try { return (fs.statSync(dirpath)).isDirectory(); } catch (_error) { e = _error; return false; } }; relativePathWithEscaping = function(fullPath, relativeTo) { return _escapeSingleQuotes('/' + path.relative(relativeTo, fullPath)); }; fullPaths = function(relativePaths, dir) { return _.map(relativePaths, function(p) { return path.resolve(dir, p); }); }; commonPath = function(paths, seperator) { var common, ixCommon, ixPart, p, part, parts, _j, _k, _len1, _len2; if (seperator == null) { seperator = '/'; } if (paths.length === 1) { return path.dirname(paths[0]); } common = paths[0].split(seperator); ixCommon = common.length; for (_j = 0, _len1 = paths.length; _j < _len1; _j++) { p = paths[_j]; parts = p.split(seperator); for (ixPart = _k = 0, _len2 = parts.length; _k < _len2; ixPart = ++_k) { part = parts[ixPart]; if (common[ixPart] !== part || ixPart > ixCommon) { break; } } ixCommon = Math.min(ixPart, ixCommon); } if (ixCommon === 1 && paths[0][0] === seperator) { return seperator; } else if (ixCommon === 0) { return null; } return (common.slice(0, ixCommon)).join(seperator); }; lsOJ = function(paths, options, cb) { if (options == null) { options = {}; } options = _.extend({}, { recurse: options.recurse, filterFile: (function(f) { return isOJPage(f); }), filterDir: (function(d) { return isOJDir(d); }) }); ls(paths, options, function(err, files, dirs) { return cb(err, files, dirs); }); }; lsWatch = function(paths, options, cb) { var lsOptions; lsOptions = _.extend({}, { recurse: options.recurse, filterFile: isWatchFile, filterDir: isOJDir }); ls(paths, lsOptions, function(err, files, dirs) { return cb(err, files, dirs); }); }; ls = function(fullPath, options, cb, acc) { var breakIfDone, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; if (_.isFunction(options)) { cb = options; options = {}; } if (options == null) { options = {}; } if ((_ref1 = options.recurse) == null) { options.recurse = false; } if ((_ref2 = options.filterFile) == null) { options.filterFile = function() { return true; }; } if ((_ref3 = options.filterDir) == null) { options.filterDir = function() { return true; }; } if ((_ref4 = options.recurseDepth) == null) { options.recurseDepth = options.recurse ? Infinity : 1; } if (acc == null) { acc = {}; } if ((_ref5 = acc.files) == null) { acc.files = []; } if ((_ref6 = acc.dirs) == null) { acc.dirs = []; } if ((_ref7 = acc.pending) == null) { acc.pending = 1; } breakIfDone = function() { var dirs, files; if (acc.pending === 0) { files = _.uniq(acc.files); dirs = _.uniq(acc.dirs); cb(null, files, dirs); } }; fs.stat(fullPath, function(err, stat) { if (err) { return cb(err); } if (stat.isFile() && options.filterFile(fullPath)) { acc.files.push(fullPath); return breakIfDone(--acc.pending); } else if (stat.isDirectory() && options.filterDir(fullPath)) { acc.dirs.push(fullPath); return fs.readdir(fullPath, function(errReadDir, paths) { var fullPath_, options_, _j, _len1; if (errReadDir) { return cb(errReadDir); } if (!paths || paths.length === 0) { return breakIfDone(--acc.pending); } acc.pending += paths.length; paths = fullPaths(paths, fullPath); if (options.recurseDepth > 0) { options_ = _.clone(options); options_.recurseDepth--; for (_j = 0, _len1 = paths.length; _j < _len1; _j++) { fullPath_ = paths[_j]; ls(fullPath_, options_, cb, acc); } } return breakIfDone(--acc.pending); }); } else { return breakIfDone(--acc.pending); } }); }; readFileSync = function(filePath) { return fs.readFileSync(filePath, 'utf8'); }; wait = function(seconds, fn) { return setTimeout(fn, seconds * 1000); }; trimArgList = function(v) { return _trim(v.split(',')); }; _trim = function(any) { var out; if (_.isString(any)) { return any.trim(); } else if (_.isArray(any)) { out = _.map(any, function(v) { return v.trim(); }); return _.reject(out, (function(v) { return v === '' || v === null; })); } else { return any; } }; _startsWith = function(strInput, strStart) { if (!((_.isString(strInput)) && (_.isString(strStart)))) { throw new Error('startsWith: argument error'); } return strInput.length >= strStart.length && strInput.lastIndexOf(strStart, 0) === 0; }; _escapeSingleQuotes = function(str) { return str.replace(/'/g, "\\'"); }; _insertAt = function(str, ix, substr) { return str.slice(0, ix) + substr + str.slice(ix); }; _length = function(any) { return any.length || _.keys(any).length; }; oj._minifyJS = function(js, options) { if (options == null) { options = {}; } if (options.filename) { verbose(4, "minified " + options.filename); } if (options.minify) { return uglifyjs(js); } else { return js; } }; oj._minifyCSS = function(css, options) { if (options == null) { options = {}; } if (options.minify) { return csso.justDoIt(css, true); } else { return css; } }; _hookRequire = function(modules, moduleLinkMap, hookCache, hookOriginalCache) { var ext, handlers, hook; if (hookCache == null) { hookCache = {}; } if (hookOriginalCache == null) { hookOriginalCache = {}; } handlers = require.extensions; for (ext in handlers) { hook = hookCache[ext] || (hookCache[ext] = _createHook(ext, modules, moduleLinkMap, hookCache, hookOriginalCache)); if (handlers[ext] !== hook) { hookOriginalCache[ext] = handlers[ext]; handlers[ext] = hook; } } }; _createHook = function(ext, modules, moduleLinkMap, hookCache, hookOriginalCache) { return function(module, filename) { var linkPath, moduleCompile, modulePath, rest; for (linkPath in moduleLinkMap) { modulePath = moduleLinkMap[linkPath]; if (0 === filename.indexOf(linkPath)) { rest = filename.slice(linkPath.length); filename = modulePath + rest; } } if (!module.loaded) { _rememberModule(modules, filename, null, module.parent.filename); moduleCompile = module._compile; module._compile = function(code) { _rememberModule(modules, filename, code, module.parent.filename); moduleCompile.apply(this, arguments); }; } hookOriginalCache[ext](module, filename); return _hookRequire(modules, moduleLinkMap, hookCache, hookOriginalCache); }; }; _unhookRequire = function(modules, hookCache, hookOriginalCache) { var ext, handlers; handlers = require.extensions; for (ext in handlers) { if (hookCache[ext] === handlers[ext]) { handlers[ext] = hookOriginalCache[ext]; } } hookCache = null; hookOriginalCache = null; }; _rememberModule = function(modules, filename, code, parent) { if (code) { verbose(3, "requiring " + filename); } return modules[filename] = _.defaults({ code: code, parent: parent }, modules[filename] || {}); }; _rememberModuleDependencies = function(modules) { var filename, module, _ref1, _results; _results = []; for (filename in modules) { module = modules[filename]; if ((_ref1 = watchParents[filename]) == null) { watchParents[filename] = []; } watchParents[filename].push(module.parent); _results.push(watchParents[filename] = _.unique(watchParents[filename])); } return _results; }; _nodeModulesSupported = { oj: 1, jquery: 1, assert: 1, console: 1, crypto: 1, events: 1, freelist: 1, path: 1, punycode: 1, querystring: 1, string_decoder: 1, tty: 1, url: 1, util: 1 }; _nodeModuleUnsupported = { child_process: 1, domain: 1, fs: 1, net: 1, os: 1, vm: 1, buffer: 1 }; isNodeModule = function(module) { return !!_nodeModulesSupported[module]; }; isUnsupportedNodeModule = function(module) { return !!_nodeModuleUnsupported[module]; }; isAppModule = function(module) { return (module.indexOf('/')) === -1; }; isRelativeModule = function(module) { return (module.indexOf('/')) !== -1; }; _requireCache = null; _saveRequireCache = function() { return _requireCache = _.clone(require.cache); }; _restoreRequireCache = function() { var k, _results; _results = []; for (k in require.cache) { if (_requireCache[k] == null) { _results.push(delete require.cache[k]); } else { _results.push(void 0); } } return _results; }; _clearRequireCacheRecord = function(record) { return delete require.cache[require.resolve(record)]; }; _getRequiresInSource = function(code) { var match, out, r; r = new RegExp("require\\s*\\(?\\s*[\"']([^\"']+)", 'g'); out = []; while (match = r.exec(code)) { out.push(match[1]); } return out; }; _first = function(array, fn) { var x, y, _j, _len1; for (_j = 0, _len1 = array.length; _j < _len1; _j++) { x = array[_j]; y = fn(x); if (y) { return y; } } }; _buildRequireCache = function(modules, cache, isMinify) { var code, data, fileLocation, filePath, modulePrefixes, pathComponents, _ref1; for (fileLocation in modules) { data = modules[fileLocation]; if (data.code == null) { throw new Error('data.code is missing'); } _buildFileCache(cache.files, fileLocation, data.code, isMinify); modulePrefixes = nodeModulePaths(fileLocation); pathComponents = _first(modulePrefixes, function(prefix) { var moduleMain, moduleName, modulePath; if (_startsWith(fileLocation, prefix + path.sep)) { modulePath = (fileLocation.slice(prefix.length + 1)).split(path.sep); moduleName = modulePath[0]; moduleMain = modulePath.slice(1).join(path.sep); return { modulesDir: prefix, moduleName: moduleName, moduleMain: moduleMain, moduleParentPath: module.id }; } }); if (pathComponents) { if (!cache.modules[pathComponents.modulesDir]) { cache.modules[pathComponents.modulesDir] = {}; } cache.modules[pathComponents.modulesDir][pathComponents.moduleName] = pathComponents.moduleMain; } _buildNativeCache(cache["native"], data.code, isMinify); verbose(4, "stored " + fileLocation); } delete cache.files[require.resolve('../oj.js')]; cache.nativeFiles = cache["native"]; cache.moduleFiles = {}; cache.pageFiles = {}; _ref1 = cache.files; for (filePath in _ref1) { code = _ref1[filePath]; if (filePath.indexOf("/node_modules/") !== -1) { cache.moduleFiles[filePath] = code; } else { cache.pageFiles[filePath] = code; } } return cache; }; _buildFileCache = function(_filesCache, fileName, code, isMinify) { return _filesCache[fileName] = oj._minifyJS(code, { filename: fileName, minify: isMinify }); }; pass = 1; _buildNativeCache = function(nativeCache, code, isMinify) { var moduleNameList; moduleNameList = _getRequiresInSource(code); return _buildNativeCacheFromModuleList(nativeCache, moduleNameList, isMinify); }; _buildNativeCacheFromModuleList = function(nativeCache, moduleNameList, isMinify) { var codeModule, moduleName; while (moduleName = moduleNameList.shift()) { if (nativeCache[moduleName]) { continue; } if (moduleName === 'oj') { nativeCache.oj = _ojModuleCode(isMinify); } else if (isUnsupportedNodeModule(moduleName)) { pass; } else if (isNodeModule(moduleName)) { codeModule = _nativeModuleCode(moduleName, isMinify); nativeCache[moduleName] = codeModule; moduleNameList = moduleNameList.concat(_getRequiresInSource(codeModule)); } else { pass; } } return null; }; _ojModuleCode = function(isMinify) { var code; code = readFileSync(path.join(__dirname, "../oj.js")); return oj._minifyJS(code, { filename: 'oj', minify: isMinify }); }; _nativeModuleCode = function(moduleName, isMinify) { var code; verbose(3, "found " + moduleName); return code = readFileSync(path.join(__dirname, "../modules/" + moduleName + ".js")); }; _requireCacheToHtml = function(cache, filePath, isMinify, options) { return "<script>\n" + (_requireCacheToJS(cache, filePath, isMinify, options)) + "\n</script>"; }; _requireCacheToJS = function(cache, filePath, isMinify, options) { var clientDir, clientFile, code, commonDir, js, moduleDir, moduleName, nameToMain, newline, prefixWithRequire, _data, _fileToString, _find, _load, _moduleFiles, _modules, _modulesToString, _nativeFiles, _nativeModuleToString, _pageFiles, _ref1, _ref2, _ref3, _ref4, _run; newline = isMinify ? '' : '\n'; commonDir = commonPath(_.keys(cache.files)); clientDir = '/' + path.relative(commonDir, path.dirname(filePath)); clientFile = path.join(clientDir, basenameForExtensions(filePath, ['.ojc', '.oj', '.coffee', '.js'])); _modulesToString = function(moduleDir, nameToMain) { moduleDir = relativePathWithEscaping(moduleDir, commonDir); return "M['" + moduleDir + "'] = " + (JSON.stringify(nameToMain)) + ";\n"; }; _nativeModuleToString = function(moduleName, code) { moduleName = _escapeSingleQuotes(moduleName); return "F['" + moduleName + "'] = (function(module,exports){(function(process,global,__dirname,__filename){" + newline + code + "})(P,G,'/','" + moduleName + "');});\n"; }; _fileToString = function(filePath, code, prefixWithRequire) { var fileDir, fileName, out; filePath = relativePathWithEscaping(filePath, commonDir); fileDir = path.dirname(filePath); fileName = path.basename(filePath); out = prefixWithRequire ? "require." : ""; return out += "F['" + filePath + "'] = (function(module,exports){(function(require,process,global,__dirname,__filename){" + newline + code + "})(require.RR('" + filePath + "'),require.P,require.G,'" + fileDir + "','" + fileName + "');});" + newline + "\n"; }; _modules = ""; _ref1 = cache.modules; for (moduleDir in _ref1) { nameToMain = _ref1[moduleDir]; _modules += _modulesToString(moduleDir, nameToMain); } _moduleFiles = ""; _ref2 = cache.moduleFiles; for (filePath in _ref2) { code = _ref2[filePath]; _moduleFiles += _fileToString(filePath, code); verbose(4, "serialized module file `" + filePath + "`"); } _pageFiles = ""; prefixWithRequire = !options.modules; _ref3 = cache.pageFiles; for (filePath in _ref3) { code = _ref3[filePath]; _pageFiles += _fileToString(filePath, code, prefixWithRequire); verbose(4, "serialized page file `" + filePath + "`"); } _nativeFiles = ""; _ref4 = cache["native"]; for (moduleName in _ref4) { code = _ref4[moduleName]; _nativeFiles += _nativeModuleToString(moduleName, code); verbose(4, "serialized native file '" + moduleName + "'"); } _data = ''; if (!_.isEmpty(options.data)) { _data = ',' + JSON.stringify(options.data); } _load = "oj.load('" + (_escapeSingleQuotes(clientFile)) + "'" + _data + ");"; _run = oj._minifyJS("function run(f){\n if(R[f] != null)\n return R[f];\n var eo = {},\n mo = {exports: eo};\n if(typeof F[f] != 'function')\n throw new Error(\"file not found (\" + f + \")\");\n F[f](mo,eo);\n return R[f] = mo.exports;\n }", { minify: isMinify }); _find = oj._minifyJS("function find(m,f){\n var r, dir, dm, ext, ex, i, loc;\n if (F[m] && !m.match(/\\//))\n return m;\n\n if (!!m.match(/\\//)) {\n r = oj._pathResolve(f, oj._pathJoin(oj._pathDirname(f), m));\n ext = ['', '.oj', '.ojc', '.js', '.coffee', '.json'];\n for(i = 0; i < ext.length; i++){\n ex = ext[i];\n if((loc = r + ex) && F[loc])\n return loc;\n else if ((loc = oj._pathJoin(r, 'index' + ex)) && F[loc])\n return loc;\n }\n } else {\n if (typeof oj !== 'undefined') {\n dir = oj._pathDirname(f);\n while(true) {\n dm = oj._pathJoin(dir, 'node_modules');\n if(M[dm] && M[dm][m])\n return oj._pathJoin(dm, m, M[dm][m]);\n if(dir == '/')\n break;\n dir = oj._pathResolve(dir, '..');\n }\n }\n }\n throw new Error(\"module not found (\" + m + \")\");\n }", { minify: isMinify }); js = "// Generated with oj v" + oj.version + "\n;(function(){"; if (options.modules) { js += "var M = {}, F = {}, R = {}, P, G, RR;\n\n// Package modules\n" + _modules + "\n" + _moduleFiles + "\n// Native modules\n" + _nativeFiles + "\n// Define node environment: process P, global G and require factory RR\nP = {cwd: function(){return '/'}}\nG = {process: P,Buffer: {}}\nRR = function(f){\n var o = function(m){return run(find(m, f))};\n o.P = P; o.G = G; o.F = F; o.M = M, o.RR = RR;\n return o;\n " + _run + "\n " + _find + "\n};\n\n// Define require and oj\nrequire = RR('/');\noj = require('oj');\n"; } if (options.js) { js += "\n// Page files\n" + _pageFiles + "\n" + _load + "\n"; } return js += "}).call(this);"; }; oj.__express = function(path, options, cb) { var data; data = _.omit(_.clone(options), 'settings', 'cache'); _.defaults(options, { minify: options.minify, write: false, watch: false, recurse: true, modules: false, html: true, css: true, js: true, data: data }); compilePath(path, options, cb); }; oj.middleware = function(options) { var urlModulesDir; urlModulesDir = '/' + path.relative(options.publicDir, options.modulesDirDest); return function(req, res, next) { var baseFileName, fileRelativePath, outputFileDir, outputFilePath, urlPath; if ('GET' !== req.method && 'HEAD' !== req.method) { return next(); } urlPath = url.parse(req.url).pathname; if (/\.js$/.test(urlPath) && _startsWith(urlPath, urlModulesDir)) { fileRelativePath = path.relative(urlModulesDir, urlPath); outputFilePath = path.join(options.modulesDirDest, fileRelativePath); outputFileDir = path.dirname(outputFilePath); baseFileName = path.basename(urlPath, '.js'); return findFile(options.modulesDirSrc, baseFileName, ['.oj', '.ojc'], function(err, inputFilePath) { var _middlewareCompileModule; if (inputFilePath) { if (options.force) { _middlewareCompileModule(); } else { fileIsOutdated(outputFilePath, inputFilePath, function(err, idOutdated) { if (idOutdated) { _middlewareCompileModule(); } else { next(); } }); } return _middlewareCompileModule = function() { var e, _ref1, _ref2; try { return compilePath(inputFilePath, { output: outputFileDir, force: (_ref1 = options.force) != null ? _ref1 : false, minify: (_ref2 = options.minify) != null ? _ref2 : true, html: 0, css: 0, js: 0, write: 1, modules: 1 }, function() { return next(); }); } catch (_error) { e = _error; return next(); } }; } else { return next(); } }); } else { return next(); } }; }; fileIsOutdated = function(fileDest, fileSource, cb) { fs.stat(fileSource, function(errSource, statSource) { if (errSource) { return cb(errSource, null); } return fs.stat(fileDest, function(errDest, statDest) { if (!errDest || errDest.code === 'ENOENT') { return cb(null, !!errDest || statSource.mtime.getTime() > statDest.mtime.getTime()); } else { return cb(errDest, null); } }); }); }; findFile = function(dir, baseFileName, extensions, cb) { var ext, fileName; if (!dir || !baseFileName || !extensions || !cb) { return cb('findFile: invalid input'); } ext = extensions.shift(); fileName = baseFileName + ext; return (function(dir, fileName) { return fs.stat(path.join(dir, fileName), function(err, statInfo) { if (statInfo && statInfo.isFile()) { return cb(null, path.join(dir, fileName)); } else if (extensions.length > 0) { return findFile(dir, baseFileName, extensions, cb); } else { return cb(null, null); } }); })(dir, fileName); }; }).call(this);