Comparing version
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { Agent } from 'http'; | ||
import { URL } from 'url'; | ||
import { Readable } from 'stream'; | ||
/** | ||
@@ -66,2 +68,6 @@ * Support `instanceof` operator for `GaxiosError`s in different versions of this library. | ||
} | ||
export interface GaxiosMultipartOptions { | ||
headers: Headers; | ||
content: string | Readable; | ||
} | ||
/** | ||
@@ -95,2 +101,3 @@ * Request options that are used to form the request. | ||
follow?: number; | ||
multipart?: GaxiosMultipartOptions[]; | ||
params?: any; | ||
@@ -123,2 +130,8 @@ paramsSerializer?: (params: { | ||
* | ||
* @remarks | ||
* | ||
* This does not replace the requirement for an active Data Loss Prevention (DLP) provider. For DLP suggestions, see: | ||
* - https://cloud.google.com/sensitive-data-protection/docs/redacting-sensitive-data#dlp_deidentify_replace_infotype-nodejs | ||
* - https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference#credentials_and_secrets | ||
* | ||
* @experimental | ||
@@ -125,0 +138,0 @@ */ |
@@ -121,5 +121,13 @@ "use strict"; | ||
// any casing of `Authentication` | ||
if (/^authentication$/.test(key)) { | ||
if (/^authentication$/i.test(key)) { | ||
headers[key] = REDACT; | ||
} | ||
// any casing of `Authorization` | ||
if (/^authorization$/i.test(key)) { | ||
headers[key] = REDACT; | ||
} | ||
// anything containing secret, such as 'client secret' | ||
if (/secret/i.test(key)) { | ||
headers[key] = REDACT; | ||
} | ||
} | ||
@@ -132,3 +140,5 @@ } | ||
const text = obj[key]; | ||
if (/grant_type=/.test(text) || /assertion=/.test(text)) { | ||
if (/grant_type=/i.test(text) || | ||
/assertion=/i.test(text) || | ||
/secret/i.test(text)) { | ||
obj[key] = REDACT; | ||
@@ -146,2 +156,5 @@ } | ||
} | ||
if ('client_secret' in obj) { | ||
obj['client_secret'] = REDACT; | ||
} | ||
} | ||
@@ -160,2 +173,5 @@ } | ||
} | ||
if (url.searchParams.has('client_secret')) { | ||
url.searchParams.set('client_secret', REDACT); | ||
} | ||
data.config.url = url.toString(); | ||
@@ -162,0 +178,0 @@ } |
@@ -51,2 +51,11 @@ /// <reference types="node" /> | ||
private getResponseDataFromContentType; | ||
/** | ||
* Creates an async generator that yields the pieces of a multipart/related request body. | ||
* This implementation follows the spec: https://www.ietf.org/rfc/rfc2387.txt. However, recursive | ||
* multipart/related requests are not currently supported. | ||
* | ||
* @param {GaxioMultipartOptions[]} multipartOptions the pieces to turn into a multipart/related body. | ||
* @param {string} boundary the boundary string to be placed between each part. | ||
*/ | ||
private getMultipartRequest; | ||
} |
@@ -27,3 +27,5 @@ "use strict"; | ||
const retry_1 = require("./retry"); | ||
const stream_1 = require("stream"); | ||
const https_proxy_agent_1 = require("https-proxy-agent"); | ||
const uuid_1 = require("uuid"); | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
@@ -217,3 +219,3 @@ const fetch = hasFetch() ? window.fetch : node_fetch_1.default; | ||
opts.headers = opts.headers || {}; | ||
if (opts.data) { | ||
if (opts.multipart === undefined && opts.data) { | ||
const isFormData = typeof FormData === 'undefined' | ||
@@ -253,2 +255,12 @@ ? false | ||
} | ||
else if (opts.multipart && opts.multipart.length > 0) { | ||
// note: once the minimum version reaches Node 16, | ||
// this can be replaced with randomUUID() function from crypto | ||
// and the dependency on UUID removed | ||
const boundary = (0, uuid_1.v4)(); | ||
opts.headers['Content-Type'] = `multipart/related; boundary=${boundary}`; | ||
const bodyStream = new stream_1.PassThrough(); | ||
opts.body = bodyStream; | ||
(0, stream_1.pipeline)(this.getMultipartRequest(opts.multipart, boundary), bodyStream, () => { }); | ||
} | ||
opts.validateStatus = opts.validateStatus || this.validateStatus; | ||
@@ -364,4 +376,28 @@ opts.responseType = opts.responseType || 'unknown'; | ||
} | ||
/** | ||
* Creates an async generator that yields the pieces of a multipart/related request body. | ||
* This implementation follows the spec: https://www.ietf.org/rfc/rfc2387.txt. However, recursive | ||
* multipart/related requests are not currently supported. | ||
* | ||
* @param {GaxioMultipartOptions[]} multipartOptions the pieces to turn into a multipart/related body. | ||
* @param {string} boundary the boundary string to be placed between each part. | ||
*/ | ||
async *getMultipartRequest(multipartOptions, boundary) { | ||
const finale = `--${boundary}--`; | ||
for (const currentPart of multipartOptions) { | ||
const partContentType = currentPart.headers['Content-Type'] || 'application/octet-stream'; | ||
const preamble = `--${boundary}\r\nContent-Type: ${partContentType}\r\n\r\n`; | ||
yield preamble; | ||
if (typeof currentPart.content === 'string') { | ||
yield currentPart.content; | ||
} | ||
else { | ||
yield* currentPart.content; | ||
} | ||
yield '\r\n'; | ||
} | ||
yield finale; | ||
} | ||
} | ||
exports.Gaxios = Gaxios; | ||
//# sourceMappingURL=gaxios.js.map |
# Changelog | ||
## [6.4.0](https://github.com/googleapis/gaxios/compare/v6.3.0...v6.4.0) (2024-04-03) | ||
### Features | ||
* Enhance Error Redaction ([#609](https://github.com/googleapis/gaxios/issues/609)) ([b1d2875](https://github.com/googleapis/gaxios/commit/b1d28759110f91b37746f9b88aba92bf52df2fcc)) | ||
* Support multipart/related requests ([#610](https://github.com/googleapis/gaxios/issues/610)) ([086c824](https://github.com/googleapis/gaxios/commit/086c8240652bd893dff0dd4c097ef00f5777564e)) | ||
### Bug Fixes | ||
* Error Redactor Case-Insensitive Matching ([#613](https://github.com/googleapis/gaxios/issues/613)) ([05e65ef](https://github.com/googleapis/gaxios/commit/05e65efda6d13e760d4f7f87be7d6cebeba3cc64)) | ||
## [6.3.0](https://github.com/googleapis/gaxios/compare/v6.2.0...v6.3.0) (2024-02-01) | ||
@@ -4,0 +17,0 @@ |
{ | ||
"name": "gaxios", | ||
"version": "6.3.0", | ||
"version": "6.4.0", | ||
"description": "A simple common HTTP client specifically for Google APIs and services.", | ||
@@ -71,3 +71,3 @@ "main": "build/src/index.js", | ||
"karma-sourcemap-loader": "^0.4.0", | ||
"karma-webpack": "^5.0.0", | ||
"karma-webpack": "5.0.0", | ||
"linkinator": "^4.0.0", | ||
@@ -83,6 +83,5 @@ "mocha": "^8.0.0", | ||
"stream-browserify": "^3.0.0", | ||
"tmp": "0.2.1", | ||
"tmp": "0.2.3", | ||
"ts-loader": "^8.0.0", | ||
"typescript": "^5.1.6", | ||
"uuid": "^9.0.0", | ||
"webpack": "^5.35.0", | ||
@@ -95,4 +94,5 @@ "webpack-cli": "^4.0.0" | ||
"is-stream": "^2.0.0", | ||
"node-fetch": "^2.6.9" | ||
"node-fetch": "^2.6.9", | ||
"uuid": "^9.0.1" | ||
} | ||
} |
@@ -163,2 +163,8 @@ # gaxios | ||
* | ||
* @remarks | ||
* | ||
* This does not replace the requirement for an active Data Loss Prevention (DLP) provider. For DLP suggestions, see: | ||
* - https://cloud.google.com/sensitive-data-protection/docs/redacting-sensitive-data#dlp_deidentify_replace_infotype-nodejs | ||
* - https://cloud.google.com/sensitive-data-protection/docs/infotypes-reference#credentials_and_secrets | ||
* | ||
* @experimental | ||
@@ -165,0 +171,0 @@ */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
99911
6.47%47
-2.08%1090
7.28%178
3.49%5
25%+ Added
+ Added