react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / node_modules / commoner / lib / util.js
81159 viewsvar assert = require("assert");1var path = require("path");2var fs = require("graceful-fs");3var Q = require("q");4var createHash = require("crypto").createHash;5var mkdirp = require("mkdirp");6var iconv = require("iconv-lite");7var Ap = Array.prototype;8var slice = Ap.slice;9var join = Ap.join;1011// The graceful-fs module attempts to limit the total number of open files12// by queueing fs operations, but it doesn't know about all open files, so13// we set the limit somewhat lower than the default to provide a healthy14// buffer against EMFILE (too many open files) errors.15fs.MAX_OPEN = 512;1617function makePromise(callback, context) {18var deferred = Q.defer();1920function finish(err, result) {21if (err) {22deferred.reject(err);23} else {24deferred.resolve(result);25}26}2728process.nextTick(function() {29try {30callback.call(context || null, finish);31} catch (err) {32finish(err);33}34});3536return deferred.promise;37}38exports.makePromise = makePromise;3940exports.cachedMethod = function(fn, keyFn) {41var p = require("private").makeAccessor();4243function wrapper() {44var priv = p(this);45var cache = priv.cache || (priv.cache = {});46var args = arguments;47var key = keyFn48? keyFn.apply(this, args)49: join.call(args, "\0");50return cache.hasOwnProperty(key)51? cache[key]52: cache[key] = fn.apply(this, args);53}5455wrapper.originalFn = fn;5657return wrapper;58};5960function readFileP(file, charset) {61return makePromise(charset ? function(callback) {62return fs.readFile(file, function(err, data) {63if (err) {64callback(err);65} else {66callback(null, iconv.decode(data, charset));67}68});69} : function(callback) {70return fs.readFile(file, "utf8", callback);71});72}73exports.readFileP = readFileP;7475exports.readJsonFileP = function(file) {76return readFileP(file).then(function(json) {77return JSON.parse(json);78});79};8081function mkdirP(dir) {82return makePromise(function(callback) {83mkdirp(dir, function(err) {84callback(err, dir);85});86});87}88exports.mkdirP = mkdirP;8990function readFromStdinP(timeLimit, message, color) {91var deferred = Q.defer();92var ins = [];9394timeLimit = timeLimit || 1000;95var timeout = setTimeout(function() {96log.err(97message || ("Warning: still waiting for STDIN after " +98timeLimit + "ms"),99color || "yellow"100);101}, timeLimit);102103try {104// On Windows, just accessing process.stdin throws an exception105// when no standard input has been provided. For consistency with106// other platforms, log the error but continue waiting (until107// killed) for the nonexistent input.108var stdin = process.stdin;109} catch (err) {110log.err(err);111}112113if (stdin) {114stdin.resume();115stdin.setEncoding("utf8");116117stdin.on("data", function(data) {118ins.push(data);119}).on("end", function() {120clearTimeout(timeout);121deferred.resolve(ins.join(""));122});123}124125return deferred.promise;126}127exports.readFromStdinP = readFromStdinP;128129exports.readJsonFromStdinP = function(timeLimit) {130return readFromStdinP(timeLimit).then(function(input) {131return JSON.parse(input);132});133};134135function deepHash(val) {136var hash = createHash("sha1");137var type = typeof val;138139if (val === null) {140type = "null";141}142143switch (type) {144case "object":145Object.keys(val).sort().forEach(function(key) {146if (typeof val[key] === "function") {147// Silently ignore nested methods, but nevertheless148// complain below if the root value is a function.149return;150}151152hash.update(key + "\0")153.update(deepHash(val[key]));154});155break;156157case "function":158assert.ok(false, "cannot hash function objects");159break;160161default:162hash.update(val + "");163break;164}165166return hash.digest("hex");167}168exports.deepHash = deepHash;169170exports.existsP = function(fullPath) {171return makePromise(function(callback) {172fs.exists(fullPath, function(exists) {173callback(null, exists);174});175});176};177178function writeFdP(fd, content) {179return makePromise(function(callback) {180content += "";181var buffer = new Buffer(content, "utf8");182var length = fs.writeSync(fd, buffer, 0, buffer.length, null);183assert.strictEqual(length, buffer.length);184callback(null, content);185}).finally(function() {186fs.closeSync(fd);187});188}189exports.writeFdP = writeFdP;190191function openFileP(file, mode) {192return makePromise(function(callback) {193fs.open(file, mode || "w+", callback);194});195}196exports.openFileP = openFileP;197198function openExclusiveP(file) {199// The 'x' in "wx+" means the file must be newly created.200return openFileP(file, "wx+");201}202exports.openExclusiveP = openExclusiveP;203204exports.copyP = function(srcFile, dstFile) {205return makePromise(function(callback) {206var reader = fs.createReadStream(srcFile);207208function onError(err) {209callback(err || new Error(210"error in util.copyP(" +211JSON.stringify(srcFile) + ", " +212JSON.stringify(dstFile) + ")"213));214}215216reader.on("error", onError).pipe(217fs.createWriteStream(dstFile)218).on("finish", function() {219callback(null, dstFile);220}).on("error", onError);221});222};223224// Even though they use synchronous operations to avoid race conditions,225// linkP and unlinkP have promise interfaces, for consistency. Note that226// this means the operation will not happen until at least the next tick227// of the event loop, but it will be atomic when it happens.228exports.linkP = function(srcFile, dstFile) {229return mkdirP(path.dirname(dstFile)).then(function() {230if (fs.existsSync(dstFile))231fs.unlinkSync(dstFile);232fs.linkSync(srcFile, dstFile);233return dstFile;234});235};236237exports.unlinkP = function(file) {238return makePromise(function(callback) {239try {240if (fs.existsSync(file))241fs.unlinkSync(file);242callback(null, file);243} catch (err) {244callback(err);245}246});247};248249var colors = {250bold: "\033[1m",251red: "\033[31m",252green: "\033[32m",253yellow: "\033[33m",254cyan: "\033[36m",255reset: "\033[0m"256};257258Object.keys(colors).forEach(function(key) {259if (key !== "reset") {260exports[key] = function(text) {261return colors[key] + text + colors.reset;262};263}264});265266var log = exports.log = {267out: function(text, color) {268text = (text + "").trim();269if (colors.hasOwnProperty(color))270text = colors[color] + text + colors.reset;271process.stdout.write(text + "\n");272},273274err: function(text, color) {275text = (text + "").trim();276if (!colors.hasOwnProperty(color))277color = "red";278text = colors[color] + text + colors.reset;279process.stderr.write(text + "\n");280}281};282283var slugExp = /[^a-z\-]/ig;284exports.idToSlug = function(id) {285return id.replace(slugExp, "_");286};287288var moduleIdExp = /^[ a-z0-9\-_\/\.]+$/i;289exports.isValidModuleId = function(id) {290return id === "<stdin>" || moduleIdExp.test(id);291};292293var objToStr = Object.prototype.toString;294var arrStr = objToStr.call([]);295296function flatten(value, into) {297if (objToStr.call(value) === arrStr) {298into = into || [];299for (var i = 0, len = value.length; i < len; ++i)300if (i in value) // Skip holes.301flatten(value[i], into);302} else if (into) {303into.push(value);304} else {305return value;306}307308return into;309};310exports.flatten = flatten;311312exports.inherits = function(ctor, base) {313return ctor.prototype = Object.create(base.prototype, {314constructor: { value: ctor }315});316};317318function absolutize(moduleId, requiredId) {319if (requiredId.charAt(0) === ".")320requiredId = path.join(moduleId, "..", requiredId);321return path.normalize(requiredId).replace(/\\/g, '/');322}323exports.absolutize = absolutize;324325function relativize(moduleId, requiredId) {326requiredId = absolutize(moduleId, requiredId);327328if (requiredId.charAt(0) === ".") {329// Keep the required ID relative.330} else {331// Relativize the required ID.332requiredId = path.relative(333path.join(moduleId, ".."),334requiredId335);336}337338if (requiredId.charAt(0) !== ".")339requiredId = "./" + requiredId;340341return requiredId.replace(/\\/g, '/');342}343exports.relativize = relativize;344345function waitForValuesP(obj, makeCopy) {346if (typeof obj !== "object")347return Q(obj);348349var result = makeCopy ? {} : obj;350var keys = Object.keys(obj);351if (keys.length === 0)352return Q(result);353354return Q.all(keys.map(function(key) {355return obj[key];356})).then(function(values) {357for (var i = values.length - 1; i >= 0; --i)358result[keys[i]] = values[i];359return result;360});361}362exports.waitForValuesP = waitForValuesP;363364function camelize(hyphenated) {365return hyphenated.replace(/-(.)/g, function(_, ch) {366return ch.toUpperCase();367});368}369exports.camelize = camelize;370371372