You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							244 lines
						
					
					
						
							8.9 KiB
						
					
					
				
			
		
		
	
	
							244 lines
						
					
					
						
							8.9 KiB
						
					
					
				#!/usr/bin/env node | 
						|
var fs = require('fs'); | 
						|
var path = require('path'); | 
						|
 | 
						|
// These are the node packages we are going to wrap. | 
						|
var packages = { | 
						|
    assert: { skip: true }, | 
						|
    async_hooks: { optional: true, skip: true }, | 
						|
    buffer: { skip: true }, | 
						|
    child_process: { | 
						|
        exec: { promisify: true, returnsObject: true, args: 1, cb:['stdout','stderr'] }, | 
						|
        execFile: { promisify: true, returnsObject: true, args: 1, cb:['stdout','stderr'] }, | 
						|
        fork: { promisify: false }, | 
						|
        spawn: { promisify: false }, | 
						|
    }, | 
						|
    cluster: { | 
						|
        disconnect: { promisify: true, args: 0 }, | 
						|
    }, | 
						|
    console: { skip: true }, | 
						|
    crypto: { | 
						|
        DEFAULT_ENCODING: { constant: false }, | 
						|
        pseudoRandomBytes: { promisify: true, syncIfNoCallback: true, args: 1 }, | 
						|
        randomBytes: { promisify: true, syncIfNoCallback: true, args: 1 }, | 
						|
        randomFill: { args: 1 }, | 
						|
    }, | 
						|
    dns: { | 
						|
        // XXX: Resolver could be wrapped... | 
						|
        ADNAME: { skip: true }, | 
						|
        lookup: { promisify: true, args: 1 }, | 
						|
        lookupService: { promisify: true, args: 2, cb:['hostname','service'] }, | 
						|
        resolve: { promisify: true, args: 1 }, | 
						|
        resolve4: { promisify: true, args: 1 }, | 
						|
        resolve6: { promisify: true, args: 1 }, | 
						|
        resolveAny: { promisify: true, args: 1 }, | 
						|
        resolveCname: { promisify: true, args: 1 }, | 
						|
        resolveMx: { promisify: true, args: 1 }, | 
						|
        resolveNaptr: { promisify: true, args: 1 }, | 
						|
        resolveNs: { promisify: true, args: 1 }, | 
						|
        resolvePtr: { promisify: true, args: 1 }, | 
						|
        resolveSoa: { promisify: true, args: 1 }, | 
						|
        resolveSrv: { promisify: true, args: 1 }, | 
						|
        resolveTxt: { promisify: true, args: 1 }, | 
						|
        reverse: { promisify: true, args: 1 }, | 
						|
    }, | 
						|
    domain: { | 
						|
        // XXX Domain#bind and Domain#intercept should be promisified | 
						|
    }, | 
						|
    events: { | 
						|
        skip: true, | 
						|
    }, | 
						|
    fs: { | 
						|
        access: { args: 1 }, | 
						|
        appendFile: { args: 2 }, | 
						|
        copyFile: { args: 2 }, | 
						|
        exists: { promisify: true, noError: true }, | 
						|
        mkdir: { args: 1 }, | 
						|
        mkdtemp: { args: 1 }, | 
						|
        open: { args: 2 }, | 
						|
        read: { cb: ['read', 'buffer'] }, | 
						|
        readdir: { args: 1 }, | 
						|
        readlink: { args: 1 }, | 
						|
        readFile: { args: 1 }, | 
						|
        realpath: { args: 1 }, | 
						|
        symlink: { args: 2 }, | 
						|
        write: { cb: ['written', 'buffer'] }, | 
						|
        writeFile: { args: 2 }, | 
						|
    }, | 
						|
    http: { | 
						|
        STATUS_CODES: { constant: true }, | 
						|
        // XXX ClientRequest#setTimeout should be promisified | 
						|
        // XXX IncomingMessage#setTimeout should be promisified | 
						|
        // XXX Server#listen, Server#close, and Server#setTimeout | 
						|
        // should be promisified | 
						|
        // XXX ServerResponse#setTimeout should be promisified | 
						|
        request: { promisify: true, returnsObject: true, args: 1 }, | 
						|
        get: { promisify: true, returnsObject: true, args: 1 }, | 
						|
    }, | 
						|
    http2: { | 
						|
        optional: true, | 
						|
    }, | 
						|
    https: { | 
						|
        // XXX Server#listen, Server#close, and Server#setTimeout | 
						|
        // should be promisified | 
						|
        request: { promisify: true, returnsObject: true, args: 1 }, | 
						|
        get: { promisify: true, returnsObject: true, args: 1 }, | 
						|
    }, | 
						|
    inspector: { | 
						|
        optional: true, | 
						|
        skip: true, | 
						|
    }, | 
						|
    net: { | 
						|
        // XXX Server#listen, Server#close, Server#getConnections | 
						|
        // should be promisified | 
						|
        // XXX Socket#write, Socket#setTimeout should be promisified | 
						|
    }, | 
						|
    os: { skip: true }, | 
						|
    path: { skip: true }, | 
						|
    perf_hooks: { optional: true, skip: true }, | 
						|
    process: { | 
						|
        nextTick: { promisify: true, args: 0 } | 
						|
    }, | 
						|
    punycode: { optional: true, skip: true }, | 
						|
    querystring: { skip: true }, | 
						|
    readline: { | 
						|
        // XXX Interface#question should be promisified | 
						|
    }, | 
						|
    repl: { skip: true }, | 
						|
    stream: { | 
						|
        super_: { skip: true }, | 
						|
        // XXX Writable#write and Writable#end should be promisified | 
						|
        // XXX same for Duplex and Transform? inheritance unclear. | 
						|
        // what about _read/_write/_transform/_flush for implementers? | 
						|
    }, | 
						|
    string_decoder: { skip: true }, | 
						|
    timers: { | 
						|
        setImmediate: { promisify: true, callbackIsFirstArg: true, noError: true }, | 
						|
        setTimeout: { promisify: true, callbackIsFirstArg: true, noError: true }, | 
						|
    }, | 
						|
    tls: { | 
						|
        connect: { promisify: true, returnsObject: true, args: 1 }, | 
						|
        createServer: { promisify: true, returnsObject: true, args: 1 }, | 
						|
    }, | 
						|
    tty: { | 
						|
        skip: true | 
						|
        // should tty.ReadStream and tty.WriteStream be promisified? | 
						|
        // (process.stdin / process.stdout) | 
						|
    }, | 
						|
    dgram: { | 
						|
        // note that createSocket takes a listener, not a callback | 
						|
        // XXX Socket#send and Socket#bind should be promisified | 
						|
    }, | 
						|
    url: { skip: true }, | 
						|
    util: { | 
						|
        pump: { promisify: true, args: 2 } | 
						|
    }, | 
						|
    v8: { optional: true, skip: true }, | 
						|
    vm: { skip: true }, | 
						|
    zlib: { | 
						|
        codes: { constant: true }, | 
						|
        deflate: { promisify: true, args: 1 }, | 
						|
        deflateRaw: { promisify: true, args: 1 }, | 
						|
        gzip: { promisify: true, args: 1 }, | 
						|
        gunzip: { promisify: true, args: 1 }, | 
						|
        inflate: { promisify: true, args: 1 }, | 
						|
        inflateRaw: { promisify: true, args: 1 }, | 
						|
        unzip: { promisify: true, args: 1 }, | 
						|
    }, | 
						|
}; | 
						|
 | 
						|
var sorted = function(arr) { | 
						|
    var s = arr.slice(0); | 
						|
    s.sort(); | 
						|
    return s; | 
						|
} | 
						|
 | 
						|
sorted(Object.keys(packages)).forEach(function(pkgname) { | 
						|
    var pkgopts = packages[pkgname] || {}; | 
						|
    var script = []; | 
						|
    var emit = function(l) { script.push(l); }; | 
						|
    var m; | 
						|
    if (pkgname==='process') { | 
						|
        m = process; | 
						|
    } else if (pkgopts.optional) { | 
						|
        // Package is not present in older versions of node. | 
						|
        emit('var '+pkgname+' = {};'); | 
						|
        emit('try { '+pkgname+' = require("'+pkgname+'"); } catch (e) { }'); | 
						|
        m = require(pkgname); | 
						|
    } else { | 
						|
        emit('var '+pkgname+' = require("'+pkgname+'");'); | 
						|
        m = require(pkgname); | 
						|
    } | 
						|
    if (pkgopts.skip) { | 
						|
        emit('module.exports = '+pkgname+';'); | 
						|
    } else { | 
						|
        emit('var promisify = require("./_promisify.js");'); | 
						|
        emit('var bind = function(c, f) { return f && f.bind(c); };'); | 
						|
        emit('Object.defineProperties(module.exports, {'); | 
						|
        sorted(Object.keys(m)).forEach(function(prop) { | 
						|
            var opts = pkgopts[prop] || {}; | 
						|
            // skip private properties | 
						|
            if (opts.skip !== undefined ? opts.skip : /^_/.test(prop)) { | 
						|
                emit('  //'+prop+': // skipping'); | 
						|
                return; | 
						|
            } | 
						|
            var out = '  '+prop+': { enumerable: true, '; | 
						|
            // Is this a function? | 
						|
            var caps = /^[A-Z]/.test(prop); | 
						|
            var isFunction = typeof(m[prop]) === 'function'; | 
						|
            var isConstant = opts.constant!==undefined ? opts.constant : | 
						|
                isFunction ? | 
						|
                (opts.bind !== undefined ? opts.bind===false : caps) : | 
						|
                caps; | 
						|
            if (isConstant) { | 
						|
                emit(out+'value: '+pkgname+'.'+prop+' },'); | 
						|
                return; | 
						|
            } | 
						|
            if (!isFunction) { | 
						|
                // add getters & setters | 
						|
                emit(out+'get: function() { return '+pkgname+'.'+prop+'; }, '+ | 
						|
                     'set: function(v) { '+pkgname+'.'+prop+' = v; } },'); | 
						|
                return; | 
						|
            } | 
						|
            // Is this a async function? | 
						|
            var isAsync = (typeof(m[prop+'Sync']) === 'function'); | 
						|
            if (opts.promisify) { isAsync = true; } | 
						|
            if (!isAsync || opts.promisify === false) { | 
						|
                emit(out+'value: bind('+pkgname+', '+pkgname+'.'+prop+') },'); | 
						|
                return; | 
						|
            } | 
						|
            // OK, this is very likely an async function! | 
						|
            // number of mandatory options (may be additional optional args) | 
						|
            var nargs = opts.args!==undefined ? opts.args : | 
						|
                (typeof(m[prop+'Sync']) === 'function') ? | 
						|
                m[prop+'Sync'].length : m[prop].length; | 
						|
            var options = {}, emitOptions = false; | 
						|
            if (opts.cb) { | 
						|
                options.pattern = opts.cb; | 
						|
                emitOptions = true; | 
						|
            } | 
						|
            if (opts.noError) { | 
						|
                options.noError = true; | 
						|
                emitOptions = true; | 
						|
            } | 
						|
            if (opts.returnsObject) { | 
						|
                options.returnsObject = true; | 
						|
                emitOptions = true; | 
						|
            } | 
						|
            if (opts.callbackIsFirstArg) { | 
						|
                options.callbackIsFirstArg = true; | 
						|
                nargs = 0; | 
						|
                emitOptions = true; | 
						|
            } | 
						|
            var optString = emitOptions ? ', '+JSON.stringify(options) : ''; | 
						|
            emit(out+'value: promisify('+pkgname+', '+pkgname+'.'+prop+', '+nargs+optString+') },'); | 
						|
            if (opts.syncIfNoCallback) { | 
						|
                emit(out.replace(/:/,"Sync:")+'value: '+pkgname+'.'+prop+'.bind('+pkgname+') },'); | 
						|
            } | 
						|
        }); | 
						|
        emit('});'); | 
						|
    } | 
						|
    // Write out this wrapped package! | 
						|
    fs.writeFileSync(path.join(__dirname,'..',pkgname+'.js'), | 
						|
                     script.join('\n'), 'utf-8'); | 
						|
});
 | 
						|
 |