(function () { // anonymous namespace /** deprecation errors ************************************************/ function removed (reason) { return function () { throw new Error(reason) } } GLOBAL.__module = removed("'__module' has been renamed to 'module'"); GLOBAL.include = removed("include(module) has been removed. Use process.mixin(GLOBAL, require(module)) to get the same effect."); GLOBAL.puts = removed("puts() has moved. Use require('sys') to bring it back."); GLOBAL.print = removed("print() has moved. Use require('sys') to bring it back."); GLOBAL.p = removed("p() has moved. Use require('sys') to bring it back."); process.debug = removed("process.debug() has moved. Use require('sys') to bring it back."); process.error = removed("process.error() has moved. Use require('sys') to bring it back."); GLOBAL.node = {}; node.createProcess = removed("node.createProcess() has been changed to process.createChildProcess() update your code"); node.exec = removed("process.exec() has moved. Use require('sys') to bring it back."); node.inherits = removed("node.inherits() has moved. Use require('sys') to access it."); node.http = {}; node.http.createServer = removed("node.http.createServer() has moved. Use require('http') to access it."); node.http.createClient = removed("node.http.createClient() has moved. Use require('http') to access it."); node.tcp = {}; node.tcp.createServer = removed("node.tcp.createServer() has moved. Use require('tcp') to access it."); node.tcp.createConnection = removed("node.tcp.createConnection() has moved. Use require('tcp') to access it."); node.dns = {}; node.dns.createConnection = removed("node.dns.createConnection() has moved. Use require('dns') to access it."); /**********************************************************************/ // Module function Module (id, parent) { this.id = id; this.exports = {}; this.parent = parent; this.filename = null; this.loaded = false; this.loadPromise = null; this.exited = false; this.children = []; }; var moduleCache = {}; function createModule (id, parent) { if (id in moduleCache) { debug("found " + JSON.stringify(id) + " in cache"); return moduleCache[id]; } debug("didn't found " + JSON.stringify(id) + " in cache. creating new module"); var m = new Module(id, parent); moduleCache[id] = m; return m; }; function createInternalModule (id, constructor) { var m = createModule(id); constructor(m.exports); m.loaded = true; return m; }; process.inherits = function (ctor, superCtor) { var tempCtor = function(){}; tempCtor.prototype = superCtor.prototype; ctor.super_ = superCtor; ctor.prototype = new tempCtor(); ctor.prototype.constructor = ctor; }; process.createChildProcess = function (file, args, env) { var child = new process.ChildProcess(); args = args || []; env = env || process.ENV; var envPairs = []; for (var key in env) { if (env.hasOwnProperty(key)) { envPairs.push(key + "=" + env[key]); } } // TODO Note envPairs is not currently used in child_process.cc. The PATH // needs to be searched for the 'file' command if 'file' does not contain // a '/' character. child.spawn(file, args, envPairs); return child; }; process.assert = function (x, msg) { if (!(x)) throw new Error(msg || "assertion error"); }; // From jQuery.extend in the jQuery JavaScript Library v1.3.2 // Copyright (c) 2009 John Resig // Dual licensed under the MIT and GPL licenses. // http://docs.jquery.com/License process.mixin = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !(typeof target === 'function') ) target = {}; // mixin process itself if only one argument is passed if ( length == i ) { target = GLOBAL; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( var name in options ) { var src = target[ name ], copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) continue; // Recurse if we're merging object values if ( deep && copy && typeof copy === "object" ) { target[ name ] = process.mixin( deep, // Never move original objects, clone them src || ( copy.length != null ? [ ] : { } ) , copy ); // Don't bring in undefined values } else { target[ name ] = copy; } } } } // Return the modified object return target; }; // Event var eventsModule = createInternalModule('events', function (exports) { exports.EventEmitter = process.EventEmitter; // process.EventEmitter is defined in src/events.cc // process.EventEmitter.prototype.emit() is also defined there. process.EventEmitter.prototype.addListener = function (type, listener) { if (listener instanceof Function) { if (!this._events) this._events = {}; if (!this._events.hasOwnProperty(type)) this._events[type] = []; // To avoid recursion in the case that type == "newListeners"! Before // adding it to the listeners, first emit "newListeners". this.emit("newListener", type, listener); this._events[type].push(listener); } return this; }; process.EventEmitter.prototype.removeListener = function (type, listener) { if (listener instanceof Function) { // does not use listeners(), so no side effect of creating _events[type] if (!this._events || !this._events.hasOwnProperty(type)) return; var list = this._events[type]; if (list.indexOf(listener) < 0) return; list.splice(list.indexOf(listener), 1); } return this; }; process.EventEmitter.prototype.listeners = function (type) { if (!this._events) this._events = {}; if (!this._events.hasOwnProperty(type)) this._events[type] = []; return this._events[type]; }; exports.Promise = function () { exports.EventEmitter.call(this); this._blocking = false; this.hasFired = false; this._values = undefined; }; process.inherits(exports.Promise, exports.EventEmitter); process.Promise = exports.Promise; exports.Promise.prototype.timeout = function(timeout) { if (!timeout) { return this._timeoutDuration; } this._timeoutDuration = timeout; if (this.hasFired) return; this._clearTimeout(); var self = this; this._timer = setTimeout(function() { self._timer = null; if (self.hasFired) { return; } self.emitError(new Error('timeout')); }, timeout); return this; }; exports.Promise.prototype._clearTimeout = function() { if (!this._timer) return; clearTimeout(this._timer); this._timer = null; } exports.Promise.prototype.emitSuccess = function() { if (this.hasFired) return; this.hasFired = true; this._clearTimeout(); this._values = Array.prototype.slice.call(arguments); this.emit.apply(this, ['success'].concat(this._values)); }; exports.Promise.prototype.emitError = function() { if (this.hasFired) return; this.hasFired = true; this._clearTimeout(); this._values = Array.prototype.slice.call(arguments); this.emit.apply(this, ['error'].concat(this._values)); if (this.listeners('error').length == 0) { var self = this; process.nextTick(function() { if (self.listeners('error').length == 0) { throw (self._values[0] instanceof Error) ? self._values[0] : new Error('Unhandled emitError: '+JSON.stringify(self._values)); } }); } }; exports.Promise.prototype.addCallback = function (listener) { if (this.hasFired) { return listener.apply(this, this._values); } return this.addListener("success", listener); }; exports.Promise.prototype.addErrback = function (listener) { if (this.hasFired) { listener.apply(this, this._values); } return this.addListener("error", listener); }; /* Poor Man's coroutines */ var coroutineStack = []; exports.Promise.prototype._destack = function () { this._blocking = false; while (coroutineStack.length > 0 && !coroutineStack[coroutineStack.length-1]._blocking) { coroutineStack.pop(); process.unloop("one"); } }; exports.Promise.prototype.wait = function () { var self = this; var ret; var hadError = false; self.addCallback(function () { if (arguments.length == 1) { ret = arguments[0]; } else if (arguments.length > 1) { ret = Array.prototype.slice.call(arguments); } self._destack(); }); self.addErrback(function (arg) { hadError = true; ret = arg; self._destack(); }); coroutineStack.push(self); if (coroutineStack.length > 10) { process.stdio.writeError("WARNING: promise.wait() is being called too often.\n"); } self._blocking = true; process.loop(); process.assert(self._blocking == false); if (hadError) { if (ret) { throw ret; } else { throw new Error("Promise completed with error (No arguments given.)"); } } return ret; }; }); var events = eventsModule.exports; // nextTick() var nextTickQueue = []; var nextTickWatcher = new process.IdleWatcher(); nextTickWatcher.setPriority(process.EVMAXPRI); // max priority nextTickWatcher.callback = function () { var l = nextTickQueue.length; while (l--) { var cb = nextTickQueue.shift(); cb(); } if (nextTickQueue.length == 0) nextTickWatcher.stop(); }; process.nextTick = function (callback) { nextTickQueue.push(callback); nextTickWatcher.start(); }; // Signal Handlers function isSignal (event) { return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event); }; process.addListener("newListener", function (event) { if (isSignal(event) && process.listeners(event).length === 0) { var handler = new process.SignalHandler(process[event]); handler.addListener("signal", function () { process.emit(event); }); } }); // Stat Change Watchers var statWatchers = {}; process.watchFile = function (filename) { var stat; var options; var listener; if ("object" == typeof arguments[1]) { options = arguments[1]; listener = arguments[2]; } else { options = {}; listener = arguments[1]; } if (options.persistent === undefined) options.persistent = true; if (options.interval === undefined) options.interval = 0; if (filename in statWatchers) { stat = statWatchers[filename]; } else { statWatchers[filename] = new process.Stat(); stat = statWatchers[filename]; stat.start(filename, options.persistent, options.interval); } stat.addListener("change", listener); return stat; }; process.unwatchFile = function (filename) { if (filename in statWatchers) { stat = statWatchers[filename]; stat.stop(); statWatchers[filename] = undefined; } }; process.Stats.prototype._checkModeProperty = function (property) { return ((this.mode & property) === property); }; process.Stats.prototype.isDirectory = function () { return this._checkModeProperty(process.S_IFDIR); }; process.Stats.prototype.isFile = function () { return this._checkModeProperty(process.S_IFREG); }; process.Stats.prototype.isBlockDevice = function () { return this._checkModeProperty(process.S_IFBLK); }; process.Stats.prototype.isCharacterDevice = function () { return this._checkModeProperty(process.S_IFCHR); }; process.Stats.prototype.isSymbolicLink = function () { return this._checkModeProperty(process.S_IFLNK); }; process.Stats.prototype.isFIFO = function () { return this._checkModeProperty(process.S_IFIFO); }; process.Stats.prototype.isSocket = function () { return this._checkModeProperty(process.S_IFSOCK); }; // Timers function addTimerListener (callback) { var timer = this; // Special case the no param case to avoid the extra object creation. if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); timer.addListener("timeout", function(){ callback.apply(timer, args); }); } else { timer.addListener("timeout", callback); } } GLOBAL.setTimeout = function (callback, after) { var timer = new process.Timer(); addTimerListener.apply(timer, arguments); timer.start(after, 0); return timer; }; GLOBAL.setInterval = function (callback, repeat) { var timer = new process.Timer(); addTimerListener.apply(timer, arguments); timer.start(repeat, repeat); return timer; }; GLOBAL.clearTimeout = function (timer) { if (timer instanceof process.Timer) { timer.stop(); } }; GLOBAL.clearInterval = GLOBAL.clearTimeout; // Modules var debugLevel = 0; if ("NODE_DEBUG" in process.ENV) debugLevel = 1; function debug (x) { if (debugLevel > 0) { process.stdio.writeError(x + "\n"); } } var posixModule = createInternalModule("posix", function (exports) { exports.Stats = process.Stats; function callback (promise) { return function () { if (arguments[0] instanceof Error) { promise.emitError.apply(promise, arguments); } else { promise.emitSuccess.apply(promise, arguments); } }; } // Yes, the follow could be easily DRYed up but I provide the explicit // list to make the arguments clear. exports.close = function (fd) { var promise = new events.Promise(); process.fs.close(fd, callback(promise)); return promise; }; exports.closeSync = function (fd) { return process.fs.close(fd); }; exports.open = function (path, flags, mode) { var promise = new events.Promise(); process.fs.open(path, flags, mode, callback(promise)); return promise; }; exports.openSync = function (path, flags, mode) { return process.fs.open(path, flags, mode); }; exports.read = function (fd, length, position, encoding) { var promise = new events.Promise(); encoding = encoding || "binary"; process.fs.read(fd, length, position, encoding, callback(promise)); return promise; }; exports.readSync = function (fd, length, position, encoding) { encoding = encoding || "binary"; return process.fs.read(fd, length, position, encoding); }; exports.write = function (fd, data, position, encoding) { var promise = new events.Promise(); encoding = encoding || "binary"; process.fs.write(fd, data, position, encoding, callback(promise)); return promise; }; exports.writeSync = function (fd, data, position, encoding) { encoding = encoding || "binary"; return process.fs.write(fd, data, position, encoding); }; exports.rename = function (oldPath, newPath) { var promise = new events.Promise(); process.fs.rename(oldPath, newPath, callback(promise)); return promise; }; exports.renameSync = function (oldPath, newPath) { return process.fs.rename(oldPath, newPath); }; exports.rmdir = function (path) { var promise = new events.Promise(); process.fs.rmdir(path, callback(promise)); return promise; }; exports.rmdirSync = function (path) { return process.fs.rmdir(path); }; exports.mkdir = function (path, mode) { var promise = new events.Promise(); process.fs.mkdir(path, mode, callback(promise)); return promise; }; exports.mkdirSync = function (path, mode) { return process.fs.mkdir(path, mode); }; exports.sendfile = function (outFd, inFd, inOffset, length) { var promise = new events.Promise(); process.fs.sendfile(outFd, inFd, inOffset, length, callback(promise)); return promise; }; exports.sendfileSync = function (outFd, inFd, inOffset, length) { return process.fs.sendfile(outFd, inFd, inOffset, length); }; exports.readdir = function (path) { var promise = new events.Promise(); process.fs.readdir(path, callback(promise)); return promise; }; exports.readdirSync = function (path) { return process.fs.readdir(path); }; exports.stat = function (path) { var promise = new events.Promise(); process.fs.stat(path, callback(promise)); return promise; }; exports.statSync = function (path) { return process.fs.stat(path); }; exports.unlink = function (path) { var promise = new events.Promise(); process.fs.unlink(path, callback(promise)); return promise; }; exports.unlinkSync = function (path) { return process.fs.unlink(path); }; exports.cat = function (path, encoding) { var promise = new events.Promise(); encoding = encoding || "utf8"; // default to utf8 exports.open(path, process.O_RDONLY, 0666).addCallback(function (fd) { var content = "", pos = 0; function readChunk () { exports.read(fd, 16*1024, pos, encoding).addCallback(function (chunk, bytes_read) { if (chunk) { if (chunk.constructor === String) { content += chunk; } else { content = content.concat(chunk); } pos += bytes_read; readChunk(); } else { promise.emitSuccess(content); exports.close(fd); } }).addErrback(function () { promise.emitError.apply(promise, arguments); }); } readChunk(); }).addErrback(function () { promise.emitError.apply(promise, arguments); }); return promise; }; }); var posix = posixModule.exports; var pathModule = createInternalModule("path", function (exports) { exports.join = function () { return exports.normalize(Array.prototype.join.call(arguments, "/")); }; exports.normalizeArray = function (parts, keepBlanks) { var directories = [], prev; for (var i = 0, l = parts.length - 1; i <= l; i++) { var directory = parts[i]; // if it's blank, but it's not the first thing, and not the last thing, skip it. if (directory === "" && i !== 0 && i !== l && !keepBlanks) continue; // if it's a dot, and there was some previous dir already, then skip it. if (directory === "." && prev !== undefined) continue; if ( directory === ".." && directories.length && prev !== ".." && prev !== undefined && (prev !== "" || keepBlanks) ) { directories.pop(); prev = directories.slice(-1)[0] } else { if (prev === ".") directories.pop(); directories.push(directory); prev = directory; } } return directories; }; exports.normalize = function (path, keepBlanks) { return exports.normalizeArray(path.split("/"), keepBlanks).join("/"); }; exports.dirname = function (path) { return path.substr(0, path.lastIndexOf("/")) || "."; }; exports.filename = function () { throw new Error("path.filename is deprecated. Please use path.basename instead."); }; exports.basename = function (path, ext) { var f = path.substr(path.lastIndexOf("/") + 1); if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function (path) { var index = path.lastIndexOf('.'); return index < 0 ? '' : path.substring(index); }; exports.exists = function (path, callback) { var p = posix.stat(path); p.addCallback(function () { callback(true); }); p.addErrback(function () { callback(false); }); }; }); var path = pathModule.exports; process.paths = [ path.join(process.installPrefix, "lib/node/libraries") ]; if (process.ENV["HOME"]) { process.paths.unshift(path.join(process.ENV["HOME"], ".node_libraries")); } if (process.ENV["NODE_PATH"]) { process.paths = process.ENV["NODE_PATH"].split(":").concat(process.paths); } function findModulePath (id, dirs, callback) { process.assert(dirs.constructor == Array); if (/^https?:\/\//.exec(id)) { callback(id); return; } if (/\.(js|node)$/.exec(id)) { throw new Error("No longer accepting filename extension in module names"); } if (dirs.length == 0) { callback(); return; } var dir = dirs[0]; var rest = dirs.slice(1, dirs.length); if (id.charAt(0) == '/') { dir = ''; rest = []; } var locations = [ path.join(dir, id + ".js"), path.join(dir, id + ".node"), path.join(dir, id, "index.js"), path.join(dir, id, "index.addon") ]; var searchLocations = function() { var location = locations.shift(); if (location === undefined) { findModulePath(id, rest, callback); return; } path.exists(location, function (found) { if (found) { callback(location); return; } searchLocations(); }); }; searchLocations(); } function loadModule (request, parent) { // This is the promise which is actually returned from require.async() var loadPromise = new events.Promise(); // debug("loadModule REQUEST " + (request) + " parent: " + JSON.stringify(parent)); var id, paths; if (request.charAt(0) == "." && (request.charAt(1) == "/" || request.charAt(1) == ".")) { // Relative request var parentIdPath = path.dirname(parent.id + (path.basename(parent.filename).match(/^index\.(js|addon)$/) ? "/" : "")); id = path.join(parentIdPath, request); // debug("RELATIVE: requested:"+request+" set ID to: "+id+" from "+parent.id+"("+parentIdPath+")"); paths = [path.dirname(parent.filename)]; } else { id = request; // debug("ABSOLUTE: id="+id); paths = process.paths; } if (id in moduleCache) { debug("found " + JSON.stringify(id) + " in cache"); // In cache var module = moduleCache[id]; process.nextTick(function () { loadPromise.emitSuccess(module.exports); }); } else { debug("looking for " + JSON.stringify(id) + " in " + JSON.stringify(paths)); // Not in cache findModulePath(request, paths, function (filename) { if (!filename) { loadPromise.emitError(new Error("Cannot find module '" + request + "'")); } else { var module = createModule(id, parent); module.load(filename, loadPromise); } }); } return loadPromise; }; Module.prototype.load = function (filename, loadPromise) { debug("load " + JSON.stringify(filename) + " for module " + JSON.stringify(this.id)); process.assert(!this.loaded); process.assert(!this.loadPromise); this.loadPromise = loadPromise; this.filename = filename; if (filename.match(/\.node$/)) { this.loadObject(filename, loadPromise); } else { this.loadScript(filename, loadPromise); } }; Module.prototype.loadObject = function (filename, loadPromise) { var self = this; // XXX Not yet supporting loading from HTTP. would need to download the // file, store it to tmp then run dlopen on it. process.nextTick(function () { self.loaded = true; process.dlopen(filename, self.exports); // FIXME synchronus loadPromise.emitSuccess(self.exports); }); }; function cat (id, loadPromise) { var promise; debug(id); if (id.match(/^http:\/\//)) { promise = new events.Promise(); loadModule('http', process.mainModule) .addCallback(function(http) { http.cat(id) .addCallback(function(content) { promise.emitSuccess(content); }) .addErrback(function() { promise.emitError.apply(null, arguments); }); }) .addErrback(function() { loadPromise.emitError(new Error("could not load core module \"http\"")); }); } else { promise = posix.cat(id); } return promise; } Module.prototype.loadScript = function (filename, loadPromise) { var self = this; var catPromise = cat(filename, loadPromise); catPromise.addErrback(function () { loadPromise.emitError(new Error("Cannot read " + filename)); }); catPromise.addCallback(function (content) { // remove shebang content = content.replace(/^\#\!.*/, ''); function requireAsync (url) { return loadModule(url, self); // new child } function require (url) { return requireAsync(url).wait(); } require.paths = process.paths; require.async = requireAsync; require.main = process.mainModule; // create wrapper function var wrapper = "var __wrap__ = function (exports, require, module, __filename, __dirname) { " + content + "\n}; __wrap__;"; try { var compiledWrapper = process.compile(wrapper, filename); compiledWrapper.apply(self.exports, [self.exports, require, self, filename, path.dirname(filename)]); } catch (e) { loadPromise.emitError(e); return; } self.waitChildrenLoad(function () { self.loaded = true; loadPromise.emitSuccess(self.exports); }); }); }; Module.prototype.waitChildrenLoad = function (callback) { var nloaded = 0; var children = this.children; for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.loaded) { nloaded++; } else { child.loadPromise.addCallback(function () { nloaded++; if (children.length == nloaded && callback) callback(); }); } } if (children.length == nloaded && callback) callback(); }; process.exit = function (code) { process.emit("exit"); process.reallyExit(code); }; var cwd = process.cwd(); // Make process.ARGV[0] and process.ARGV[1] into full paths. if (process.ARGV[0].indexOf('/') > 0) { process.ARGV[0] = path.join(cwd, process.ARGV[0]); } if (process.ARGV[1].charAt(0) != "/" && !(/^http:\/\//).exec(process.ARGV[1])) { process.ARGV[1] = path.join(cwd, process.ARGV[1]); } // Load the main module--the command line argument. process.mainModule = createModule("."); var loadPromise = new events.Promise(); process.mainModule.load(process.ARGV[1], loadPromise); // All our arguments are loaded. We've evaluated all of the scripts. We // might even have created TCP servers. Now we enter the main eventloop. If // there are no watchers on the loop (except for the ones that were // ev_unref'd) then this function exits. As long as there are active // watchers, it blocks. process.loop(); process.emit("exit"); }()); // end anonymous namespace