JAVASCRIPT   165

generate.js

Guest on 27th July 2021 08:38:56 AM

  1. #!/usr/bin/env node
  2. var fs = require('fs');
  3. var path = require('path');
  4.  
  5. // These are the node packages we are going to wrap.
  6. var packages = {
  7.     assert: { skip: true },
  8.     async_hooks: { optional: true, skip: true },
  9.     buffer: { skip: true },
  10.     child_process: {
  11.         exec: { promisify: true, returnsObject: true, args: 1, cb:['stdout','stderr'] },
  12.         execFile: { promisify: true, returnsObject: true, args: 1, cb:['stdout','stderr'] },
  13.         fork: { promisify: false },
  14.         spawn: { promisify: false },
  15.     },
  16.     cluster: {
  17.         disconnect: { promisify: true, args: 0 },
  18.     },
  19.     console: { skip: true },
  20.     crypto: {
  21.         DEFAULT_ENCODING: { constant: false },
  22.         pseudoRandomBytes: { promisify: true, syncIfNoCallback: true, args: 1 },
  23.         randomBytes: { promisify: true, syncIfNoCallback: true, args: 1 },
  24.         randomFill: { args: 1 },
  25.     },
  26.     dns: {
  27.         // XXX: Resolver could be wrapped...
  28.         ADNAME: { skip: true },
  29.         lookup: { promisify: true, args: 1 },
  30.         lookupService: { promisify: true, args: 2, cb:['hostname','service'] },
  31.         resolve: { promisify: true, args: 1 },
  32.         resolve4: { promisify: true, args: 1 },
  33.         resolve6: { promisify: true, args: 1 },
  34.         resolveAny: { promisify: true, args: 1 },
  35.         resolveCname: { promisify: true, args: 1 },
  36.         resolveMx: { promisify: true, args: 1 },
  37.         resolveNaptr: { promisify: true, args: 1 },
  38.         resolveNs: { promisify: true, args: 1 },
  39.         resolvePtr: { promisify: true, args: 1 },
  40.         resolveSoa: { promisify: true, args: 1 },
  41.         resolveSrv: { promisify: true, args: 1 },
  42.         resolveTxt: { promisify: true, args: 1 },
  43.         reverse: { promisify: true, args: 1 },
  44.     },
  45.     domain: {
  46.         // XXX Domain#bind and Domain#intercept should be promisified
  47.     },
  48.     events: {
  49.         skip: true,
  50.     },
  51.     fs: {
  52.         access: { args: 1 },
  53.         appendFile: { args: 2 },
  54.         copyFile: { args: 2 },
  55.         exists: { promisify: true, noError: true },
  56.         mkdir: { args: 1 },
  57.         mkdtemp: { args: 1 },
  58.         open: { args: 2 },
  59.         read: { cb: ['read', 'buffer'] },
  60.         readdir: { args: 1 },
  61.         readlink: { args: 1 },
  62.         readFile: { args: 1 },
  63.         realpath: { args: 1 },
  64.         symlink: { args: 2 },
  65.         write: { cb: ['written', 'buffer'] },
  66.         writeFile: { args: 2 },
  67.     },
  68.     http: {
  69.         STATUS_CODES: { constant: true },
  70.         // XXX ClientRequest#setTimeout should be promisified
  71.         // XXX IncomingMessage#setTimeout should be promisified
  72.         // XXX Server#listen, Server#close, and Server#setTimeout
  73.         // should be promisified
  74.         // XXX ServerResponse#setTimeout should be promisified
  75.         request: { promisify: true, returnsObject: true, args: 1 },
  76.         get: { promisify: true, returnsObject: true, args: 1 },
  77.     },
  78.     http2: {
  79.         optional: true,
  80.     },
  81.     https: {
  82.         // XXX Server#listen, Server#close, and Server#setTimeout
  83.         // should be promisified
  84.         request: { promisify: true, returnsObject: true, args: 1 },
  85.         get: { promisify: true, returnsObject: true, args: 1 },
  86.     },
  87.     inspector: {
  88.         optional: true,
  89.         skip: true,
  90.     },
  91.     net: {
  92.         // XXX Server#listen, Server#close, Server#getConnections
  93.         // should be promisified
  94.         // XXX Socket#write, Socket#setTimeout should be promisified
  95.     },
  96.     os: { skip: true },
  97.     path: { skip: true },
  98.     perf_hooks: { optional: true, skip: true },
  99.     process: {
  100.         nextTick: { promisify: true, args: 0 }
  101.     },
  102.     punycode: { optional: true, skip: true },
  103.     querystring: { skip: true },
  104.     readline: {
  105.         // XXX Interface#question should be promisified
  106.     },
  107.     repl: { skip: true },
  108.     stream: {
  109.         super_: { skip: true },
  110.         // XXX Writable#write and Writable#end should be promisified
  111.         // XXX same for Duplex and Transform? inheritance unclear.
  112.         // what about _read/_write/_transform/_flush for implementers?
  113.     },
  114.     string_decoder: { skip: true },
  115.     timers: {
  116.         setImmediate: { promisify: true, callbackIsFirstArg: true, noError: true },
  117.         setTimeout: { promisify: true, callbackIsFirstArg: true, noError: true },
  118.     },
  119.     tls: {
  120.         connect: { promisify: true, returnsObject: true, args: 1 },
  121.         createServer: { promisify: true, returnsObject: true, args: 1 },
  122.     },
  123.     tty: {
  124.         skip: true
  125.         // should tty.ReadStream and tty.WriteStream be promisified?
  126.         // (process.stdin / process.stdout)
  127.     },
  128.     dgram: {
  129.         // note that createSocket takes a listener, not a callback
  130.         // XXX Socket#send and Socket#bind should be promisified
  131.     },
  132.     url: { skip: true },
  133.     util: {
  134.         pump: { promisify: true, args: 2 }
  135.     },
  136.     v8: { optional: true, skip: true },
  137.     vm: { skip: true },
  138.     zlib: {
  139.         codes: { constant: true },
  140.         deflate: { promisify: true, args: 1 },
  141.         deflateRaw: { promisify: true, args: 1 },
  142.         gzip: { promisify: true, args: 1 },
  143.         gunzip: { promisify: true, args: 1 },
  144.         inflate: { promisify: true, args: 1 },
  145.         inflateRaw: { promisify: true, args: 1 },
  146.         unzip: { promisify: true, args: 1 },
  147.     },
  148. };
  149.  
  150. var sorted = function(arr) {
  151.     var s = arr.slice(0);
  152.     s.sort();
  153.     return s;
  154. }
  155.  
  156. sorted(Object.keys(packages)).forEach(function(pkgname) {
  157.     var pkgopts = packages[pkgname] || {};
  158.     var script = [];
  159.     var emit = function(l) { script.push(l); };
  160.     var m;
  161.     if (pkgname==='process') {
  162.         m = process;
  163.     } else if (pkgopts.optional) {
  164.         // Package is not present in older versions of node.
  165.         emit('var '+pkgname+' = {};');
  166.         emit('try { '+pkgname+' = require("'+pkgname+'"); } catch (e) { }');
  167.         m = require(pkgname);
  168.     } else {
  169.         emit('var '+pkgname+' = require("'+pkgname+'");');
  170.         m = require(pkgname);
  171.     }
  172.     if (pkgopts.skip) {
  173.         emit('module.exports = '+pkgname+';');
  174.     } else {
  175.         emit('var promisify = require("./_promisify.js");');
  176.         emit('var bind = function(c, f) { return f && f.bind(c); };');
  177.         emit('Object.defineProperties(module.exports, {');
  178.         sorted(Object.keys(m)).forEach(function(prop) {
  179.             var opts = pkgopts[prop] || {};
  180.             // skip private properties
  181.             if (opts.skip !== undefined ? opts.skip : /^_/.test(prop)) {
  182.                 emit('  //'+prop+': // skipping');
  183.                 return;
  184.             }
  185.             var out = '  '+prop+': { enumerable: true, ';
  186.             // Is this a function?
  187.             var caps = /^[A-Z]/.test(prop);
  188.             var isFunction = typeof(m[prop]) === 'function';
  189.             var isConstant = opts.constant!==undefined ? opts.constant :
  190.                 isFunction ?
  191.                 (opts.bind !== undefined ? opts.bind===false : caps) :
  192.                 caps;
  193.             if (isConstant) {
  194.                 emit(out+'value: '+pkgname+'.'+prop+' },');
  195.                 return;
  196.             }
  197.             if (!isFunction) {
  198.                 // add getters & setters
  199.                 emit(out+'get: function() { return '+pkgname+'.'+prop+'; }, '+
  200.                      'set: function(v) { '+pkgname+'.'+prop+' = v; } },');
  201.                 return;
  202.             }
  203.             // Is this a async function?
  204.             var isAsync = (typeof(m[prop+'Sync']) === 'function');
  205.             if (opts.promisify) { isAsync = true; }
  206.             if (!isAsync || opts.promisify === false) {
  207.                 emit(out+'value: bind('+pkgname+', '+pkgname+'.'+prop+') },');
  208.                 return;
  209.             }
  210.             // OK, this is very likely an async function!
  211.             // number of mandatory options (may be additional optional args)
  212.             var nargs = opts.args!==undefined ? opts.args :
  213.                 (typeof(m[prop+'Sync']) === 'function') ?
  214.                 m[prop+'Sync'].length : m[prop].length;
  215.             var options = {}, emitOptions = false;
  216.             if (opts.cb) {
  217.                 options.pattern = opts.cb;
  218.                 emitOptions = true;
  219.             }
  220.             if (opts.noError) {
  221.                 options.noError = true;
  222.                 emitOptions = true;
  223.             }
  224.             if (opts.returnsObject) {
  225.                 options.returnsObject = true;
  226.                 emitOptions = true;
  227.             }
  228.             if (opts.callbackIsFirstArg) {
  229.                 options.callbackIsFirstArg = true;
  230.                 nargs = 0;
  231.                 emitOptions = true;
  232.             }
  233.             var optString = emitOptions ? ', '+JSON.stringify(options) : '';
  234.             emit(out+'value: promisify('+pkgname+', '+pkgname+'.'+prop+', '+nargs+optString+') },');
  235.             if (opts.syncIfNoCallback) {
  236.                 emit(out.replace(/:/,"Sync:")+'value: '+pkgname+'.'+prop+'.bind('+pkgname+') },');
  237.             }
  238.         });
  239.         emit('});');
  240.     }
  241.     // Write out this wrapped package!
  242.     fs.writeFileSync(path.join(__dirname,'..',pkgname+'.js'),
  243.                      script.join('\n'), 'utf-8');
  244. });

Raw Paste


Login or Register to edit or fork this paste. It's free.