@octokit/rest
Advanced tools
Comparing version 15.1.3 to 15.1.4
@@ -12,9 +12,12 @@ 'use strict' | ||
module.exports = class HttpError extends Error { | ||
constructor (message, code, headers) { | ||
constructor (message, code) { | ||
super(message) | ||
Error.captureStackTrace(this, this.constructor) | ||
// Maintains proper stack trace for where our error was thrown (only available on V8) | ||
/* istanbul ignore else */ | ||
if (Error.captureStackTrace) { | ||
Error.captureStackTrace(this, this.constructor) | ||
} | ||
this.name = 'HttpError' | ||
this.code = code | ||
this.status = STATUS_CODES[code] | ||
this.headers = headers | ||
} | ||
@@ -21,0 +24,0 @@ |
'use strict' | ||
module.exports = httpRequest | ||
module.exports = request | ||
const url = require('url') | ||
const http = require('http') | ||
const https = require('https') | ||
const fetch = require('@gr2m/node-fetch') | ||
const debug = require('debug')('octokit:rest') | ||
const defaults = require('lodash/defaults') | ||
const isStream = require('is-stream') | ||
const isPlainObject = require('lodash/isPlainObject') | ||
const pick = require('lodash/pick') | ||
const getBuffer = require('./get-buffer-response') | ||
const HttpError = require('./http-error') | ||
const isArrayBuffer = require('./is-array-buffer') | ||
function httpRequest (origRequestOptions) { | ||
const requestOptions = Object.assign( | ||
url.parse(origRequestOptions.url), | ||
pick(origRequestOptions, 'method', 'body', 'headers', 'agent', 'timeout') | ||
) | ||
function request (requestOptions) { | ||
debug('REQUEST:', requestOptions) | ||
@@ -27,110 +19,68 @@ | ||
// content length is already set per option | ||
if (requestOptions.body && !isStream(requestOptions.body)) { | ||
// stringify body unless it’s an ArrayBuffer | ||
if (!isArrayBuffer(requestOptions.body) && !Buffer.isBuffer(requestOptions.body) && typeof requestOptions.body !== 'string') { | ||
requestOptions.body = JSON.stringify(requestOptions.body) | ||
} | ||
if (requestOptions.body) { | ||
defaults(requestOptions.headers, { | ||
'content-type': 'application/json; charset=utf-8', | ||
'content-length': Buffer.byteLength(requestOptions.body, 'utf8') | ||
'content-type': 'application/json; charset=utf-8' | ||
}) | ||
} | ||
// https://fetch.spec.whatwg.org/#methods | ||
requestOptions.method = requestOptions.method.toUpperCase() | ||
// GitHub expects "content-length: 0" header for PUT/PATCH requests without body | ||
if (['patch', 'put'].indexOf(requestOptions.method) >= 0 && | ||
!requestOptions.headers['content-length']) { | ||
requestOptions.headers['content-length'] = 0 | ||
// fetch does not allow to set `content-length` header, but we can set body to an empty string | ||
if (['PATCH', 'PUT'].indexOf(requestOptions.method) >= 0 && !requestOptions.body) { | ||
requestOptions.body = '' | ||
} | ||
if ('content-length' in requestOptions.headers) { | ||
requestOptions.headers['content-length'] = parseInt(requestOptions.headers['content-length'], 10) | ||
if (isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) { | ||
requestOptions.body = JSON.stringify(requestOptions.body) | ||
} | ||
const reqModule = requestOptions.protocol === 'http:' ? http : https | ||
delete requestOptions.protocol | ||
let headers = {} | ||
return fetch(requestOptions.url, pick(requestOptions, 'method', 'body', 'headers', 'timeout', 'agent')) | ||
return new Promise((resolve, reject) => { | ||
const request = reqModule.request(requestOptions, (response) => { | ||
debug('STATUS: ' + response.statusCode) | ||
debug('HEADERS: ' + JSON.stringify(response.headers)) | ||
.then(response => { | ||
const contentType = response.headers.get('content-type') | ||
const data = [] | ||
response.on('data', (chunk) => { | ||
data.push(chunk) | ||
}) | ||
for (const keyAndValue of response.headers.entries()) { | ||
headers[keyAndValue[0]] = keyAndValue[1] | ||
} | ||
/* istanbul ignore next */ | ||
response.on('error', (error) => { | ||
reject(new HttpError(error.message, 500)) | ||
}) | ||
response.on('end', () => { | ||
if (response.statusCode !== 304 && response.statusCode >= 301 && response.statusCode <= 307) { | ||
origRequestOptions.url = response.headers.location | ||
if (response.status === 204) { | ||
return | ||
} | ||
httpRequest(origRequestOptions).then(resolve, reject) | ||
return | ||
} | ||
if (response.status >= 400) { | ||
return response.text() | ||
if (response.statusCode === 304 || response.statusCode >= 400 || response.statusCode < 10) { | ||
reject(new HttpError(data, response.statusCode, response.headers)) | ||
return | ||
} | ||
const contentType = response.headers['content-type'] || '' | ||
if (data.length === 0) { | ||
return resolve({ | ||
meta: response.headers | ||
.then(message => { | ||
throw new HttpError(message, response.status) | ||
}) | ||
} | ||
} | ||
if (contentType.indexOf('application/json') !== -1) { | ||
return resolve({ | ||
meta: response.headers, | ||
data: JSON.parse(Buffer.concat(data).toString()) | ||
}) | ||
} | ||
if (/application\/json/.test(contentType)) { | ||
return response.json() | ||
} | ||
if (/^text\/|charset=utf-8$/i.test(contentType)) { | ||
return resolve({ | ||
meta: response.headers, | ||
data: Buffer.concat(data).toString() | ||
}) | ||
} | ||
if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) { | ||
return response.text() | ||
} | ||
resolve({ | ||
meta: response.headers, | ||
data: Buffer.concat(data) | ||
}) | ||
}) | ||
return getBuffer(response) | ||
}) | ||
let aborted | ||
request.on('error', (error) => { | ||
if (aborted) return | ||
debug('REQUEST ERROR: ' + error.message) | ||
reject(new HttpError(error.message, 500)) | ||
.then(data => { | ||
return { | ||
data, | ||
meta: headers | ||
} | ||
}) | ||
if (requestOptions.timeout) { | ||
request.setTimeout(requestOptions.timeout) | ||
} | ||
request.on('timeout', () => { | ||
debug('REQUEST ERROR: timed out') | ||
request.abort() | ||
aborted = true | ||
reject(new HttpError('Request timeout', 504)) | ||
}) | ||
if (requestOptions.body) { | ||
if (isStream(requestOptions.body)) { | ||
return requestOptions.body.pipe(request) | ||
.catch(error => { | ||
if (error instanceof HttpError) { | ||
throw error | ||
} | ||
request.write(Buffer.from(requestOptions.body)) | ||
} | ||
request.end() | ||
}) | ||
throw new HttpError(error.message, 500) | ||
}) | ||
} |
{ | ||
"name": "@octokit/rest", | ||
"version": "15.1.3", | ||
"version": "15.1.4", | ||
"publishConfig": { | ||
@@ -42,3 +42,2 @@ "access": "public", | ||
"debug": "^3.1.0", | ||
"is-stream": "^1.1.0", | ||
"lodash": "^4.17.4", | ||
@@ -63,3 +62,3 @@ "url-template": "^2.0.8" | ||
"nock": "^9.1.0", | ||
"node-fetch": "^2.0.0", | ||
"@gr2m/node-fetch": "^2.0.0", | ||
"npm-run-all": "^4.1.2", | ||
@@ -80,4 +79,4 @@ "nyc": "^11.2.1", | ||
"browser": { | ||
"./lib/request/request.js": "./lib/request/request-browser.js", | ||
"./lib/get-request-agent.js": false | ||
"./lib/get-request-agent.js": false, | ||
"./lib/request/get-buffer-response.js": "./lib/request/get-buffer-response-browser.js" | ||
}, | ||
@@ -133,3 +132,4 @@ "types": "index.d.ts", | ||
"assets": [ | ||
"dist/*.js" | ||
"dist/*", | ||
"!dist/*.map.gz" | ||
] | ||
@@ -136,0 +136,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5
41
3
563300
14715
- Removedis-stream@^1.1.0
- Removedis-stream@1.1.0(transitive)