From e7cf8ce35c91570a9735473b27ef82551834f808 Mon Sep 17 00:00:00 2001 From: BinHong Lee Date: Tue, 11 Jul 2017 16:17:53 -0700 Subject: [PATCH] Use http instead of xmlhttprequest --- src/index.js | 29 +- src/node_modules/https/package.json | 68 ++ src/node_modules/xmlhttprequest/.jshintrc | 26 - src/node_modules/xmlhttprequest/.npmignore | 4 - src/node_modules/xmlhttprequest/LICENSE | 22 - src/node_modules/xmlhttprequest/README.md | 55 -- .../xmlhttprequest/lib/XMLHttpRequest.js | 620 ------------------ src/node_modules/xmlhttprequest/package.json | 80 --- 8 files changed, 89 insertions(+), 815 deletions(-) create mode 100644 src/node_modules/https/package.json delete mode 100644 src/node_modules/xmlhttprequest/.jshintrc delete mode 100644 src/node_modules/xmlhttprequest/.npmignore delete mode 100644 src/node_modules/xmlhttprequest/LICENSE delete mode 100644 src/node_modules/xmlhttprequest/README.md delete mode 100644 src/node_modules/xmlhttprequest/lib/XMLHttpRequest.js delete mode 100644 src/node_modules/xmlhttprequest/package.json diff --git a/src/index.js b/src/index.js index 2ea037e..8d19c69 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ 'use strict' const Alexa = require('alexa-sdk') -const XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest +var https = require('https') let response = '' exports.handler = function (event, context, callback) { @@ -22,14 +22,27 @@ var handlers = { // RequestIntent handler 'RequestIntent': function () { - var xhr = new XMLHttpRequest() - xhr.open('GET', 'https://api.opendota.com/api/heroes', true) - xhr.onreadystatechange = function () { - if (this.readyState === 4) { - response = JSON.parse(xhr.responseText) - } + var info = { + host: 'api.opendota.com/api/heroes', + port: 443, + path: '/api/heroes', + method: 'GET' } - xhr.send() + + var req = https.request(info, res => { + res.setEncoding('utf8') + var returnData = '' + + res.on('data', chunk => { + returnData = returnData + chunk + }) + + res.on('end', () => { + response = JSON.parse(returnData) + }) + }) + + req.end() var speechOutput = 'Output is :' + response[getRandomInt() - 1] + '?' diff --git a/src/node_modules/https/package.json b/src/node_modules/https/package.json new file mode 100644 index 0000000..e8ac124 --- /dev/null +++ b/src/node_modules/https/package.json @@ -0,0 +1,68 @@ +{ + "_args": [ + [ + "https", + "/home/binhong/dota2-alexa-skill/src" + ] + ], + "_from": "https@latest", + "_id": "https@1.0.0", + "_inCache": true, + "_installable": true, + "_location": "/https", + "_nodeVersion": "0.10.3", + "_npmUser": { + "email": "hardus@sunfork.com", + "name": "hardus" + }, + "_npmVersion": "2.1.18", + "_phantomChildren": {}, + "_requested": { + "name": "https", + "raw": "https", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "_shasum": "3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4", + "_shrinkwrap": null, + "_spec": "https", + "_where": "/home/binhong/dota2-alexa-skill/src", + "author": { + "email": "hardus@sunfork.com", + "name": "hardus van der berg", + "url": "http://www.sunfork.com" + }, + "dependencies": {}, + "description": "https mediation", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4", + "tarball": "https://registry.npmjs.org/https/-/https-1.0.0.tgz" + }, + "keywords": [ + "https", + "mediation" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "hardus", + "email": "hardus@sunfork.com" + } + ], + "name": "https", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "version": "1.0.0" +} diff --git a/src/node_modules/xmlhttprequest/.jshintrc b/src/node_modules/xmlhttprequest/.jshintrc deleted file mode 100644 index 3df2adc..0000000 --- a/src/node_modules/xmlhttprequest/.jshintrc +++ /dev/null @@ -1,26 +0,0 @@ -{ - "node": true, - "browser": false, - "esnext": true, - "bitwise": false, - "camelcase": true, - "curly": true, - "eqeqeq": true, - "eqnull": true, - "immed": true, - "indent": 2, - "latedef": true, - "laxbreak": true, - "newcap": true, - "noarg": true, - "quotmark": "double", - "regexp": true, - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "smarttabs": true, - "globals": { - "define": false - } -} diff --git a/src/node_modules/xmlhttprequest/.npmignore b/src/node_modules/xmlhttprequest/.npmignore deleted file mode 100644 index 97b5e9b..0000000 --- a/src/node_modules/xmlhttprequest/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -example -tests - -autotest.watchr diff --git a/src/node_modules/xmlhttprequest/LICENSE b/src/node_modules/xmlhttprequest/LICENSE deleted file mode 100644 index 1c63271..0000000 --- a/src/node_modules/xmlhttprequest/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ - Copyright (c) 2010 passive.ly LLC - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/node_modules/xmlhttprequest/README.md b/src/node_modules/xmlhttprequest/README.md deleted file mode 100644 index 50039f9..0000000 --- a/src/node_modules/xmlhttprequest/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# node-XMLHttpRequest # - -node-XMLHttpRequest is a wrapper for the built-in http client to emulate the -browser XMLHttpRequest object. - -This can be used with JS designed for browsers to improve reuse of code and -allow the use of existing libraries. - -Note: This library currently conforms to [XMLHttpRequest 1](http://www.w3.org/TR/XMLHttpRequest/). Version 2.0 will target [XMLHttpRequest Level 2](http://www.w3.org/TR/XMLHttpRequest2/). - -## Usage ## - -Here's how to include the module in your project and use as the browser-based -XHR object. - - var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; - var xhr = new XMLHttpRequest(); - -Note: use the lowercase string "xmlhttprequest" in your require(). On -case-sensitive systems (eg Linux) using uppercase letters won't work. - -## Versions ## - -Prior to 1.4.0 version numbers were arbitrary. From 1.4.0 on they conform to -the standard major.minor.bugfix. 1.x shouldn't necessarily be considered -stable just because it's above 0.x. - -Since the XMLHttpRequest API is stable this library's API is stable as -well. Major version numbers indicate significant core code changes. -Minor versions indicate minor core code changes or better conformity to -the W3C spec. - -## License ## - -MIT license. See LICENSE for full details. - -## Supports ## - -* Async and synchronous requests -* GET, POST, PUT, and DELETE requests -* All spec methods (open, send, abort, getRequestHeader, - getAllRequestHeaders, event methods) -* Requests to all domains - -## Known Issues / Missing Features ## - -For a list of open issues or to report your own visit the [github issues -page](https://github.com/driverdan/node-XMLHttpRequest/issues). - -* Local file access may have unexpected results for non-UTF8 files -* Synchronous requests don't set headers properly -* Synchronous requests freeze node while waiting for response (But that's what you want, right? Stick with async!). -* Some events are missing, such as abort -* Cookies aren't persisted between requests -* Missing XML support diff --git a/src/node_modules/xmlhttprequest/lib/XMLHttpRequest.js b/src/node_modules/xmlhttprequest/lib/XMLHttpRequest.js deleted file mode 100644 index 4893913..0000000 --- a/src/node_modules/xmlhttprequest/lib/XMLHttpRequest.js +++ /dev/null @@ -1,620 +0,0 @@ -/** - * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object. - * - * This can be used with JS designed for browsers to improve reuse of code and - * allow the use of existing libraries. - * - * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs. - * - * @author Dan DeFelippi - * @contributor David Ellis - * @license MIT - */ - -var Url = require("url"); -var spawn = require("child_process").spawn; -var fs = require("fs"); - -exports.XMLHttpRequest = function() { - "use strict"; - - /** - * Private variables - */ - var self = this; - var http = require("http"); - var https = require("https"); - - // Holds http.js objects - var request; - var response; - - // Request settings - var settings = {}; - - // Disable header blacklist. - // Not part of XHR specs. - var disableHeaderCheck = false; - - // Set some default headers - var defaultHeaders = { - "User-Agent": "node-XMLHttpRequest", - "Accept": "*/*", - }; - - var headers = {}; - var headersCase = {}; - - // These headers are not user setable. - // The following are allowed but banned in the spec: - // * user-agent - var forbiddenRequestHeaders = [ - "accept-charset", - "accept-encoding", - "access-control-request-headers", - "access-control-request-method", - "connection", - "content-length", - "content-transfer-encoding", - "cookie", - "cookie2", - "date", - "expect", - "host", - "keep-alive", - "origin", - "referer", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "via" - ]; - - // These request methods are not allowed - var forbiddenRequestMethods = [ - "TRACE", - "TRACK", - "CONNECT" - ]; - - // Send flag - var sendFlag = false; - // Error flag, used when errors occur or abort is called - var errorFlag = false; - - // Event listeners - var listeners = {}; - - /** - * Constants - */ - - this.UNSENT = 0; - this.OPENED = 1; - this.HEADERS_RECEIVED = 2; - this.LOADING = 3; - this.DONE = 4; - - /** - * Public vars - */ - - // Current state - this.readyState = this.UNSENT; - - // default ready state change handler in case one is not set or is set late - this.onreadystatechange = null; - - // Result & response - this.responseText = ""; - this.responseXML = ""; - this.status = null; - this.statusText = null; - - // Whether cross-site Access-Control requests should be made using - // credentials such as cookies or authorization headers - this.withCredentials = false; - - /** - * Private methods - */ - - /** - * Check if the specified header is allowed. - * - * @param string header Header to validate - * @return boolean False if not allowed, otherwise true - */ - var isAllowedHttpHeader = function(header) { - return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1); - }; - - /** - * Check if the specified method is allowed. - * - * @param string method Request method to validate - * @return boolean False if not allowed, otherwise true - */ - var isAllowedHttpMethod = function(method) { - return (method && forbiddenRequestMethods.indexOf(method) === -1); - }; - - /** - * Public methods - */ - - /** - * Open the connection. Currently supports local server requests. - * - * @param string method Connection method (eg GET, POST) - * @param string url URL for the connection. - * @param boolean async Asynchronous connection. Default is true. - * @param string user Username for basic authentication (optional) - * @param string password Password for basic authentication (optional) - */ - this.open = function(method, url, async, user, password) { - this.abort(); - errorFlag = false; - - // Check for valid request method - if (!isAllowedHttpMethod(method)) { - throw new Error("SecurityError: Request method not allowed"); - } - - settings = { - "method": method, - "url": url.toString(), - "async": (typeof async !== "boolean" ? true : async), - "user": user || null, - "password": password || null - }; - - setState(this.OPENED); - }; - - /** - * Disables or enables isAllowedHttpHeader() check the request. Enabled by default. - * This does not conform to the W3C spec. - * - * @param boolean state Enable or disable header checking. - */ - this.setDisableHeaderCheck = function(state) { - disableHeaderCheck = state; - }; - - /** - * Sets a header for the request or appends the value if one is already set. - * - * @param string header Header name - * @param string value Header value - */ - this.setRequestHeader = function(header, value) { - if (this.readyState !== this.OPENED) { - throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN"); - } - if (!isAllowedHttpHeader(header)) { - console.warn("Refused to set unsafe header \"" + header + "\""); - return; - } - if (sendFlag) { - throw new Error("INVALID_STATE_ERR: send flag is true"); - } - header = headersCase[header.toLowerCase()] || header; - headersCase[header.toLowerCase()] = header; - headers[header] = headers[header] ? headers[header] + ', ' + value : value; - }; - - /** - * Gets a header from the server response. - * - * @param string header Name of header to get. - * @return string Text of the header or null if it doesn't exist. - */ - this.getResponseHeader = function(header) { - if (typeof header === "string" - && this.readyState > this.OPENED - && response - && response.headers - && response.headers[header.toLowerCase()] - && !errorFlag - ) { - return response.headers[header.toLowerCase()]; - } - - return null; - }; - - /** - * Gets all the response headers. - * - * @return string A string with all response headers separated by CR+LF - */ - this.getAllResponseHeaders = function() { - if (this.readyState < this.HEADERS_RECEIVED || errorFlag) { - return ""; - } - var result = ""; - - for (var i in response.headers) { - // Cookie headers are excluded - if (i !== "set-cookie" && i !== "set-cookie2") { - result += i + ": " + response.headers[i] + "\r\n"; - } - } - return result.substr(0, result.length - 2); - }; - - /** - * Gets a request header - * - * @param string name Name of header to get - * @return string Returns the request header or empty string if not set - */ - this.getRequestHeader = function(name) { - if (typeof name === "string" && headersCase[name.toLowerCase()]) { - return headers[headersCase[name.toLowerCase()]]; - } - - return ""; - }; - - /** - * Sends the request to the server. - * - * @param string data Optional data to send as request body. - */ - this.send = function(data) { - if (this.readyState !== this.OPENED) { - throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called"); - } - - if (sendFlag) { - throw new Error("INVALID_STATE_ERR: send has already been called"); - } - - var ssl = false, local = false; - var url = Url.parse(settings.url); - var host; - // Determine the server - switch (url.protocol) { - case "https:": - ssl = true; - // SSL & non-SSL both need host, no break here. - case "http:": - host = url.hostname; - break; - - case "file:": - local = true; - break; - - case undefined: - case null: - case "": - host = "localhost"; - break; - - default: - throw new Error("Protocol not supported."); - } - - // Load files off the local filesystem (file://) - if (local) { - if (settings.method !== "GET") { - throw new Error("XMLHttpRequest: Only GET method is supported"); - } - - if (settings.async) { - fs.readFile(url.pathname, "utf8", function(error, data) { - if (error) { - self.handleError(error); - } else { - self.status = 200; - self.responseText = data; - setState(self.DONE); - } - }); - } else { - try { - this.responseText = fs.readFileSync(url.pathname, "utf8"); - this.status = 200; - setState(self.DONE); - } catch(e) { - this.handleError(e); - } - } - - return; - } - - // Default to port 80. If accessing localhost on another port be sure - // to use http://localhost:port/path - var port = url.port || (ssl ? 443 : 80); - // Add query string if one is used - var uri = url.pathname + (url.search ? url.search : ""); - - // Set the defaults if they haven't been set - for (var name in defaultHeaders) { - if (!headersCase[name.toLowerCase()]) { - headers[name] = defaultHeaders[name]; - } - } - - // Set the Host header or the server may reject the request - headers.Host = host; - if (!((ssl && port === 443) || port === 80)) { - headers.Host += ":" + url.port; - } - - // Set Basic Auth if necessary - if (settings.user) { - if (typeof settings.password === "undefined") { - settings.password = ""; - } - var authBuf = new Buffer(settings.user + ":" + settings.password); - headers.Authorization = "Basic " + authBuf.toString("base64"); - } - - // Set content length header - if (settings.method === "GET" || settings.method === "HEAD") { - data = null; - } else if (data) { - headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data); - - if (!headers["Content-Type"]) { - headers["Content-Type"] = "text/plain;charset=UTF-8"; - } - } else if (settings.method === "POST") { - // For a post with no data set Content-Length: 0. - // This is required by buggy servers that don't meet the specs. - headers["Content-Length"] = 0; - } - - var options = { - host: host, - port: port, - path: uri, - method: settings.method, - headers: headers, - agent: false, - withCredentials: self.withCredentials - }; - - // Reset error flag - errorFlag = false; - - // Handle async requests - if (settings.async) { - // Use the proper protocol - var doRequest = ssl ? https.request : http.request; - - // Request is being sent, set send flag - sendFlag = true; - - // As per spec, this is called here for historical reasons. - self.dispatchEvent("readystatechange"); - - // Handler for the response - var responseHandler = function responseHandler(resp) { - // Set response var to the response we got back - // This is so it remains accessable outside this scope - response = resp; - // Check for redirect - // @TODO Prevent looped redirects - if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) { - // Change URL to the redirect location - settings.url = response.headers.location; - var url = Url.parse(settings.url); - // Set host var in case it's used later - host = url.hostname; - // Options for the new request - var newOptions = { - hostname: url.hostname, - port: url.port, - path: url.path, - method: response.statusCode === 303 ? "GET" : settings.method, - headers: headers, - withCredentials: self.withCredentials - }; - - // Issue the new request - request = doRequest(newOptions, responseHandler).on("error", errorHandler); - request.end(); - // @TODO Check if an XHR event needs to be fired here - return; - } - - response.setEncoding("utf8"); - - setState(self.HEADERS_RECEIVED); - self.status = response.statusCode; - - response.on("data", function(chunk) { - // Make sure there's some data - if (chunk) { - self.responseText += chunk; - } - // Don't emit state changes if the connection has been aborted. - if (sendFlag) { - setState(self.LOADING); - } - }); - - response.on("end", function() { - if (sendFlag) { - // Discard the end event if the connection has been aborted - setState(self.DONE); - sendFlag = false; - } - }); - - response.on("error", function(error) { - self.handleError(error); - }); - }; - - // Error handler for the request - var errorHandler = function errorHandler(error) { - self.handleError(error); - }; - - // Create the request - request = doRequest(options, responseHandler).on("error", errorHandler); - - // Node 0.4 and later won't accept empty data. Make sure it's needed. - if (data) { - request.write(data); - } - - request.end(); - - self.dispatchEvent("loadstart"); - } else { // Synchronous - // Create a temporary file for communication with the other Node process - var contentFile = ".node-xmlhttprequest-content-" + process.pid; - var syncFile = ".node-xmlhttprequest-sync-" + process.pid; - fs.writeFileSync(syncFile, "", "utf8"); - // The async request the other Node process executes - var execString = "var http = require('http'), https = require('https'), fs = require('fs');" - + "var doRequest = http" + (ssl ? "s" : "") + ".request;" - + "var options = " + JSON.stringify(options) + ";" - + "var responseText = '';" - + "var req = doRequest(options, function(response) {" - + "response.setEncoding('utf8');" - + "response.on('data', function(chunk) {" - + " responseText += chunk;" - + "});" - + "response.on('end', function() {" - + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');" - + "fs.unlinkSync('" + syncFile + "');" - + "});" - + "response.on('error', function(error) {" - + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" - + "fs.unlinkSync('" + syncFile + "');" - + "});" - + "}).on('error', function(error) {" - + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');" - + "fs.unlinkSync('" + syncFile + "');" - + "});" - + (data ? "req.write('" + JSON.stringify(data).slice(1,-1).replace(/'/g, "\\'") + "');":"") - + "req.end();"; - // Start the other Node Process, executing this string - var syncProc = spawn(process.argv[0], ["-e", execString]); - while(fs.existsSync(syncFile)) { - // Wait while the sync file is empty - } - var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8')); - // Kill the child process once the file has data - syncProc.stdin.end(); - // Remove the temporary file - fs.unlinkSync(contentFile); - - if (resp.err) { - self.handleError(resp.err); - } else { - response = resp.data; - self.status = resp.data.statusCode; - self.responseText = resp.data.text; - setState(self.DONE); - } - } - }; - - /** - * Called when an error is encountered to deal with it. - */ - this.handleError = function(error) { - this.status = 0; - this.statusText = error; - this.responseText = error.stack; - errorFlag = true; - setState(this.DONE); - this.dispatchEvent('error'); - }; - - /** - * Aborts a request. - */ - this.abort = function() { - if (request) { - request.abort(); - request = null; - } - - headers = defaultHeaders; - this.status = 0; - this.responseText = ""; - this.responseXML = ""; - - errorFlag = true; - - if (this.readyState !== this.UNSENT - && (this.readyState !== this.OPENED || sendFlag) - && this.readyState !== this.DONE) { - sendFlag = false; - setState(this.DONE); - } - this.readyState = this.UNSENT; - this.dispatchEvent('abort'); - }; - - /** - * Adds an event listener. Preferred method of binding to events. - */ - this.addEventListener = function(event, callback) { - if (!(event in listeners)) { - listeners[event] = []; - } - // Currently allows duplicate callbacks. Should it? - listeners[event].push(callback); - }; - - /** - * Remove an event callback that has already been bound. - * Only works on the matching funciton, cannot be a copy. - */ - this.removeEventListener = function(event, callback) { - if (event in listeners) { - // Filter will return a new array with the callback removed - listeners[event] = listeners[event].filter(function(ev) { - return ev !== callback; - }); - } - }; - - /** - * Dispatch any events, including both "on" methods and events attached using addEventListener. - */ - this.dispatchEvent = function(event) { - if (typeof self["on" + event] === "function") { - self["on" + event](); - } - if (event in listeners) { - for (var i = 0, len = listeners[event].length; i < len; i++) { - listeners[event][i].call(self); - } - } - }; - - /** - * Changes readyState and calls onreadystatechange. - * - * @param int state New state - */ - var setState = function(state) { - if (state == self.LOADING || self.readyState !== state) { - self.readyState = state; - - if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) { - self.dispatchEvent("readystatechange"); - } - - if (self.readyState === self.DONE && !errorFlag) { - self.dispatchEvent("load"); - // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie) - self.dispatchEvent("loadend"); - } - } - }; -}; diff --git a/src/node_modules/xmlhttprequest/package.json b/src/node_modules/xmlhttprequest/package.json deleted file mode 100644 index 15c80cc..0000000 --- a/src/node_modules/xmlhttprequest/package.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "_args": [ - [ - "xmlhttprequest@^1.00", - "/home/binhong/dota2-alexa-skill/src" - ] - ], - "_from": "xmlhttprequest@>=1.0.0 <2.0.0", - "_id": "xmlhttprequest@1.8.0", - "_inCache": true, - "_installable": true, - "_location": "/xmlhttprequest", - "_nodeVersion": "0.12.2", - "_npmUser": { - "email": "dan@driverdan.com", - "name": "driverdan" - }, - "_npmVersion": "2.7.5", - "_phantomChildren": {}, - "_requested": { - "name": "xmlhttprequest", - "raw": "xmlhttprequest@^1.00", - "rawSpec": "^1.00", - "scope": null, - "spec": ">=1.0.0 <2.0.0", - "type": "range" - }, - "_requiredBy": [ - "/" - ], - "_resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "_shasum": "67fe075c5c24fef39f9d65f5f7b7fe75171968fc", - "_shrinkwrap": null, - "_spec": "xmlhttprequest@^1.00", - "_where": "/home/binhong/dota2-alexa-skill/src", - "author": { - "name": "Dan DeFelippi", - "url": "http://driverdan.com" - }, - "bugs": { - "url": "http://github.com/driverdan/node-XMLHttpRequest/issues" - }, - "dependencies": {}, - "description": "XMLHttpRequest for Node", - "devDependencies": {}, - "directories": { - "example": "./example", - "lib": "./lib" - }, - "dist": { - "shasum": "67fe075c5c24fef39f9d65f5f7b7fe75171968fc", - "tarball": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz" - }, - "engines": { - "node": ">=0.4.0" - }, - "gitHead": "86ff70effb6dd529b34650242b9e3b1f0b8b6e86", - "homepage": "https://github.com/driverdan/node-XMLHttpRequest", - "keywords": [ - "ajax", - "xhr" - ], - "license": "MIT", - "main": "./lib/XMLHttpRequest.js", - "maintainers": [ - { - "name": "driverdan", - "email": "dan@driverdan.com" - } - ], - "name": "xmlhttprequest", - "optionalDependencies": {}, - "readme": "ERROR: No README data found!", - "repository": { - "type": "git", - "url": "git://github.com/driverdan/node-XMLHttpRequest.git" - }, - "scripts": {}, - "version": "1.8.0" -}