code:
/**
 * XmlHttpRequest implementation that uses TLS and flash SocketPool.
 *
 * @author Dave Longley
 *
 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
 */
var forge = require('./forge');
require('./socket');
require('./http');

/* XHR API */
var xhrApi = module.exports = forge.xhr = forge.xhr || {};

(function($) {

// logging category
var cat = 'forge.xhr';

/*
XMLHttpRequest interface definition from:
http://www.w3.org/TR/XMLHttpRequest

interface XMLHttpRequest {
  // event handler
  attribute EventListener onreadystatechange;

  // state
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  void open(in DOMString method, in DOMString url);
  void open(in DOMString method, in DOMString url, in boolean async);
  void open(in DOMString method, in DOMString url,
            in boolean async, in DOMString user);
  void open(in DOMString method, in DOMString url,
            in boolean async, in DOMString user, in DOMString password);
  void setRequestHeader(in DOMString header, in DOMString value);
  void send();
  void send(in DOMString data);
  void send(in Document data);
  void abort();

  // response
  DOMString getAllResponseHeaders();
  DOMString getResponseHeader(in DOMString header);
  readonly attribute DOMString responseText;
  readonly attribute Document responseXML;
  readonly attribute unsigned short status;
  readonly attribute DOMString statusText;
};
*/

// readyStates
var UNSENT = 0;
var OPENED = 1;
var HEADERS_RECEIVED = 2;
var LOADING = 3;
var DONE = 4;

// exceptions
var INVALID_STATE_ERR = 11;
var SYNTAX_ERR = 12;
var SECURITY_ERR = 18;
var NETWORK_ERR = 19;
var ABORT_ERR = 20;

// private flash socket pool vars
var _sp = null;
var _policyPort = 0;
var _policyUrl = null;

// default client (used if no special URL provided when creating an XHR)
var _client = null;

// all clients including the default, key'd by full base url
// (multiple cross-domain http clients are permitted so there may be more
// than one client in this map)
// TODO: provide optional clean up API for non-default clients
var _clients = {};

// the default maximum number of concurrents connections per client
var _maxConnections = 10;

var net = forge.net;
var http = forge.http;

/**
 * Initializes flash XHR support.
 *
 * @param options:
 *   url: the default base URL to connect to if xhr URLs are relative,
 *     ie: https://myserver.com.
 *   flashId: the dom ID of the flash SocketPool.
 *   policyPort: the port that provides the server's flash policy, 0 to use
 *     the flash default.
 *   policyUrl: the policy file URL to use instead of a policy port.
 *   msie: true if browser is internet explorer, false if not.
 *   connections: the maximum number of concurrent connections.
 *   caCerts: a list of PEM-formatted certificates to trust.
 *   cipherSuites: an optional array of cipher suites to use,
 *     see forge.tls.CipherSuites.
 *   verify: optional TLS certificate verify callback to use (see forge.tls
 *     for details).
 *   getCertificate: an optional callback used to get a client-side
 *     certificate (see forge.tls for details).
 *   getPrivateKey: an optional callback used to get a client-side private
 *     key (see forge.tls for details).
 *   getSignature: an optional callback used to get a client-side signature
 *     (see forge.tls for details).
 *   persistCookies: true to use persistent cookies via flash local storage,
 *     false to only keep cookies in javascript.
 *   primeTlsSockets: true to immediately connect TLS sockets on their
 *     creation so that they will cache TLS sessions for reuse.
 */
xhrApi.init = function(options) {
  forge.log.debug(cat, 'initializing', options);

  // update default policy port and max connections
  _policyPort = options.policyPort || _policyPort;
  _policyUrl = options.policyUrl || _policyUrl;
  _maxConnections = options.connections || _maxConnections;

  // create the flash socket pool
  _sp = net.createSocketPool({
    flashId: options.flashId,
    policyPort: _policyPort,
    policyUrl: _policyUrl,
    msie: options.msie || false
  });

  // create default http client
  _client = http.createClient({
    url: options.url || (
      window.location.protocol + '//' + window.location.host),
    socketPool: _sp,
    policyPort: _policyPort,
    policyUrl: _policyUrl,
    connections: options.connections || _maxConnections,
    caCerts: options.caCerts,
    cipherSuites: options.cipherSuites,
    persistCookies: options.persistCookies || true,
    primeTlsSockets: options.primeTlsSockets || false,
    verify: options.verify,
    getCertificate: options.getCertificate,
    getPrivateKey: options.getPrivateKey,
    getSignature: options.getSignature
  });
  _clients[_client.url.origin] = _client;

  forge.log.debug(cat, 'ready');
};

/**
 * Called to clean up the clients and socket pool.
 */
xhrApi.cleanup = function() {
  // destroy all clients
  for(var key in _clients) {
    _clients[key].destroy();
  }
  _clients = {};
  _client = null;

  // destroy socket pool
  _sp.destroy();
  _sp = null;
};

/**
 * Sets a cookie.
 *
 * @param cookie the cookie with parameters:
 *   name: the name of the cookie.
 *   value: the value of the cookie.
 *   comment: an optional comment string.
 *   maxAge: the age of the cookie in seconds relative to created time.
 *   secure: true if the cookie must be sent over a secure protocol.
 *   httpOnly: true to restrict access to the cookie from javascript
 *     (inaffective since the cookies are stored in javascript).
 *   path: the path for the cookie.
 *   domain: optional domain the cookie belongs to (must start with dot).
 *   version: optional version of the cookie.
 *   created: creation time, in UTC seconds, of the cookie.
 */
xhrApi.setCookie = function(cookie) {
  // default cookie expiration to never
  cookie.maxAge = cookie.maxAge || -1;

  // if the cookie's domain is set, use the appropriate client
  if(cookie.domain) {
    // add the cookies to the applicable domains
    for(var key in _clients) {
      var client = _clients[key];
      if(http.withinCookieDomain(client.url, cookie) &&
        client.secure === cookie.secure) {
        client.setCookie(cookie);
      }
    }
  } else {
    // use the default domain
    // FIXME: should a null domain cookie be added to all clients? should
    // this be an option?
    _client.setCookie(cookie);
  }
};

/**
 * Gets a cookie.
 *
 * @param name the name of the cookie.
 * @param path an optional path for the cookie (if there are multiple cookies
 *          with the same name but different paths).
 * @param domain an optional domain for the cookie (if not using the default
 *          domain).
 *
 * @return the cookie, cookies (if multiple matches), or null if not found.
 */
xhrApi.getCookie = function(name, path, domain) {
  var rval = null;

  if(domain) {
    // get the cookies from the applicable domains
    for(var key in _clients) {
      var client = _clients[key];
      if(http.withinCookieDomain(client.url, domain)) {
        var cookie = client.getCookie(name, path);
        if(cookie !== null) {
          if(rval === null) {
            rval = cookie;
          } else if(!forge.util.isArray(rval)) {
            rval = [rval, cookie];
          } else {
            rval.push(cookie);
          }
        }
      }
    }
  } else {
    // get cookie from default domain
    rval = _client.getCookie(name, path);
  }

  return rval;
};

/**
 * Removes a cookie.
 *
 * @param name the name of the cookie.
 * @param path an optional path for the cookie (if there are multiple cookies
 *          with the same name but different paths).
 * @param domain an optional domain for the cookie (if not using the default
 *          domain).
 *
 * @return true if a cookie was removed, false if not.
 */
xhrApi.removeCookie = function(name, path, domain) {
  var rval = false;

  if(domain) {
    // remove the cookies from the applicable domains
    for(var key in _clients) {
      var client = _clients[key];
      if(http.withinCookieDomain(client.url, domain)) {
        if(client.removeCookie(name, path)) {
           rval = true;
        }
      }
    }
  } else {
    // remove cookie from default domain
    rval = _client.removeCookie(name, path);
  }

  return rval;
};

/**
 * Creates a new XmlHttpRequest. By default the base URL, flash policy port,
 * etc, will be used. However, an XHR can be created to point at another
 * cross-domain URL.
 *
 * @param options:
 *   logWarningOnError: If true and an HTTP error status code is received then
 *     log a warning, otherwise log a verbose message.
 *   verbose: If true be very verbose in the output including the response
 *     event and response body, otherwise only include status, timing, and
 *     data size.
 *   logError: a multi-var log function for warnings that takes the log
 *     category as the first var.
 *   logWarning: a multi-var log function for warnings that takes the log
 *     category as the first var.
 *   logDebug: a multi-var log function for warnings that takes the log
 *     category as the first var.
 *   logVerbose: a multi-var log function for warnings that takes the log
 *     category as the first var.
 *   url: the default base URL to connect to if xhr URLs are relative,
 *     eg: https://myserver.com, and note that the following options will be
 *     ignored if the URL is absent or the same as the default base URL.
 *   policyPort: the port that provides the server's flash policy, 0 to use
 *     the flash default.
 *   policyUrl: the policy file URL to use instead of a policy port.
 *   connections: the maximum number of concurrent connections.
 *   caCerts: a list of PEM-formatted certificates to trust.
 *   cipherSuites: an optional array of cipher suites to use, see
 *     forge.tls.CipherSuites.
 *   verify: optional TLS certificate verify callback to use (see forge.tls
 *     for details).
 *   getCertificate: an optional callback used to get a client-side
 *     certificate.
 *   getPrivateKey: an optional callback used to get a client-side private key.
 *   getSignature: an optional callback used to get a client-side signature.
 *   persistCookies: true to use persistent cookies via flash local storage,
 *     false to only keep cookies in javascript.
 *   primeTlsSockets: true to immediately connect TLS sockets on their
 *     creation so that they will cache TLS sessions for reuse.
 *
 * @return the XmlHttpRequest.
 */
xhrApi.create = function(options) {
  // set option defaults
  options = $.extend({
    logWarningOnError: true,
    verbose: false,
    logError: function() {},
    logWarning: function() {},
    logDebug: function() {},
    logVerbose: function() {},
    url: null
  }, options || {});

  // private xhr state
  var _state = {
    // the http client to use
    client: null,
    // request storage
    request: null,
    // response storage
    response: null,
    // asynchronous, true if doing asynchronous communication
    asynchronous: true,
    // sendFlag, true if send has been called
    sendFlag: false,
    // errorFlag, true if a network error occurred
    errorFlag: false
  };

  // private log functions
  var _log = {
    error: options.logError || forge.log.error,
    warning: options.logWarning || forge.log.warning,
    debug: options.logDebug || forge.log.debug,
    verbose: options.logVerbose || forge.log.verbose
  };

  // create public xhr interface
  var xhr = {
    // an EventListener
    onreadystatechange: null,
    // readonly, the current readyState
    readyState: UNSENT,
    // a string with the response entity-body
    responseText: '',
    // a Document for response entity-bodies that are XML
    responseXML: null,
    // readonly, returns the HTTP status code (i.e. 404)
    status: 0,
    // readonly, returns the HTTP status message (i.e. 'Not Found')
    statusText: ''
  };

  // determine which http client to use
  if(options.url === null) {
    // use default
    _state.client = _client;
  } else {
    var url;
    try {
      url = new URL(options.url);
    } catch(e) {
      var error = new Error('Invalid url.');
      error.details = {
        url: options.url
      };
    }

    // find client
    if(url.origin in _clients) {
      // client found
      _state.client = _clients[url.origin];
    } else {
      // create client
      _state.client = http.createClient({
        url: options.url,
        socketPool: _sp,
        policyPort: options.policyPort || _policyPort,
        policyUrl: options.policyUrl || _policyUrl,
        connections: options.connections || _maxConnections,
        caCerts: options.caCerts,
        cipherSuites: options.cipherSuites,
        persistCookies: options.persistCookies || true,
        primeTlsSockets: options.primeTlsSockets || false,
        verify: options.verify,
        getCertificate: options.getCertificate,
        getPrivateKey: options.getPrivateKey,
        getSignature: options.getSignature
      });
      _clients[url.origin] = _state.client;
    }
  }

  /**
   * Opens the request. This method will create the HTTP request to send.
   *
   * @param method the HTTP method (i.e. 'GET').
   * @param url the relative url (the HTTP request path).
   * @param async always true, ignored.
   * @param user always null, ignored.
   * @param password always null, ignored.
   */
  xhr.open = function(method, url, async, user, password) {
    // 1. validate Document if one is associated
    // TODO: not implemented (not used yet)

    // 2. validate method token
    // 3. change method to uppercase if it matches a known
    // method (here we just require it to be uppercase, and
    // we do not allow the standard methods)
    // 4. disallow CONNECT, TRACE, or TRACK with a security error
    switch(method) {
    case 'DELETE':
    case 'GET':
    case 'HEAD':
    case 'OPTIONS':
    case 'PATCH':
    case 'POST':
    case 'PUT':
      // valid method
      break;
    case 'CONNECT':
    case 'TRACE':
    case 'TRACK':
      throw new Error('CONNECT, TRACE and TRACK methods are disallowed');
    default:
      throw new Error('Invalid method: ' + method);
    }

    // TODO: other validation steps in algorithm are not implemented

    // 19. set send flag to false
    // set response body to null
    // empty list of request headers
    // set request method to given method
    // set request URL
    // set username, password
    // set asychronous flag
    _state.sendFlag = false;
    xhr.responseText = '';
    xhr.responseXML = null;

    // custom: reset status and statusText
    xhr.status = 0;
    xhr.statusText = '';

    // create the HTTP request
    _state.request = http.createRequest({
      method: method,
      path: url
    });

    // 20. set state to OPENED
    xhr.readyState = OPENED;

    // 21. dispatch onreadystatechange
    if(xhr.onreadystatechange) {
       xhr.onreadystatechange();
    }
  };

  /**
   * Adds an HTTP header field to the request.
   *
   * @param header the name of the header field.
   * @param value the value of the header field.
   */
  xhr.setRequestHeader = function(header, value) {
    // 1. if state is not OPENED or send flag is true, raise exception
    if(xhr.readyState != OPENED || _state.sendFlag) {
      throw new Error('XHR not open or sending');
    }

    // TODO: other validation steps in spec aren't implemented

    // set header
    _state.request.setField(header, value);
  };

  /**
   * Sends the request and any associated data.
   *
   * @param data a string or Document object to send, null to send no data.
   */
  xhr.send = function(data) {
    // 1. if state is not OPENED or 2. send flag is true, raise
    // an invalid state exception
    if(xhr.readyState != OPENED || _state.sendFlag) {
      throw new Error('XHR not open or sending');
    }

    // 3. ignore data if method is GET or HEAD
    if(data &&
      _state.request.method !== 'GET' &&
      _state.request.method !== 'HEAD') {
      // handle non-IE case
      if(typeof(XMLSerializer) !== 'undefined') {
        if(data instanceof Document) {
          var xs = new XMLSerializer();
          _state.request.body = xs.serializeToString(data);
        } else {
          _state.request.body = data;
        }
      } else {
        // poorly implemented IE case
        if(typeof(data.xml) !== 'undefined') {
          _state.request.body = data.xml;
        } else {
          _state.request.body = data;
        }
      }
    }

    // 4. release storage mutex (not used)

    // 5. set error flag to false
    _state.errorFlag = false;

    // 6. if asynchronous is true (must be in this implementation)

    // 6.1 set send flag to true
    _state.sendFlag = true;

    // 6.2 dispatch onreadystatechange
    if(xhr.onreadystatechange) {
      xhr.onreadystatechange();
    }

    // create send options
    var options = {};
    options.request = _state.request;
    options.headerReady = function(e) {
      // make cookies available for ease of use/iteration
      xhr.cookies = _state.client.cookies;

      // TODO: update document.cookie with any cookies where the
      // script's domain matches

      // headers received
      xhr.readyState = HEADERS_RECEIVED;
      xhr.status = e.response.code;
      xhr.statusText = e.response.message;
      _state.response = e.response;
      if(xhr.onreadystatechange) {
        xhr.onreadystatechange();
      }
      if(!_state.response.aborted) {
        // now loading body
        xhr.readyState = LOADING;
        if(xhr.onreadystatechange) {
           xhr.onreadystatechange();
        }
      }
    };
    options.bodyReady = function(e) {
      xhr.readyState = DONE;
      var ct = e.response.getField('Content-Type');
      // Note: this null/undefined check is done outside because IE
      // dies otherwise on a "'null' is null" error
      if(ct) {
        if(ct.indexOf('text/xml') === 0 ||
          ct.indexOf('application/xml') === 0 ||
          ct.indexOf('+xml') !== -1) {
          try {
            var doc = new ActiveXObject('MicrosoftXMLDOM');
            doc.async = false;
            doc.loadXML(e.response.body);
            xhr.responseXML = doc;
          } catch(ex) {
            var parser = new DOMParser();
            xhr.responseXML = parser.parseFromString(ex.body, 'text/xml');
          }
        }
      }

      var length = 0;
      if(e.response.body !== null) {
        xhr.responseText = e.response.body;
        length = e.response.body.length;
      }
      // build logging output
      var req = _state.request;
      var output =
        req.method + ' ' + req.path + ' ' +
        xhr.status + ' ' + xhr.statusText + ' ' +
        length + 'B ' +
        (e.request.connectTime + e.request.time + e.response.time) +
        'ms';
      var lFunc;
      if(options.verbose) {
        lFunc = (xhr.status >= 400 && options.logWarningOnError) ?
          _log.warning : _log.verbose;
        lFunc(cat, output,
          e, e.response.body ? '\n' + e.response.body : '\nNo content');
      } else {
        lFunc = (xhr.status >= 400 && options.logWarningOnError) ?
          _log.warning : _log.debug;
        lFunc(cat, output);
      }
      if(xhr.onreadystatechange) {
        xhr.onreadystatechange();
      }
    };
    options.error = function(e) {
      var req = _state.request;
      _log.error(cat, req.method + ' ' + req.path, e);

      // 1. set response body to null
      xhr.responseText = '';
      xhr.responseXML = null;

      // 2. set error flag to true (and reset status)
      _state.errorFlag = true;
      xhr.status = 0;
      xhr.statusText = '';

      // 3. set state to done
      xhr.readyState = DONE;

      // 4. asyc flag is always true, so dispatch onreadystatechange
      if(xhr.onreadystatechange) {
        xhr.onreadystatechange();
      }
    };

    // 7. send request
    _state.client.send(options);
  };

  /**
   * Aborts the request.
   */
  xhr.abort = function() {
    // 1. abort send
    // 2. stop network activity
    _state.request.abort();

    // 3. set response to null
    xhr.responseText = '';
    xhr.responseXML = null;

    // 4. set error flag to true (and reset status)
    _state.errorFlag = true;
    xhr.status = 0;
    xhr.statusText = '';

    // 5. clear user headers
    _state.request = null;
    _state.response = null;

    // 6. if state is DONE or UNSENT, or if OPENED and send flag is false
    if(xhr.readyState === DONE || xhr.readyState === UNSENT ||
     (xhr.readyState === OPENED && !_state.sendFlag)) {
      // 7. set ready state to unsent
      xhr.readyState = UNSENT;
    } else {
      // 6.1 set state to DONE
      xhr.readyState = DONE;

      // 6.2 set send flag to false
      _state.sendFlag = false;

      // 6.3 dispatch onreadystatechange
      if(xhr.onreadystatechange) {
        xhr.onreadystatechange();
      }

      // 7. set state to UNSENT
      xhr.readyState = UNSENT;
    }
  };

  /**
   * Gets all response headers as a string.
   *
   * @return the HTTP-encoded response header fields.
   */
  xhr.getAllResponseHeaders = function() {
    var rval = '';
    if(_state.response !== null) {
      var fields = _state.response.fields;
      $.each(fields, function(name, array) {
        $.each(array, function(i, value) {
          rval += name + ': ' + value + '\r\n';
        });
      });
    }
    return rval;
  };

  /**
   * Gets a single header field value or, if there are multiple
   * fields with the same name, a comma-separated list of header
   * values.
   *
   * @return the header field value(s) or null.
   */
  xhr.getResponseHeader = function(header) {
    var rval = null;
    if(_state.response !== null) {
      if(header in _state.response.fields) {
        rval = _state.response.fields[header];
        if(forge.util.isArray(rval)) {
          rval = rval.join();
        }
      }
    }
    return rval;
  };

  return xhr;
};

})(jQuery);

license: mit


node-forge

description: JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.

type: git

license: (BSD-3-Clause OR GPL-2.0)

keywords: aes asn asn.1 cbc crypto cryptography csr des gcm hmac http https md5 network pkcs pki prng rc2 rsa sha1 sha256 sha384 sha512 ssh tls x.509 x509

prepublish: npm run build

build: webpack

test: npm run test-node

test-node: cross-env NODE_ENV=test mocha -t 30000 -R ${REPORTER:-spec} tests/unit/index.js

test-karma: karma start

test-karma-sauce: karma start karma-sauce.conf

test-server: node tests/server.js

test-server-ws: node tests/websockets/server-ws.js

test-server-webid: node tests/websockets/server-webid.js

coverage: rm -rf coverage && nyc --reporter=lcov --reporter=text-summary npm test

coverage-ci: rm -rf coverage && nyc --reporter=lcovonly npm test

coverage-report: nyc report

lint: eslint *.js lib/*.js tests/*.js tests/**/*.js examples/*.js flash/*.js

format: amd


code:
# Node.js releases data

All data is located in `data` directory.

`data/processed` contains `envs.json` with node.js releases data preprocessed to be used by [Browserslist](https://github.com/ai/browserslist) and other projects. Each version in this file contains only necessary info: version, release date, LTS flag/name, and security flag.

`data/release-schedule` contains `release-schedule.json` with node.js releases date and end of life date.

## Installation
```bash
npm install node-releases
```


node-releases

description: Node.js releases data

type: module

build: node scripts/build.js

keywords: nodejs releases

author: Sergey Rubanov <chi187@gmail.com>

license: MIT


code:
# Names sorted by how much code was originally theirs.
Isaac Z. Schlueter <i@izs.me>
Meryn Stol <merynstol@gmail.com>
Robert Kowalski <rok@kowalski.gd>


code:
# normalize-package-data [![Build Status](https://travis-ci.org/npm/normalize-package-data.png?branch=master)](https://travis-ci.org/npm/normalize-package-data)

normalize-package-data exports a function that normalizes package metadata. This data is typically found in a package.json file, but in principle could come from any source - for example the npm registry.

normalize-package-data is used by [read-package-json](https://npmjs.org/package/read-package-json) to normalize the data it reads from a package.json file. In turn, read-package-json is used by [npm](https://npmjs.org/package/npm) and various npm-related tools.

## Installation

```
npm install normalize-package-data
```

## Usage

Basic usage is really simple. You call the function that normalize-package-data exports. Let's call it `normalizeData`.

```javascript
normalizeData = require('normalize-package-data')
packageData = require("./package.json")
normalizeData(packageData)
// packageData is now normalized
```

#### Strict mode

You may activate strict validation by passing true as the second argument.

```javascript
normalizeData = require('normalize-package-data')
packageData = require("./package.json")
normalizeData(packageData, true)
// packageData is now normalized
```

If strict mode is activated, only Semver 2.0 version strings are accepted. Otherwise, Semver 1.0 strings are accepted as well. Packages must have a name, and the name field must not have contain leading or trailing whitespace.

#### Warnings

Optionally, you may pass a "warning" function. It gets called whenever the `normalizeData` function encounters something that doesn't look right. It indicates less than perfect input data.

```javascript
normalizeData = require('normalize-package-data')
packageData = require("./package.json")
warnFn = function(msg) { console.error(msg) }
normalizeData(packageData, warnFn)
// packageData is now normalized. Any number of warnings may have been logged.
```

You may combine strict validation with warnings by passing `true` as the second argument, and `warnFn` as third.

When `private` field is set to `true`, warnings will be suppressed.

### Potential exceptions

If the supplied data has an invalid name or version vield, `normalizeData` will throw an error. Depending on where you call `normalizeData`, you may want to catch these errors so can pass them to a callback.

## What normalization (currently) entails

* The value of `name` field gets trimmed (unless in strict mode).
* The value of the `version` field gets cleaned by `semver.clean`. See [documentation for the semver module](https://github.com/isaacs/node-semver).
* If `name` and/or `version` fields are missing, they are set to empty strings.
* If `files` field is not an array, it will be removed.
* If `bin` field is a string, then `bin` field will become an object with `name` set to the value of the `name` field, and `bin` set to the original string value.
* If `man` field is a string, it will become an array with the original string as its sole member.
* If `keywords` field is string, it is considered to be a list of keywords separated by one or more white-space characters. It gets converted to an array by splitting on `\s+`.
* All people fields (`author`, `maintainers`, `contributors`) get converted into objects with name, email and url properties.
* If `bundledDependencies` field (a typo) exists and `bundleDependencies` field does not, `bundledDependencies` will get renamed to `bundleDependencies`.
* If the value of any of the dependencies fields  (`dependencies`, `devDependencies`, `optionalDependencies`) is a string, it gets converted into an object with familiar `name=>value` pairs.
* The values in `optionalDependencies` get added to `dependencies`. The `optionalDependencies` array is left untouched.
* As of v2: Dependencies that point at known hosted git providers (currently: github, bitbucket, gitlab) will have their URLs canonicalized, but protocols will be preserved.
* As of v2: Dependencies that use shortcuts for hosted git providers (`org/proj`, `github:org/proj`, `bitbucket:org/proj`, `gitlab:org/proj`, `gist:docid`) will have the shortcut left in place. (In the case of github, the `org/proj` form will be expanded to `github:org/proj`.) THIS MARKS A BREAKING CHANGE FROM V1, where the shorcut was previously expanded to a URL.
* If `description` field does not exist, but `readme` field does, then (more or less) the first paragraph of text that's found in the readme is taken as value for `description`.
* If `repository` field is a string, it will become an object with `url` set to the original string value, and `type` set to `"git"`.
* If `repository.url` is not a valid url, but in the style of "[owner-name]/[repo-name]", `repository.url` will be set to git+https://github.com/[owner-name]/[repo-name].git
* If `bugs` field is a string, the value of `bugs` field is changed into an object with `url` set to the original string value.
* If `bugs` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `bugs` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]/issues . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.
* If `bugs` field is an object, the resulting value only has email and url properties. If email and url properties are not strings, they are ignored. If no valid values for either email or url is found, bugs field will be removed.
* If `homepage` field is not a string, it will be removed.
* If the url in the `homepage` field does not specify a protocol, then http is assumed. For example, `myproject.org` will be changed to `http://myproject.org`.
* If `homepage` field does not exist, but `repository` field points to a repository hosted on GitHub, the value of the `homepage` field gets set to an url in the form of https://github.com/[owner-name]/[repo-name]#readme . If the repository field points to a GitHub Gist repo url, the associated http url is chosen.

### Rules for name field

If `name` field is given, the value of the name field must be a string. The string may not:

* start with a period.
* contain the following characters: `/@\s+%`
* contain any characters that would need to be encoded for use in urls.
* resemble the word `node_modules` or `favicon.ico` (case doesn't matter).

### Rules for version field

If `version` field is given, the value of the version field must be a valid *semver* string, as determined by the `semver.valid` method. See [documentation for the semver module](https://github.com/isaacs/node-semver).

### Rules for license field

The `license` field should be a valid *SPDX license expression* or one of the special values allowed by [validate-npm-package-license](https://npmjs.com/package/validate-npm-package-license). See [documentation for the license field in package.json](https://docs.npmjs.com/files/package.json#license).

## Credits

This package contains code based on read-package-json written by Isaac Z. Schlueter. Used with permisson.

## License

normalize-package-data is released under the [BSD 2-Clause License](http://opensource.org/licenses/MIT).
Copyright (c) 2013 Meryn Stol


code:
module.exports = extractDescription

// Extracts description from contents of a readme file in markdown format
function extractDescription (d) {
  if (!d) return;
  if (d === "ERROR: No README data found!") return;
  // the first block of text before the first heading
  // that isn't the first line heading
  d = d.trim().split('\n')
  for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++);
  var l = d.length
  for (var e = s + 1; e < l && d[e].trim(); e ++);
  return d.slice(s, e).join(' ').trim()
}


code:
var semver = require("semver")
var validateLicense = require('validate-npm-package-license');
var hostedGitInfo = require("hosted-git-info")
var isBuiltinModule = require("resolve").isCore
var depTypes = ["dependencies","devDependencies","optionalDependencies"]
var extractDescription = require("./extract_description")
var url = require("url")
var typos = require("./typos.json")

var fixer = module.exports = {
  // default warning function
  warn: function() {},

  fixRepositoryField: function(data) {
    if (data.repositories) {
      this.warn("repositories");
      data.repository = data.repositories[0]
    }
    if (!data.repository) return this.warn("missingRepository")
    if (typeof data.repository === "string") {
      data.repository = {
        type: "git",
        url: data.repository
      }
    }
    var r = data.repository.url || ""
    if (r) {
      var hosted = hostedGitInfo.fromUrl(r)
      if (hosted) {
        r = data.repository.url
          = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString()
      }
    }

    if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) {
      this.warn("brokenGitUrl", r)
    }
  }

, fixTypos: function(data) {
    Object.keys(typos.topLevel).forEach(function (d) {
      if (data.hasOwnProperty(d)) {
        this.warn("typo", d, typos.topLevel[d])
      }
    }, this)
  }

, fixScriptsField: function(data) {
    if (!data.scripts) return
    if (typeof data.scripts !== "object") {
      this.warn("nonObjectScripts")
      delete data.scripts
      return
    }
    Object.keys(data.scripts).forEach(function (k) {
      if (typeof data.scripts[k] !== "string") {
        this.warn("nonStringScript")
        delete data.scripts[k]
      } else if (typos.script[k] && !data.scripts[typos.script[k]]) {
        this.warn("typo", k, typos.script[k], "scripts")
      }
    }, this)
  }

, fixFilesField: function(data) {
    var files = data.files
    if (files && !Array.isArray(files)) {
      this.warn("nonArrayFiles")
      delete data.files
    } else if (data.files) {
      data.files = data.files.filter(function(file) {
        if (!file || typeof file !== "string") {
          this.warn("invalidFilename", file)
          return false
        } else {
          return true
        }
      }, this)
    }
  }

, fixBinField: function(data) {
    if (!data.bin) return;
    if (typeof data.bin === "string") {
      var b = {}
      var match
      if (match = data.name.match(/^@[^/]+[/](.*)$/)) {
        b[match[1]] = data.bin
      } else {
        b[data.name] = data.bin
      }
      data.bin = b
    }
  }

, fixManField: function(data) {
    if (!data.man) return;
    if (typeof data.man === "string") {
      data.man = [ data.man ]
    }
  }
, fixBundleDependenciesField: function(data) {
    var bdd = "bundledDependencies"
    var bd = "bundleDependencies"
    if (data[bdd] && !data[bd]) {
      data[bd] = data[bdd]
      delete data[bdd]
    }
    if (data[bd] && !Array.isArray(data[bd])) {
      this.warn("nonArrayBundleDependencies")
      delete data[bd]
    } else if (data[bd]) {
      data[bd] = data[bd].filter(function(bd) {
        if (!bd || typeof bd !== 'string') {
          this.warn("nonStringBundleDependency", bd)
          return false
        } else {
          if (!data.dependencies) {
            data.dependencies = {}
          }
          if (!data.dependencies.hasOwnProperty(bd)) {
            this.warn("nonDependencyBundleDependency", bd)
            data.dependencies[bd] = "*"
          }
          return true
        }
      }, this)
    }
  }

, fixDependencies: function(data, strict) {
    var loose = !strict
    objectifyDeps(data, this.warn)
    addOptionalDepsToDeps(data, this.warn)
    this.fixBundleDependenciesField(data)

    ;['dependencies','devDependencies'].forEach(function(deps) {
      if (!(deps in data)) return
      if (!data[deps] || typeof data[deps] !== "object") {
        this.warn("nonObjectDependencies", deps)
        delete data[deps]
        return
      }
      Object.keys(data[deps]).forEach(function (d) {
        var r = data[deps][d]
        if (typeof r !== 'string') {
          this.warn("nonStringDependency", d, JSON.stringify(r))
          delete data[deps][d]
        }
        var hosted = hostedGitInfo.fromUrl(data[deps][d])
        if (hosted) data[deps][d] = hosted.toString()
      }, this)
    }, this)
  }

, fixModulesField: function (data) {
    if (data.modules) {
      this.warn("deprecatedModules")
      delete data.modules
    }
  }

, fixKeywordsField: function (data) {
    if (typeof data.keywords === "string") {
      data.keywords = data.keywords.split(/,\s+/)
    }
    if (data.keywords && !Array.isArray(data.keywords)) {
      delete data.keywords
      this.warn("nonArrayKeywords")
    } else if (data.keywords) {
      data.keywords = data.keywords.filter(function(kw) {
        if (typeof kw !== "string" || !kw) {
          this.warn("nonStringKeyword");
          return false
        } else {
          return true
        }
      }, this)
    }
  }

, fixVersionField: function(data, strict) {
    // allow "loose" semver 1.0 versions in non-strict mode
    // enforce strict semver 2.0 compliance in strict mode
    var loose = !strict
    if (!data.version) {
      data.version = ""
      return true
    }
    if (!semver.valid(data.version, loose)) {
      throw new Error('Invalid version: "'+ data.version + '"')
    }
    data.version = semver.clean(data.version, loose)
    return true
  }

, fixPeople: function(data) {
    modifyPeople(data, unParsePerson)
    modifyPeople(data, parsePerson)
  }

, fixNameField: function(data, options) {
    if (typeof options === "boolean") options = {strict: options}
    else if (typeof options === "undefined") options = {}
    var strict = options.strict
    if (!data.name && !strict) {
      data.name = ""
      return
    }
    if (typeof data.name !== "string") {
      throw new Error("name field must be a string.")
    }
    if (!strict)
      data.name = data.name.trim()
    ensureValidName(data.name, strict, options.allowLegacyCase)
    if (isBuiltinModule(data.name))
      this.warn("conflictingName", data.name)
  }

, fixDescriptionField: function (data) {
    if (data.description && typeof data.description !== 'string') {
      this.warn("nonStringDescription")
      delete data.description
    }
    if (data.readme && !data.description)
      data.description = extractDescription(data.readme)
      if(data.description === undefined) delete data.description;
    if (!data.description) this.warn("missingDescription")
  }

, fixReadmeField: function (data) {
    if (!data.readme) {
      this.warn("missingReadme")
      data.readme = "ERROR: No README data found!"
    }
  }

, fixBugsField: function(data) {
    if (!data.bugs && data.repository && data.repository.url) {
      var hosted = hostedGitInfo.fromUrl(data.repository.url)
      if(hosted && hosted.bugs()) {
        data.bugs = {url: hosted.bugs()}
      }
    }
    else if(data.bugs) {
      var emailRe = /^.+@.*\..+$/
      if(typeof data.bugs == "string") {
        if(emailRe.test(data.bugs))
          data.bugs = {email:data.bugs}
        else if(url.parse(data.bugs).protocol)
          data.bugs = {url: data.bugs}
        else
          this.warn("nonEmailUrlBugsString")
      }
      else {
        bugsTypos(data.bugs, this.warn)
        var oldBugs = data.bugs
        data.bugs = {}
        if(oldBugs.url) {
          if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol)
            data.bugs.url = oldBugs.url
          else
            this.warn("nonUrlBugsUrlField")
        }
        if(oldBugs.email) {
          if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email))
            data.bugs.email = oldBugs.email
          else
            this.warn("nonEmailBugsEmailField")
        }
      }
      if(!data.bugs.email && !data.bugs.url) {
        delete data.bugs
        this.warn("emptyNormalizedBugs")
      }
    }
  }

, fixHomepageField: function(data) {
    if (!data.homepage && data.repository && data.repository.url) {
      var hosted = hostedGitInfo.fromUrl(data.repository.url)
      if (hosted && hosted.docs()) data.homepage = hosted.docs()
    }
    if (!data.homepage) return

    if(typeof data.homepage !== "string") {
      this.warn("nonUrlHomepage")
      return delete data.homepage
    }
    if(!url.parse(data.homepage).protocol) {
      data.homepage = "http://" + data.homepage
    }
  }

, fixLicenseField: function(data) {
    if (!data.license) {
      return this.warn("missingLicense")
    } else{
      if (
        typeof(data.license) !== 'string' ||
        data.license.length < 1 ||
        data.license.trim() === ''
      ) {
        this.warn("invalidLicense")
      } else {
        if (!validateLicense(data.license).validForNewPackages)
          this.warn("invalidLicense")
      }
    }
  }
}

function isValidScopedPackageName(spec) {
  if (spec.charAt(0) !== '@') return false

  var rest = spec.slice(1).split('/')
  if (rest.length !== 2) return false

  return rest[0] && rest[1] &&
    rest[0] === encodeURIComponent(rest[0]) &&
    rest[1] === encodeURIComponent(rest[1])
}

function isCorrectlyEncodedName(spec) {
  return !spec.match(/[\/@\s\+%:]/) &&
    spec === encodeURIComponent(spec)
}

function ensureValidName (name, strict, allowLegacyCase) {
  if (name.charAt(0) === "." ||
      !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) ||
      (strict && (!allowLegacyCase) && name !== name.toLowerCase()) ||
      name.toLowerCase() === "node_modules" ||
      name.toLowerCase() === "favicon.ico") {
        throw new Error("Invalid name: " + JSON.stringify(name))
  }
}

function modifyPeople (data, fn) {
  if (data.author) data.author = fn(data.author)
  ;["maintainers", "contributors"].forEach(function (set) {
    if (!Array.isArray(data[set])) return;
    data[set] = data[set].map(fn)
  })
  return data
}

function unParsePerson (person) {
  if (typeof person === "string") return person
  var name = person.name || ""
  var u = person.url || person.web
  var url = u ? (" ("+u+")") : ""
  var e = person.email || person.mail
  var email = e ? (" <"+e+">") : ""
  return name+email+url
}

function parsePerson (person) {
  if (typeof person !== "string") return person
  var name = person.match(/^([^\(<]+)/)
  var url = person.match(/\(([^\)]+)\)/)
  var email = person.match(/<([^>]+)>/)
  var obj = {}
  if (name && name[0].trim()) obj.name = name[0].trim()
  if (email) obj.email = email[1];
  if (url) obj.url = url[1];
  return obj
}

function addOptionalDepsToDeps (data, warn) {
  var o = data.optionalDependencies
  if (!o) return;
  var d = data.dependencies || {}
  Object.keys(o).forEach(function (k) {
    d[k] = o[k]
  })
  data.dependencies = d
}

function depObjectify (deps, type, warn) {
  if (!deps) return {}
  if (typeof deps === "string") {
    deps = deps.trim().split(/[\n\r\s\t ,]+/)
  }
  if (!Array.isArray(deps)) return deps
  warn("deprecatedArrayDependencies", type)
  var o = {}
  deps.filter(function (d) {
    return typeof d === "string"
  }).forEach(function(d) {
    d = d.trim().split(/(:?[@\s><=])/)
    var dn = d.shift()
    var dv = d.join("")
    dv = dv.trim()
    dv = dv.replace(/^@/, "")
    o[dn] = dv
  })
  return o
}

function objectifyDeps (data, warn) {
  depTypes.forEach(function (type) {
    if (!data[type]) return;
    data[type] = depObjectify(data[type], type, warn)
  })
}

function bugsTypos(bugs, warn) {
  if (!bugs) return
  Object.keys(bugs).forEach(function (k) {
    if (typos.bugs[k]) {
      warn("typo", k, typos.bugs[k], "bugs")
      bugs[typos.bugs[k]] = bugs[k]
      delete bugs[k]
    }
  })
}


code:
var util = require("util")
var messages = require("./warning_messages.json")

module.exports = function() {
  var args = Array.prototype.slice.call(arguments, 0)
  var warningName = args.shift()
  if (warningName == "typo") {
    return makeTypoWarning.apply(null,args)
  }
  else {
    var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'"
    args.unshift(msgTemplate)
    return util.format.apply(null, args)
  }
}

function makeTypoWarning (providedName, probableName, field) {
  if (field) {
    providedName = field + "['" + providedName + "']"
    probableName = field + "['" + probableName + "']"
  }
  return util.format(messages.typo, providedName, probableName)
}


code:
module.exports = normalize

var fixer = require("./fixer")
normalize.fixer = fixer

var makeWarning = require("./make_warning")

var fieldsToFix = ['name','version','description','repository','modules','scripts'
                  ,'files','bin','man','bugs','keywords','readme','homepage','license']
var otherThingsToFix = ['dependencies','people', 'typos']

var thingsToFix = fieldsToFix.map(function(fieldName) {
  return ucFirst(fieldName) + "Field"
})
// two ways to do this in CoffeeScript on only one line, sub-70 chars:
// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field"
// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix)
thingsToFix = thingsToFix.concat(otherThingsToFix)

function normalize (data, warn, strict) {
  if(warn === true) warn = null, strict = true
  if(!strict) strict = false
  if(!warn || data.private) warn = function(msg) { /* noop */ }

  if (data.scripts &&
      data.scripts.install === "node-gyp rebuild" &&
      !data.scripts.preinstall) {
    data.gypfile = true
  }
  fixer.warn = function() { warn(makeWarning.apply(null, arguments)) }
  thingsToFix.forEach(function(thingName) {
    fixer["fix" + ucFirst(thingName)](data, strict)
  })
  data._id = data.name + "@" + data.version
}

function ucFirst (string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}


code:
var util = require('util')

module.exports = function() {
  var args = Array.prototype.slice.call(arguments, 0)
  args.forEach(function(arg) {
    if (!arg) throw new TypeError('Bad arguments.')
  })
  return util.format.apply(null, arguments)
}


dependancies: dependencies

dependecies: dependencies

depdenencies: dependencies

devEependencies: devDependencies

depends: dependencies

dev-dependencies: devDependencies

devDependences: devDependencies

devDepenencies: devDependencies

devdependencies: devDependencies

repostitory: repository

repo: repository

prefereGlobal: preferGlobal

hompage: homepage

hampage: homepage

autohr: author

autor: author

contributers: contributors

publicationConfig: publishConfig

script: scripts

url

web: url

server: start

tests: test


repositories: 'repositories' (plural) Not supported. Please pick one as the 'repository' field

missingRepository: No repository field.

brokenGitUrl: Probably broken git url: %s

nonObjectScripts: scripts must be an object

nonStringScript: script values must be string commands

nonArrayFiles: Invalid 'files' member

invalidFilename: Invalid filename in 'files' list: %s

nonArrayBundleDependencies: Invalid 'bundleDependencies' list. Must be array of package names

nonStringBundleDependency: Invalid bundleDependencies member: %s

nonDependencyBundleDependency: Non-dependency in bundleDependencies: %s

nonObjectDependencies: %s field must be an object

nonStringDependency: Invalid dependency: %s %s

deprecatedArrayDependencies: specifying %s as array is deprecated

deprecatedModules: modules field is deprecated

nonArrayKeywords: keywords should be an array of strings

nonStringKeyword: keywords should be an array of strings

conflictingName: %s is also the name of a node core module.

nonStringDescription: 'description' field should be a string

missingDescription: No description

missingReadme: No README data

missingLicense: No license field.

nonEmailUrlBugsString: Bug string field must be url, email, or {email,url}

nonUrlBugsUrlField: bugs.url field must be a string url. Deleted.

nonEmailBugsEmailField: bugs.email field must be a string email. Deleted.

emptyNormalizedBugs: Normalized value of bugs field is an empty object. Deleted.

nonUrlHomepage: homepage field must be a string url. Deleted.

invalidLicense: license should be a valid SPDX license expression

typo: %s should probably be %s.


code:
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  exec "$basedir/node"  "$basedir/../semver/bin/semver" "$@"
else
  exec node  "$basedir/../semver/bin/semver" "$@"
fi


code:
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0

IF EXIST "%dp0%\node.exe" (
  SET "_prog=%dp0%\node.exe"
) ELSE (
  SET "_prog=node"
  SET PATHEXT=%PATHEXT:;.JS;=;%
)

endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%"  "%dp0%\..\semver\bin\semver" %*


code:
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent

$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
  # Fix case when both the Windows and Linux builds of Node
  # are installed in the same directory
  $exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "$basedir/node$exe"  "$basedir/../semver/bin/semver" $args
  } else {
    & "$basedir/node$exe"  "$basedir/../semver/bin/semver" $args
  }
  $ret=$LASTEXITCODE
} else {
  # Support pipeline input
  if ($MyInvocation.ExpectingInput) {
    $input | & "node$exe"  "$basedir/../semver/bin/semver" $args
  } else {
    & "node$exe"  "$basedir/../semver/bin/semver" $args
  }
  $ret=$LASTEXITCODE
}
exit $ret


code:
semver(1) -- The semantic versioner for npm
===========================================

## Install

```bash
npm install --save semver
````

## Usage

As a node module:

```js
const semver = require('semver')

semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean('  =v1.2.3   ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
semver.minVersion('>=1.0.0') // '1.0.0'
semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
```

As a command-line utility:

```
$ semver -h

A JavaScript implementation of the https://semver.org/ specification
Copyright Isaac Z. Schlueter

Usage: semver [options] <version> [<version> [...]]
Prints valid versions sorted by SemVer precedence

Options:
-r --range <range>
        Print versions that match the specified range.

-i --increment [<level>]
        Increment a version by the specified level.  Level can
        be one of: major, minor, patch, premajor, preminor,
        prepatch, or prerelease.  Default level is 'patch'.
        Only one version may be specified.

--preid <identifier>
        Identifier to be used to prefix premajor, preminor,
        prepatch or prerelease version increments.

-l --loose
        Interpret versions and ranges loosely

-p --include-prerelease
        Always include prerelease versions in range matching

-c --coerce
        Coerce a string into SemVer if possible
        (does not imply --loose)

Program exits successfully if any valid version satisfies
all supplied ranges, and prints all satisfying versions.

If no satisfying versions are found, then exits failure.

Versions are printed in ascending order, so supplying
multiple versions to the utility will just sort them.
```

## Versions

A "version" is described by the `v2.0.0` specification found at
<https://semver.org/>.

A leading `"="` or `"v"` character is stripped off and ignored.

## Ranges

A `version range` is a set of `comparators` which specify versions
that satisfy the range.

A `comparator` is composed of an `operator` and a `version`.  The set
of primitive `operators` is:

* `<` Less than
* `<=` Less than or equal to
* `>` Greater than
* `>=` Greater than or equal to
* `=` Equal.  If no operator is specified, then equality is assumed,
  so this operator is optional, but MAY be included.

For example, the comparator `>=1.2.7` would match the versions
`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6`
or `1.1.0`.

Comparators can be joined by whitespace to form a `comparator set`,
which is satisfied by the **intersection** of all of the comparators
it includes.

A range is composed of one or more comparator sets, joined by `||`.  A
version matches a range if and only if every comparator in at least
one of the `||`-separated comparator sets is satisfied by the version.

For example, the range `>=1.2.7 <1.3.0` would match the versions
`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`,
or `1.1.0`.

The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`,
`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`.

### Prerelease Tags

If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then
it will only be allowed to satisfy comparator sets if at least one
comparator with the same `[major, minor, patch]` tuple also has a
prerelease tag.

For example, the range `>1.2.3-alpha.3` would be allowed to match the
version `1.2.3-alpha.7`, but it would *not* be satisfied by
`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater
than" `1.2.3-alpha.3` according to the SemVer sort rules.  The version
range only accepts prerelease tags on the `1.2.3` version.  The
version `3.4.5` *would* satisfy the range, because it does not have a
prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`.

The purpose for this behavior is twofold.  First, prerelease versions
frequently are updated very quickly, and contain many breaking changes
that are (by the author's design) not yet fit for public consumption.
Therefore, by default, they are excluded from range matching
semantics.

Second, a user who has opted into using a prerelease version has
clearly indicated the intent to use *that specific* set of
alpha/beta/rc versions.  By including a prerelease tag in the range,
the user is indicating that they are aware of the risk.  However, it
is still not appropriate to assume that they have opted into taking a
similar risk on the *next* set of prerelease versions.

Note that this behavior can be suppressed (treating all prerelease
versions as if they were normal versions, for the purpose of range
matching) by setting the `includePrerelease` flag on the options
object to any
[functions](https://github.com/npm/node-semver#functions) that do
range matching.

#### Prerelease Identifiers

The method `.inc` takes an additional `identifier` string argument that
will append the value of the string as a prerelease identifier:

```javascript
semver.inc('1.2.3', 'prerelease', 'beta')
// '1.2.4-beta.0'
```

command-line example:

```bash
$ semver 1.2.3 -i prerelease --preid beta
1.2.4-beta.0
```

Which then can be used to increment further:

```bash
$ semver 1.2.4-beta.0 -i prerelease
1.2.4-beta.1
```

### Advanced Range Syntax

Advanced range syntax desugars to primitive comparators in
deterministic ways.

Advanced ranges may be combined in the same way as primitive
comparators using white space or `||`.

#### Hyphen Ranges `X.Y.Z - A.B.C`

Specifies an inclusive set.

* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`

If a partial version is provided as the first version in the inclusive
range, then the missing pieces are replaced with zeroes.

* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4`

If a partial version is provided as the second version in the
inclusive range, then all versions that start with the supplied parts
of the tuple are accepted, but nothing that would be greater than the
provided tuple parts.

* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0`
* `1.2.3 - 2` := `>=1.2.3 <3.0.0`

#### X-Ranges `1.2.x` `1.X` `1.2.*` `*`

Any of `X`, `x`, or `*` may be used to "stand in" for one of the
numeric values in the `[major, minor, patch]` tuple.

* `*` := `>=0.0.0` (Any version satisfies)
* `1.x` := `>=1.0.0 <2.0.0` (Matching major version)
* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions)

A partial version range is treated as an X-Range, so the special
character is in fact optional.

* `""` (empty string) := `*` := `>=0.0.0`
* `1` := `1.x.x` := `>=1.0.0 <2.0.0`
* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0`

#### Tilde Ranges `~1.2.3` `~1.2` `~1`

Allows patch-level changes if a minor version is specified on the
comparator.  Allows minor-level changes if not.

* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0`
* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`)
* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`)
* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0`
* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`)
* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`)
* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in
  the `1.2.3` version will be allowed, if they are greater than or
  equal to `beta.2`.  So, `1.2.3-beta.4` would be allowed, but
  `1.2.4-beta.2` would not, because it is a prerelease of a
  different `[major, minor, patch]` tuple.

#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4`

Allows changes that do not modify the left-most non-zero digit in the
`[major, minor, patch]` tuple.  In other words, this allows patch and
minor updates for versions `1.0.0` and above, patch updates for
versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`.

Many authors treat a `0.x` version as if the `x` were the major
"breaking-change" indicator.

Caret ranges are ideal when an author may make breaking changes
between `0.2.4` and `0.3.0` releases, which is a common practice.
However, it presumes that there will *not* be breaking changes between
`0.2.4` and `0.2.5`.  It allows for changes that are presumed to be
additive (but non-breaking), according to commonly observed practices.

* `^1.2.3` := `>=1.2.3 <2.0.0`
* `^0.2.3` := `>=0.2.3 <0.3.0`
* `^0.0.3` := `>=0.0.3 <0.0.4`
* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in
  the `1.2.3` version will be allowed, if they are greater than or
  equal to `beta.2`.  So, `1.2.3-beta.4` would be allowed, but
  `1.2.4-beta.2` would not, because it is a prerelease of a
  different `[major, minor, patch]` tuple.
* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4`  Note that prereleases in the
  `0.0.3` version *only* will be allowed, if they are greater than or
  equal to `beta`.  So, `0.0.3-pr.2` would be allowed.

When parsing caret ranges, a missing `patch` value desugars to the
number `0`, but will allow flexibility within that value, even if the
major and minor versions are both `0`.

* `^1.2.x` := `>=1.2.0 <2.0.0`
* `^0.0.x` := `>=0.0.0 <0.1.0`
* `^0.0` := `>=0.0.0 <0.1.0`

A missing `minor` and `patch` values will desugar to zero, but also
allow flexibility within those values, even if the major version is
zero.

* `^1.x` := `>=1.0.0 <2.0.0`
* `^0.x` := `>=0.0.0 <1.0.0`

### Range Grammar

Putting all this together, here is a Backus-Naur grammar for ranges,
for the benefit of parser authors:

```bnf
range-set  ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range      ::= hyphen | simple ( ' ' simple ) * | ''
hyphen     ::= partial ' - ' partial
simple     ::= primitive | partial | tilde | caret
primitive  ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial    ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr         ::= 'x' | 'X' | '*' | nr
nr         ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
tilde      ::= '~' partial
caret      ::= '^' partial
qualifier  ::= ( '-' pre )? ( '+' build )?
pre        ::= parts
build      ::= parts
parts      ::= part ( '.' part ) *
part       ::= nr | [-0-9A-Za-z]+
```

## Functions

All methods and classes take a final `options` object argument.  All
options in this object are `false` by default.  The options supported
are:

- `loose`  Be more forgiving about not-quite-valid semver strings.
  (Any resulting output will always be 100% strict compliant, of
  course.)  For backwards compatibility reasons, if the `options`
  argument is a boolean value instead of an object, it is interpreted
  to be the `loose` param.
- `includePrerelease`  Set to suppress the [default
  behavior](https://github.com/npm/node-semver#prerelease-tags) of
  excluding prerelease tagged versions from ranges unless they are
  explicitly opted into.

Strict-mode Comparators and Ranges will be strict about the SemVer
strings that they parse.

* `valid(v)`: Return the parsed version, or null if it's not valid.
* `inc(v, release)`: Return the version incremented by the release
  type (`major`,   `premajor`, `minor`, `preminor`, `patch`,
  `prepatch`, or `prerelease`), or null if it's not valid
  * `premajor` in one call will bump the version up to the next major
    version and down to a prerelease of that major version.
    `preminor`, and `prepatch` work the same way.
  * If called from a non-prerelease version, the `prerelease` will work the
    same as `prepatch`. It increments the patch version, then makes a
    prerelease. If the input version is already a prerelease it simply
    increments it.
* `prerelease(v)`: Returns an array of prerelease components, or null
  if none exist. Example: `prerelease('1.2.3-alpha.1') -> ['alpha', 1]`
* `major(v)`: Return the major version number.
* `minor(v)`: Return the minor version number.
* `patch(v)`: Return the patch version number.
* `intersects(r1, r2, loose)`: Return true if the two supplied ranges
  or comparators intersect.
* `parse(v)`: Attempt to parse a string as a semantic version, returning either
  a `SemVer` object or `null`.

### Comparison

* `gt(v1, v2)`: `v1 > v2`
* `gte(v1, v2)`: `v1 >= v2`
* `lt(v1, v2)`: `v1 < v2`
* `lte(v1, v2)`: `v1 <= v2`
* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent,
  even if they're not the exact same string.  You already know how to
  compare strings.
* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`.
* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call
  the corresponding function above.  `"==="` and `"!=="` do simple
  string comparison, but are included for completeness.  Throws if an
  invalid comparison string is provided.
* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if
  `v2` is greater.  Sorts in ascending order if passed to `Array.sort()`.
* `rcompare(v1, v2)`: The reverse of compare.  Sorts an array of versions
  in descending order when passed to `Array.sort()`.
* `diff(v1, v2)`: Returns difference between two versions by the release type
  (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`),
  or null if the versions are the same.

### Comparators

* `intersects(comparator)`: Return true if the comparators intersect

### Ranges

* `validRange(range)`: Return the valid range or null if it's not valid
* `satisfies(version, range)`: Return true if the version satisfies the
  range.
* `maxSatisfying(versions, range)`: Return the highest version in the list
  that satisfies the range, or `null` if none of them do.
* `minSatisfying(versions, range)`: Return the lowest version in the list
  that satisfies the range, or `null` if none of them do.
* `minVersion(range)`: Return the lowest version that can possibly match
  the given range.
* `gtr(version, range)`: Return `true` if version is greater than all the
  versions possible in the range.
* `ltr(version, range)`: Return `true` if version is less than all the
  versions possible in the range.
* `outside(version, range, hilo)`: Return true if the version is outside
  the bounds of the range in either the high or low direction.  The
  `hilo` argument must be either the string `'>'` or `'<'`.  (This is
  the function called by `gtr` and `ltr`.)
* `intersects(range)`: Return true if any of the ranges comparators intersect

Note that, since ranges may be non-contiguous, a version might not be
greater than a range, less than a range, *or* satisfy a range!  For
example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9`
until `2.0.0`, so the version `1.2.10` would not be greater than the
range (because `2.0.1` satisfies, which is higher), nor less than the
range (since `1.2.8` satisfies, which is lower), and it also does not
satisfy the range.

If you want to know if a version satisfies or does not satisfy a
range, use the `satisfies(version, range)` function.

### Coercion

* `coerce(version)`: Coerces a string to semver if possible

This aims to provide a very forgiving translation of a non-semver string to
semver. It looks for the first digit in a string, and consumes all
remaining characters which satisfy at least a partial semver (e.g., `1`,
`1.2`, `1.2.3`) up to the max permitted length (256 characters).  Longer
versions are simply truncated (`4.6.3.9.2-alpha2` becomes `4.6.3`).  All
surrounding text is simply ignored (`v3.4 replaces v3.3.1` becomes
`3.4.0`).  Only text which lacks digits will fail coercion (`version one`
is not valid).  The maximum  length for any semver component considered for
coercion is 16 characters; longer components will be ignored
(`10000000000000000.4.7.4` becomes `4.7.4`).  The maximum value for any
semver component is `Number.MAX_SAFE_INTEGER || (2**53 - 1)`; higher value
components are invalid (`9999999999999999.4.7.4` is likely invalid).


code:
#!/usr/bin/env node
// Standalone semver comparison program.
// Exits successfully and prints matching version(s) if
// any supplied version is valid and passes all tests.

var argv = process.argv.slice(2)

var versions = []

var range = []

var inc = null

var version = require('../package.json').version

var loose = false

var includePrerelease = false

var coerce = false

var identifier

var semver = require('../semver')

var reverse = false

var options = {}

main()

function main () {
  if (!argv.length) return help()
  while (argv.length) {
    var a = argv.shift()
    var indexOfEqualSign = a.indexOf('=')
    if (indexOfEqualSign !== -1) {
      a = a.slice(0, indexOfEqualSign)
      argv.unshift(a.slice(indexOfEqualSign + 1))
    }
    switch (a) {
      case '-rv': case '-rev': case '--rev': case '--reverse':
        reverse = true
        break
      case '-l': case '--loose':
        loose = true
        break
      case '-p': case '--include-prerelease':
        includePrerelease = true
        break
      case '-v': case '--version':
        versions.push(argv.shift())
        break
      case '-i': case '--inc': case '--increment':
        switch (argv[0]) {
          case 'major': case 'minor': case 'patch': case 'prerelease':
          case 'premajor': case 'preminor': case 'prepatch':
            inc = argv.shift()
            break
          default:
            inc = 'patch'
            break
        }
        break
      case '--preid':
        identifier = argv.shift()
        break
      case '-r': case '--range':
        range.push(argv.shift())
        break
      case '-c': case '--coerce':
        coerce = true
        break
      case '-h': case '--help': case '-?':
        return help()
      default:
        versions.push(a)
        break
    }
  }

  var options = { loose: loose, includePrerelease: includePrerelease }

  versions = versions.map(function (v) {
    return coerce ? (semver.coerce(v) || { version: v }).version : v
  }).filter(function (v) {
    return semver.valid(v)
  })
  if (!versions.length) return fail()
  if (inc && (versions.length !== 1 || range.length)) { return failInc() }

  for (var i = 0, l = range.length; i < l; i++) {
    versions = versions.filter(function (v) {
      return semver.satisfies(v, range[i], options)
    })
    if (!versions.length) return fail()
  }
  return success(versions)
}

function failInc () {
  console.error('--inc can only be used on a single version with no range')
  fail()
}

function fail () { process.exit(1) }

function success () {
  var compare = reverse ? 'rcompare' : 'compare'
  versions.sort(function (a, b) {
    return semver[compare](a, b, options)
  }).map(function (v) {
    return semver.clean(v, options)
  }).map(function (v) {
    return inc ? semver.inc(v, inc, options, identifier) : v
  }).forEach(function (v, i, _) { console.log(v) })
}

function help () {
  console.log(['SemVer ' + version,
    '',
    'A JavaScript implementation of the https://semver.org/ specification',
    'Copyright Isaac Z. Schlueter',
    '',
    'Usage: semver [options] <version> [<version> [...]]',
    'Prints valid versions sorted by SemVer precedence',
    '',
    'Options:',
    '-r --range <range>',
    '        Print versions that match the specified range.',
    '',
    '-i --increment [<level>]',
    '        Increment a version by the specified level.  Level can',
    '        be one of: major, minor, patch, premajor, preminor,',
    "        prepatch, or prerelease.  Default level is 'patch'.",
    '        Only one version may be specified.',
    '',
    '--preid <identifier>',
    '        Identifier to be used to prefix premajor, preminor,',
    '        prepatch or prerelease version increments.',
    '',
    '-l --loose',
    '        Interpret versions and ranges loosely',
    '',
    '-p --include-prerelease',
    '        Always include prerelease versions in range matching',
    '',
    '-c --coerce',
    '        Coerce a string into SemVer if possible',
    '        (does not imply --loose)',
    '',
    'Program exits successfully if any valid version satisfies',
    'all supplied ranges, and prints all satisfying versions.',
    '',
    'If no satisfying versions are found, then exits failure.',
    '',
    'Versions are printed in ascending order, so supplying',
    'multiple versions to the utility will just sort them.'
  ].join('\n'))
}


semver

description: The semantic version parser used by npm.

test: tap test/ --100 --timeout=30

lint: echo linting disabled

postlint: template-oss-check

template-oss-apply: template-oss-apply --force

lintfix: npm run lint -- --fix

snap: tap test/ --100 --timeout=30

posttest: npm run lint

license: ISC

author: GitHub Inc.

//@npmcli/template-oss: This file is partially managed by @npmcli/template-oss. Edits may be overwritten.


code:
range-set  ::= range ( logical-or range ) *
logical-or ::= ( ' ' ) * '||' ( ' ' ) *
range      ::= hyphen | simple ( ' ' simple ) * | ''
hyphen     ::= partial ' - ' partial
simple     ::= primitive | partial | tilde | caret
primitive  ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
partial    ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
xr         ::= 'x' | 'X' | '*' | nr
nr         ::= '0' | [1-9] ( [0-9] ) *
tilde      ::= '~' partial
caret      ::= '^' partial
qualifier  ::= ( '-' pre )? ( '+' build )?
pre        ::= parts
build      ::= parts
parts      ::= part ( '.' part ) *
part       ::= nr | [-0-9A-Za-z]+