@openclaw/googlechat 2026.7.1-beta.1 → 2026.7.1-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actions-BaygKCqu.js → actions-BacnMHv0.js} +2 -2
- package/dist/api.js +2 -2
- package/dist/{approval-auth-BxSuKX1J.js → approval-auth-C_BVZZFA.js} +2 -2
- package/dist/{approval-handler.runtime-AQl0xUss.js → approval-handler.runtime-BnkufknT.js} +7 -5
- package/dist/{channel-BQMTDOKw.js → channel-_o671C-U.js} +9 -8
- package/dist/{channel-base-Qh87GFW_.js → channel-base-DJICAvKH.js} +7 -6
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.adapters-CFEUpRK6.js → channel.adapters-FEj7zUjh.js} +53 -3
- package/dist/{channel.runtime-BBH8WHto.js → channel.runtime-CYmt7Ybo.js} +2 -8
- package/dist/directory-contract-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
- package/node_modules/gaxios/package.json +7 -9
- package/node_modules/google-auth-library/build/src/auth/gdchclient.d.ts +47 -0
- package/node_modules/google-auth-library/build/src/auth/gdchclient.js +307 -0
- package/node_modules/google-auth-library/build/src/auth/googleauth.d.ts +5 -4
- package/node_modules/google-auth-library/build/src/auth/googleauth.js +18 -1
- package/node_modules/google-auth-library/build/src/index.d.ts +1 -0
- package/node_modules/google-auth-library/build/src/index.js +4 -1
- package/node_modules/google-auth-library/package.json +5 -7
- package/npm-shrinkwrap.json +11 -39
- package/package.json +6 -6
- package/node_modules/gcp-metadata/node_modules/gaxios/LICENSE +0 -202
- package/node_modules/gcp-metadata/node_modules/gaxios/README.md +0 -240
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.js +0 -109
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/test.browser.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/test.browser.js +0 -81
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/browser-test/test.browser.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/common.d.ts +0 -329
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/common.js +0 -311
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/common.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/gaxios.d.ts +0 -104
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/gaxios.js +0 -564
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/gaxios.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/index.d.ts +0 -15
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/index.js +0 -48
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/index.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/interceptor.d.ts +0 -25
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/interceptor.js +0 -22
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/interceptor.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/retry.d.ts +0 -8
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/retry.js +0 -165
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/retry.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/util.cjs +0 -16
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/util.cjs.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/src/util.d.cts +0 -7
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/system-test/test.install.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/system-test/test.install.js +0 -128
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/system-test/test.install.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.getch.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.getch.js +0 -1444
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.getch.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.index.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.index.js +0 -61
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.index.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.retry.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.retry.js +0 -367
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/test/test.retry.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/browser-test-runner.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/browser-test-runner.js +0 -71
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/browser-test-runner.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/test.browser.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/test.browser.js +0 -76
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/browser-test/test.browser.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/package.json +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/common.d.ts +0 -329
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/common.js +0 -303
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/common.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/gaxios.d.ts +0 -104
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/gaxios.js +0 -557
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/gaxios.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/index.d.ts +0 -15
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/index.js +0 -29
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/index.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/interceptor.d.ts +0 -25
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/interceptor.js +0 -18
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/interceptor.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/retry.d.ts +0 -8
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/retry.js +0 -162
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/retry.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/util.cjs +0 -15
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/util.cjs.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/src/util.d.cts +0 -7
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/system-test/test.install.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/system-test/test.install.js +0 -123
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/system-test/test.install.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.getch.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.getch.js +0 -1406
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.getch.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.index.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.index.js +0 -23
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.index.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.retry.d.ts +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.retry.js +0 -362
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/test/test.retry.js.map +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +0 -1
- package/node_modules/gcp-metadata/node_modules/gaxios/package.json +0 -105
- package/node_modules/google-auth-library/node_modules/gaxios/LICENSE +0 -202
- package/node_modules/google-auth-library/node_modules/gaxios/README.md +0 -240
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.js +0 -109
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/browser-test-runner.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/test.browser.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/test.browser.js +0 -81
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/browser-test/test.browser.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/common.d.ts +0 -329
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/common.js +0 -311
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/common.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/gaxios.d.ts +0 -104
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/gaxios.js +0 -564
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/gaxios.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/index.d.ts +0 -15
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/index.js +0 -48
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/index.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/interceptor.d.ts +0 -25
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/interceptor.js +0 -22
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/interceptor.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/retry.d.ts +0 -8
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/retry.js +0 -165
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/retry.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/util.cjs +0 -16
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/util.cjs.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/src/util.d.cts +0 -7
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/system-test/test.install.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/system-test/test.install.js +0 -128
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/system-test/test.install.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.getch.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.getch.js +0 -1444
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.getch.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.index.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.index.js +0 -61
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.index.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.retry.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.retry.js +0 -367
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/test/test.retry.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/browser-test-runner.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/browser-test-runner.js +0 -71
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/browser-test-runner.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/test.browser.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/test.browser.js +0 -76
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/browser-test/test.browser.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/package.json +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/common.d.ts +0 -329
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/common.js +0 -303
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/common.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/gaxios.d.ts +0 -104
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/gaxios.js +0 -557
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/gaxios.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/index.d.ts +0 -15
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/index.js +0 -29
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/index.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/interceptor.d.ts +0 -25
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/interceptor.js +0 -18
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/interceptor.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/retry.d.ts +0 -8
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/retry.js +0 -162
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/retry.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/util.cjs +0 -15
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/util.cjs.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/src/util.d.cts +0 -7
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/system-test/test.install.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/system-test/test.install.js +0 -123
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/system-test/test.install.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.getch.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.getch.js +0 -1406
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.getch.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.index.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.index.js +0 -23
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.index.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.retry.d.ts +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.retry.js +0 -362
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/test/test.retry.js.map +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +0 -1
- package/node_modules/google-auth-library/node_modules/gaxios/package.json +0 -105
|
@@ -1,1406 +0,0 @@
|
|
|
1
|
-
// Copyright 2018 Google LLC
|
|
2
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
-
// you may not use this file except in compliance with the License.
|
|
4
|
-
// You may obtain a copy of the License at
|
|
5
|
-
//
|
|
6
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
-
//
|
|
8
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
-
// See the License for the specific language governing permissions and
|
|
12
|
-
// limitations under the License.
|
|
13
|
-
import assert from 'assert';
|
|
14
|
-
import nock from 'nock';
|
|
15
|
-
import sinon from 'sinon';
|
|
16
|
-
import stream, { Readable } from 'stream';
|
|
17
|
-
import { describe, it, afterEach } from 'mocha';
|
|
18
|
-
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
19
|
-
import { Gaxios, GaxiosError, request, } from '../src/index.js';
|
|
20
|
-
import { GAXIOS_ERROR_SYMBOL, } from '../src/common.js';
|
|
21
|
-
import util from '../src/util.cjs';
|
|
22
|
-
import fs from 'fs';
|
|
23
|
-
const pkg = util.pkg;
|
|
24
|
-
nock.disableNetConnect();
|
|
25
|
-
const sandbox = sinon.createSandbox();
|
|
26
|
-
afterEach(() => {
|
|
27
|
-
sandbox.restore();
|
|
28
|
-
nock.cleanAll();
|
|
29
|
-
});
|
|
30
|
-
const url = 'https://example.com';
|
|
31
|
-
function setEnv(obj) {
|
|
32
|
-
return sandbox.stub(process, 'env').value(obj);
|
|
33
|
-
}
|
|
34
|
-
describe('🦖 option validation', () => {
|
|
35
|
-
it('should throw an error if a url is not provided', async () => {
|
|
36
|
-
await assert.rejects(request({}), /URL is required/);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('🚙 error handling', () => {
|
|
40
|
-
it('should throw on non-2xx responses by default', async () => {
|
|
41
|
-
const scope = nock(url).get('/').reply(500);
|
|
42
|
-
await assert.rejects(request({ url }), (err) => {
|
|
43
|
-
scope.done();
|
|
44
|
-
return err.status === 500;
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
it('should throw the error as a GaxiosError object, regardless of Content-Type header', async () => {
|
|
48
|
-
const body = {
|
|
49
|
-
error: {
|
|
50
|
-
message: 'File not found',
|
|
51
|
-
code: 404,
|
|
52
|
-
status: 'NOT FOUND',
|
|
53
|
-
details: [
|
|
54
|
-
{
|
|
55
|
-
some: 'details',
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
const scope = nock(url).get('/').reply(404, body);
|
|
61
|
-
await assert.rejects(request({ url, responseType: 'json' }), (err) => {
|
|
62
|
-
scope.done();
|
|
63
|
-
assert.deepStrictEqual(err.cause, body.error);
|
|
64
|
-
return err.status === 404 && err.message === 'File not found';
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
it('should throw the error as a `GaxiosError` object (with the message as a string), even if the request type is requested as an arraybuffer', async () => {
|
|
68
|
-
const body = {
|
|
69
|
-
error: {
|
|
70
|
-
status: 404,
|
|
71
|
-
message: 'File not found',
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
const scope = nock(url).get('/').reply(404, body);
|
|
75
|
-
await assert.rejects(request({ url, responseType: 'arraybuffer' }), (err) => {
|
|
76
|
-
scope.done();
|
|
77
|
-
return (err.status === 404 &&
|
|
78
|
-
err.message === 'Request failed with status code 404' &&
|
|
79
|
-
err.response?.data.error.message === 'File not found');
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
it('should handle AIP-193 error bodies: passes API error in message', async () => {
|
|
83
|
-
const body = {
|
|
84
|
-
error: {
|
|
85
|
-
code: 429,
|
|
86
|
-
message: "The zone 'us-east1-a' does not have enough resources available to fulfill the request. Try a different zone, or try again later.",
|
|
87
|
-
status: 'RESOURCE_EXHAUSTED',
|
|
88
|
-
details: [],
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
const readableStream = Readable.from(JSON.stringify(body));
|
|
92
|
-
const scope = nock(url).get('/').reply(429, readableStream);
|
|
93
|
-
await assert.rejects(request({ url, responseType: 'stream' }), (err) => {
|
|
94
|
-
scope.done();
|
|
95
|
-
const apiError = JSON.parse(err.message);
|
|
96
|
-
return (apiError.error.code === 429 &&
|
|
97
|
-
apiError.error.message ===
|
|
98
|
-
"The zone 'us-east1-a' does not have enough resources available to fulfill the request. Try a different zone, or try again later." &&
|
|
99
|
-
apiError.error.status === 'RESOURCE_EXHAUSTED' &&
|
|
100
|
-
Array.isArray(apiError.error.details) &&
|
|
101
|
-
apiError.error.details.length === 0);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
it('should not throw an error during a translation error', () => {
|
|
105
|
-
const notJSON = '.';
|
|
106
|
-
const response = {
|
|
107
|
-
config: {
|
|
108
|
-
responseType: 'json',
|
|
109
|
-
},
|
|
110
|
-
data: notJSON,
|
|
111
|
-
status: 500,
|
|
112
|
-
statusText: '',
|
|
113
|
-
headers: new Headers(),
|
|
114
|
-
// workaround for `node-fetch`'s `.data` deprecation...
|
|
115
|
-
bodyUsed: true,
|
|
116
|
-
};
|
|
117
|
-
const error = new GaxiosError('translation test', {}, response);
|
|
118
|
-
assert(error.response);
|
|
119
|
-
assert.equal(error.response.data, notJSON);
|
|
120
|
-
});
|
|
121
|
-
it('should support `instanceof` for GaxiosErrors of the same version', () => {
|
|
122
|
-
class A extends GaxiosError {
|
|
123
|
-
}
|
|
124
|
-
const wrongVersion = { [GAXIOS_ERROR_SYMBOL]: '0.0.0' };
|
|
125
|
-
const correctVersion = { [GAXIOS_ERROR_SYMBOL]: pkg.version };
|
|
126
|
-
const child = new A('', {});
|
|
127
|
-
assert.equal(wrongVersion instanceof GaxiosError, false);
|
|
128
|
-
assert.equal(correctVersion instanceof GaxiosError, true);
|
|
129
|
-
assert.equal(child instanceof GaxiosError, true);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe('🥁 configuration options', () => {
|
|
133
|
-
it('should accept `URL` objects', async () => {
|
|
134
|
-
const scope = nock(url).get('/').reply(204);
|
|
135
|
-
const res = await request({ url: new URL(url) });
|
|
136
|
-
scope.done();
|
|
137
|
-
assert.strictEqual(res.status, 204);
|
|
138
|
-
});
|
|
139
|
-
it('should accept `Request` objects', async () => {
|
|
140
|
-
const scope = nock(url).get('/').reply(204);
|
|
141
|
-
const res = await request(new Request(url));
|
|
142
|
-
scope.done();
|
|
143
|
-
assert.strictEqual(res.status, 204);
|
|
144
|
-
});
|
|
145
|
-
it('should use options passed into the constructor', async () => {
|
|
146
|
-
const scope = nock(url).head('/').reply(200);
|
|
147
|
-
const inst = new Gaxios({ method: 'HEAD' });
|
|
148
|
-
const res = await inst.request({ url });
|
|
149
|
-
scope.done();
|
|
150
|
-
assert.strictEqual(res.config.method, 'HEAD');
|
|
151
|
-
});
|
|
152
|
-
it('should handle nested options passed into the constructor', async () => {
|
|
153
|
-
const scope = nock(url).get('/').reply(200);
|
|
154
|
-
const inst = new Gaxios({ headers: new Headers({ apple: 'juice' }) });
|
|
155
|
-
const res = await inst.request({
|
|
156
|
-
url,
|
|
157
|
-
headers: { figgy: 'pudding' },
|
|
158
|
-
});
|
|
159
|
-
scope.done();
|
|
160
|
-
assert.strictEqual(res.config.headers.get('apple'), 'juice');
|
|
161
|
-
assert.strictEqual(res.config.headers.get('figgy'), 'pudding');
|
|
162
|
-
});
|
|
163
|
-
it('should allow setting a base url in the options', async () => {
|
|
164
|
-
const scope = nock(url).get('/v1/mango').reply(200, {});
|
|
165
|
-
const inst = new Gaxios({ baseURL: `${url}/v1/` });
|
|
166
|
-
const res = await inst.request({ url: 'mango' });
|
|
167
|
-
scope.done();
|
|
168
|
-
assert.deepStrictEqual(res.data, {});
|
|
169
|
-
});
|
|
170
|
-
it('should allow overriding valid status', async () => {
|
|
171
|
-
const scope = nock(url).get('/').reply(304);
|
|
172
|
-
const res = await request({ url, validateStatus: () => true });
|
|
173
|
-
scope.done();
|
|
174
|
-
assert.strictEqual(res.status, 304);
|
|
175
|
-
});
|
|
176
|
-
it('should allow setting maxContentLength', async () => {
|
|
177
|
-
const body = { hello: '🌎' };
|
|
178
|
-
const scope = nock(url)
|
|
179
|
-
.get('/')
|
|
180
|
-
.reply(200, body, { 'content-length': body.toString().length.toString() });
|
|
181
|
-
const maxContentLength = 1;
|
|
182
|
-
await assert.rejects(request({ url, maxContentLength }), (err) => {
|
|
183
|
-
return err instanceof GaxiosError && /limit/.test(err.message);
|
|
184
|
-
});
|
|
185
|
-
scope.done();
|
|
186
|
-
});
|
|
187
|
-
it('should support redirects by default', async () => {
|
|
188
|
-
const body = { hello: '🌎' };
|
|
189
|
-
const scopes = [
|
|
190
|
-
nock(url).get('/foo').reply(200, body),
|
|
191
|
-
nock(url).get('/').reply(302, undefined, { location: '/foo' }),
|
|
192
|
-
];
|
|
193
|
-
const res = await request({ url });
|
|
194
|
-
scopes.forEach(x => x.done());
|
|
195
|
-
assert.deepStrictEqual(res.data, body);
|
|
196
|
-
assert.strictEqual(res.url, `${url}/foo`);
|
|
197
|
-
});
|
|
198
|
-
it('should allow overriding the adapter', async () => {
|
|
199
|
-
const response = {
|
|
200
|
-
data: { hello: '🌎' },
|
|
201
|
-
config: {},
|
|
202
|
-
status: 200,
|
|
203
|
-
statusText: 'OK',
|
|
204
|
-
headers: new Headers(),
|
|
205
|
-
};
|
|
206
|
-
const adapter = () => Promise.resolve(response);
|
|
207
|
-
const res = await request({ url, adapter });
|
|
208
|
-
assert.strictEqual(response, res);
|
|
209
|
-
});
|
|
210
|
-
it('should allow overriding the adapter with default adapter wrapper', async () => {
|
|
211
|
-
const body = { hello: '🌎' };
|
|
212
|
-
const extraProperty = '🦦';
|
|
213
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
214
|
-
const timings = [];
|
|
215
|
-
const res = await request({
|
|
216
|
-
url,
|
|
217
|
-
adapter: async (opts, defaultAdapter) => {
|
|
218
|
-
const begin = Date.now();
|
|
219
|
-
const res = await defaultAdapter(opts);
|
|
220
|
-
const end = Date.now();
|
|
221
|
-
res.data = {
|
|
222
|
-
...res.data,
|
|
223
|
-
extraProperty,
|
|
224
|
-
};
|
|
225
|
-
timings.push({ duration: end - begin });
|
|
226
|
-
return res;
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
scope.done();
|
|
230
|
-
assert.deepStrictEqual(res.data, {
|
|
231
|
-
...body,
|
|
232
|
-
extraProperty,
|
|
233
|
-
});
|
|
234
|
-
assert(timings.length === 1);
|
|
235
|
-
assert(typeof timings[0].duration === 'number');
|
|
236
|
-
});
|
|
237
|
-
it('should encode URL parameters', async () => {
|
|
238
|
-
const path = '/?james=kirk&montgomery=scott';
|
|
239
|
-
const opts = { url: `${url}${path}` };
|
|
240
|
-
const scope = nock(url).get(path).reply(200, {});
|
|
241
|
-
const res = await request(opts);
|
|
242
|
-
assert.strictEqual(res.status, 200);
|
|
243
|
-
assert.strictEqual(res.config.url?.toString(), url + path);
|
|
244
|
-
scope.done();
|
|
245
|
-
});
|
|
246
|
-
it('should preserve the original querystring', async () => {
|
|
247
|
-
const path = '/?robot';
|
|
248
|
-
const opts = { url: `${url}${path}` };
|
|
249
|
-
const scope = nock(url).get(path).reply(200, {});
|
|
250
|
-
const res = await request(opts);
|
|
251
|
-
assert.strictEqual(res.status, 200);
|
|
252
|
-
assert.strictEqual(res.config.url?.toString(), url + path);
|
|
253
|
-
scope.done();
|
|
254
|
-
});
|
|
255
|
-
it('should handle empty querystring params', async () => {
|
|
256
|
-
const scope = nock(url).get('/').reply(200, {});
|
|
257
|
-
const res = await request({
|
|
258
|
-
url,
|
|
259
|
-
params: {},
|
|
260
|
-
});
|
|
261
|
-
assert.strictEqual(res.status, 200);
|
|
262
|
-
scope.done();
|
|
263
|
-
});
|
|
264
|
-
it('should encode parameters from the params option', async () => {
|
|
265
|
-
const opts = { url, params: { james: 'kirk', montgomery: 'scott' } };
|
|
266
|
-
const qs = '?james=kirk&montgomery=scott';
|
|
267
|
-
const path = `/${qs}`;
|
|
268
|
-
const scope = nock(url).get(path).reply(200, {});
|
|
269
|
-
const res = await request(opts);
|
|
270
|
-
assert.strictEqual(res.status, 200);
|
|
271
|
-
assert.strictEqual(res.config.url?.toString(), new URL(url + qs).toString());
|
|
272
|
-
scope.done();
|
|
273
|
-
});
|
|
274
|
-
it('should merge URL parameters with the params option', async () => {
|
|
275
|
-
const opts = {
|
|
276
|
-
url: `${url}/?james=beckwith&montgomery=scott`,
|
|
277
|
-
params: { james: 'kirk' },
|
|
278
|
-
};
|
|
279
|
-
const path = '/?james=beckwith&montgomery=scott&james=kirk';
|
|
280
|
-
const scope = nock(url).get(path).reply(200, {});
|
|
281
|
-
const res = await request(opts);
|
|
282
|
-
assert.strictEqual(res.status, 200);
|
|
283
|
-
assert.strictEqual(res.config.url?.toString(), url + path);
|
|
284
|
-
scope.done();
|
|
285
|
-
});
|
|
286
|
-
it('should allow overriding the param serializer', async () => {
|
|
287
|
-
const qs = '?oh=HAI';
|
|
288
|
-
const params = { james: 'kirk' };
|
|
289
|
-
const opts = {
|
|
290
|
-
url,
|
|
291
|
-
params,
|
|
292
|
-
paramsSerializer: ps => {
|
|
293
|
-
assert.strictEqual(JSON.stringify(params), JSON.stringify(ps));
|
|
294
|
-
return '?oh=HAI';
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
const scope = nock(url).get(`/${qs}`).reply(200, {});
|
|
298
|
-
const res = await request(opts);
|
|
299
|
-
assert.strictEqual(res.status, 200);
|
|
300
|
-
assert.strictEqual(res.config.url.toString(), new URL(url + qs).toString());
|
|
301
|
-
scope.done();
|
|
302
|
-
});
|
|
303
|
-
it('should return json by default', async () => {
|
|
304
|
-
const body = { hello: '🌎' };
|
|
305
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
306
|
-
const res = await request({ url });
|
|
307
|
-
scope.done();
|
|
308
|
-
assert.deepStrictEqual(body, res.data);
|
|
309
|
-
});
|
|
310
|
-
it('should send an application/json header by default', async () => {
|
|
311
|
-
const scope = nock(url)
|
|
312
|
-
.matchHeader('accept', 'application/json')
|
|
313
|
-
.get('/')
|
|
314
|
-
.reply(200, {});
|
|
315
|
-
const res = await request({ url, responseType: 'json' });
|
|
316
|
-
scope.done();
|
|
317
|
-
assert.deepStrictEqual(res.data, {});
|
|
318
|
-
});
|
|
319
|
-
describe('proxying', () => {
|
|
320
|
-
const url = 'https://domain.example.com/with-path';
|
|
321
|
-
const proxy = 'https://fake.proxy/';
|
|
322
|
-
let gaxios;
|
|
323
|
-
let request;
|
|
324
|
-
let responseBody;
|
|
325
|
-
let scope;
|
|
326
|
-
beforeEach(() => {
|
|
327
|
-
gaxios = new Gaxios();
|
|
328
|
-
request = gaxios.request.bind(gaxios);
|
|
329
|
-
responseBody = { hello: '🌎' };
|
|
330
|
-
const direct = new URL(url);
|
|
331
|
-
scope = nock(direct.origin).get(direct.pathname).reply(200, responseBody);
|
|
332
|
-
});
|
|
333
|
-
function expectDirect(res) {
|
|
334
|
-
scope.done();
|
|
335
|
-
assert.deepStrictEqual(res.data, responseBody);
|
|
336
|
-
assert.strictEqual(res.config.agent, undefined);
|
|
337
|
-
}
|
|
338
|
-
function expectProxy(res) {
|
|
339
|
-
scope.done();
|
|
340
|
-
assert.deepStrictEqual(res.data, responseBody);
|
|
341
|
-
assert.ok(res.config.agent instanceof HttpsProxyAgent);
|
|
342
|
-
assert.equal(res.config.agent.proxy.toString(), proxy);
|
|
343
|
-
}
|
|
344
|
-
it('should use an https proxy if asked nicely (config)', async () => {
|
|
345
|
-
const res = await request({ url, proxy });
|
|
346
|
-
expectProxy(res);
|
|
347
|
-
});
|
|
348
|
-
it('should use an https proxy if asked nicely (env)', async () => {
|
|
349
|
-
setEnv({ https_proxy: proxy });
|
|
350
|
-
const res = await request({ url });
|
|
351
|
-
expectProxy(res);
|
|
352
|
-
});
|
|
353
|
-
it('should use mTLS with proxy', async () => {
|
|
354
|
-
const cert = 'cert';
|
|
355
|
-
const key = 'key';
|
|
356
|
-
const res = await request({ url, proxy, cert, key });
|
|
357
|
-
expectProxy(res);
|
|
358
|
-
assert(res.config.agent instanceof HttpsProxyAgent);
|
|
359
|
-
assert.equal(res.config.agent.connectOpts.cert, cert);
|
|
360
|
-
assert.equal(res.config.agent.connectOpts.key, key);
|
|
361
|
-
});
|
|
362
|
-
it('should load the proxy from the cache', async () => {
|
|
363
|
-
const res1 = await request({ url, proxy });
|
|
364
|
-
const agent = res1.config.agent;
|
|
365
|
-
expectProxy(res1);
|
|
366
|
-
const direct = new URL(url);
|
|
367
|
-
scope = nock(direct.origin).get(direct.pathname).reply(200, responseBody);
|
|
368
|
-
const res2 = await request({ url, proxy });
|
|
369
|
-
assert.strictEqual(agent, res2.config.agent);
|
|
370
|
-
expectProxy(res2);
|
|
371
|
-
});
|
|
372
|
-
it('should load the proxy from the cache with mTLS', async () => {
|
|
373
|
-
const cert = 'cert';
|
|
374
|
-
const key = 'key';
|
|
375
|
-
const res1 = await request({ url, proxy, cert, key });
|
|
376
|
-
const agent = res1.config.agent;
|
|
377
|
-
expectProxy(res1);
|
|
378
|
-
const direct = new URL(url);
|
|
379
|
-
scope = nock(direct.origin).get(direct.pathname).reply(200, responseBody);
|
|
380
|
-
const res2 = await request({ url, proxy });
|
|
381
|
-
assert.strictEqual(agent, res2.config.agent);
|
|
382
|
-
expectProxy(res2);
|
|
383
|
-
assert(res2.config.agent instanceof HttpsProxyAgent);
|
|
384
|
-
assert.equal(res2.config.agent.connectOpts.cert, cert);
|
|
385
|
-
assert.equal(res2.config.agent.connectOpts.key, key);
|
|
386
|
-
});
|
|
387
|
-
describe('noProxy', () => {
|
|
388
|
-
it('should not proxy when url matches `noProxy` (config > string)', async () => {
|
|
389
|
-
const noProxy = [new URL(url).host];
|
|
390
|
-
const res = await request({ url, proxy, noProxy });
|
|
391
|
-
expectDirect(res);
|
|
392
|
-
});
|
|
393
|
-
it('should not proxy when url matches `noProxy` (config > URL)', async () => {
|
|
394
|
-
// should match by `URL#origin`
|
|
395
|
-
const noProxyURL = new URL(url);
|
|
396
|
-
noProxyURL.pathname = '/some-other-path';
|
|
397
|
-
const noProxy = [noProxyURL];
|
|
398
|
-
const res = await request({ url, proxy, noProxy });
|
|
399
|
-
expectDirect(res);
|
|
400
|
-
});
|
|
401
|
-
it('should not proxy when url matches `noProxy` (config > RegExp)', async () => {
|
|
402
|
-
const noProxy = [/example.com/];
|
|
403
|
-
const res = await request({ url, proxy, noProxy });
|
|
404
|
-
expectDirect(res);
|
|
405
|
-
});
|
|
406
|
-
it('should not proxy when url matches `noProxy` (config + env > match config)', async () => {
|
|
407
|
-
const noProxy = [url];
|
|
408
|
-
setEnv({ no_proxy: 'https://foo.bar' });
|
|
409
|
-
const res = await request({ url, proxy, noProxy });
|
|
410
|
-
expectDirect(res);
|
|
411
|
-
});
|
|
412
|
-
it('should not proxy when url matches `noProxy` (config + env > match env)', async () => {
|
|
413
|
-
const noProxy = ['https://foo.bar'];
|
|
414
|
-
setEnv({ no_proxy: url });
|
|
415
|
-
const res = await request({ url, proxy, noProxy });
|
|
416
|
-
expectDirect(res);
|
|
417
|
-
});
|
|
418
|
-
it('should proxy when url does not match `noProxy` (config > string)', async () => {
|
|
419
|
-
const noProxy = [url];
|
|
420
|
-
const res = await request({ url, proxy, noProxy });
|
|
421
|
-
expectDirect(res);
|
|
422
|
-
});
|
|
423
|
-
it('should proxy if url does not match `noProxy` (config > URL > diff origin > protocol)', async () => {
|
|
424
|
-
const noProxyURL = new URL(url);
|
|
425
|
-
noProxyURL.protocol = 'http:';
|
|
426
|
-
const noProxy = [noProxyURL];
|
|
427
|
-
const res = await request({ url, proxy, noProxy });
|
|
428
|
-
expectProxy(res);
|
|
429
|
-
});
|
|
430
|
-
it('should proxy if url does not match `noProxy` (config > URL > diff origin > port)', async () => {
|
|
431
|
-
const noProxyURL = new URL(url);
|
|
432
|
-
noProxyURL.port = '8443';
|
|
433
|
-
const noProxy = [noProxyURL];
|
|
434
|
-
const res = await request({ url, proxy, noProxy });
|
|
435
|
-
expectProxy(res);
|
|
436
|
-
});
|
|
437
|
-
it('should proxy if url does not match `noProxy` (env)', async () => {
|
|
438
|
-
setEnv({ https_proxy: proxy, no_proxy: 'https://blah' });
|
|
439
|
-
const res = await request({ url });
|
|
440
|
-
expectProxy(res);
|
|
441
|
-
});
|
|
442
|
-
it('should not proxy if `noProxy` env var matches the origin or hostname of the URL (config > string)', async () => {
|
|
443
|
-
const noProxy = [new URL(url).hostname];
|
|
444
|
-
const res = await request({ url, proxy, noProxy });
|
|
445
|
-
expectDirect(res);
|
|
446
|
-
});
|
|
447
|
-
it('should not proxy if `noProxy` env var matches the origin or hostname of the URL (env)', async () => {
|
|
448
|
-
setEnv({ https_proxy: proxy, no_proxy: new URL(url).hostname });
|
|
449
|
-
const res = await request({ url });
|
|
450
|
-
expectDirect(res);
|
|
451
|
-
});
|
|
452
|
-
it('should not proxy if `noProxy` env variable has asterisk, and URL partially matches (config)', async () => {
|
|
453
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
454
|
-
// ensure we have a host for a valid test
|
|
455
|
-
assert(parentHost);
|
|
456
|
-
const noProxy = [`*.${parentHost}`];
|
|
457
|
-
const res = await request({ url, proxy, noProxy });
|
|
458
|
-
expectDirect(res);
|
|
459
|
-
});
|
|
460
|
-
it('should not proxy if `noProxy` env variable has asterisk, and URL partially matches (env)', async () => {
|
|
461
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
462
|
-
// ensure we have a host for a valid test
|
|
463
|
-
assert(parentHost);
|
|
464
|
-
setEnv({ https_proxy: proxy, no_proxy: `*.${parentHost}` });
|
|
465
|
-
const res = await request({ url });
|
|
466
|
-
expectDirect(res);
|
|
467
|
-
});
|
|
468
|
-
it('should not proxy if `noProxy` env variable starts with a dot, and URL partially matches (config)', async () => {
|
|
469
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
470
|
-
// ensure we have a host for a valid test
|
|
471
|
-
assert(parentHost);
|
|
472
|
-
const noProxy = [`.${parentHost}`];
|
|
473
|
-
const res = await request({ url, proxy, noProxy });
|
|
474
|
-
expectDirect(res);
|
|
475
|
-
});
|
|
476
|
-
it('should not proxy if `noProxy` env variable starts with a dot, and URL partially matches (env)', async () => {
|
|
477
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
478
|
-
// ensure we have a host for a valid test
|
|
479
|
-
assert(parentHost);
|
|
480
|
-
setEnv({ https_proxy: proxy, no_proxy: '.example.com' });
|
|
481
|
-
const res = await request({ url });
|
|
482
|
-
expectDirect(res);
|
|
483
|
-
});
|
|
484
|
-
it('should proxy if `noProxy` env variable has asterisk, but URL is not matching (config)', async () => {
|
|
485
|
-
const noProxy = ['*.no.match'];
|
|
486
|
-
const res = await request({ url, proxy, noProxy });
|
|
487
|
-
expectProxy(res);
|
|
488
|
-
});
|
|
489
|
-
it('should proxy if `noProxy` env variable has asterisk, but URL is not matching (env)', async () => {
|
|
490
|
-
setEnv({ https_proxy: proxy, no_proxy: '*.no.match' });
|
|
491
|
-
const res = await request({ url });
|
|
492
|
-
expectProxy(res);
|
|
493
|
-
});
|
|
494
|
-
it('should allow comma-separated lists for `noProxy` env variables (config)', async () => {
|
|
495
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
496
|
-
// ensure we have a host for a valid test
|
|
497
|
-
assert(parentHost);
|
|
498
|
-
const noProxy = ['google.com', `*.${parentHost}`, 'hello.com'];
|
|
499
|
-
const res = await request({ url, proxy, noProxy });
|
|
500
|
-
expectDirect(res);
|
|
501
|
-
});
|
|
502
|
-
it('should allow comma-separated lists for `noProxy` env variables (env)', async () => {
|
|
503
|
-
const parentHost = new URL(url).hostname.split('.').slice(1).join('.');
|
|
504
|
-
// ensure we have a host for a valid test
|
|
505
|
-
assert(parentHost);
|
|
506
|
-
// added spaces to ensure trimming works as expected
|
|
507
|
-
const noProxy = [' google.com ', ` *.${parentHost} `, ' hello.com '];
|
|
508
|
-
setEnv({ https_proxy: proxy, no_proxy: noProxy.join(',') });
|
|
509
|
-
const res = await request({ url });
|
|
510
|
-
expectDirect(res);
|
|
511
|
-
});
|
|
512
|
-
});
|
|
513
|
-
});
|
|
514
|
-
it('should include the request data in the response config', async () => {
|
|
515
|
-
const body = { hello: '🌎' };
|
|
516
|
-
const scope = nock(url).post('/', body).reply(200);
|
|
517
|
-
const res = await request({ url, method: 'POST', data: body });
|
|
518
|
-
scope.done();
|
|
519
|
-
assert.deepStrictEqual(res.config.data, body);
|
|
520
|
-
});
|
|
521
|
-
it('should not stringify the data if it is appended by a form', async () => {
|
|
522
|
-
const formData = new FormData();
|
|
523
|
-
formData.append('test', '123');
|
|
524
|
-
const scope = nock(url)
|
|
525
|
-
.post('/', body => {
|
|
526
|
-
/**
|
|
527
|
-
* Sample from native `node-fetch`
|
|
528
|
-
* body: '------3785545705014550845559551617\r\n' +
|
|
529
|
-
* 'Content-Disposition: form-data; name="test"\r\n' +
|
|
530
|
-
* '\r\n' +
|
|
531
|
-
* '123\r\n' +
|
|
532
|
-
* '------3785545705014550845559551617--',
|
|
533
|
-
*/
|
|
534
|
-
/**
|
|
535
|
-
* Sample from native `fetch`
|
|
536
|
-
* body: '------formdata-undici-0.39470493152687736\r\n' +
|
|
537
|
-
* 'Content-Disposition: form-data; name="test"\r\n' +
|
|
538
|
-
* '\r\n' +
|
|
539
|
-
* '123\r\n' +
|
|
540
|
-
* '------formdata-undici-0.39470493152687736--',
|
|
541
|
-
*/
|
|
542
|
-
return body.match('Content-Disposition: form-data;');
|
|
543
|
-
})
|
|
544
|
-
.reply(200);
|
|
545
|
-
const res = await request({
|
|
546
|
-
url,
|
|
547
|
-
method: 'POST',
|
|
548
|
-
data: formData,
|
|
549
|
-
});
|
|
550
|
-
scope.done();
|
|
551
|
-
assert.deepStrictEqual(res.config.data, formData);
|
|
552
|
-
assert.ok(res.config.body instanceof FormData);
|
|
553
|
-
assert.ok(res.config.data instanceof FormData);
|
|
554
|
-
});
|
|
555
|
-
it('should allow explicitly setting the fetch implementation', async () => {
|
|
556
|
-
let customFetchCalled = false;
|
|
557
|
-
const myFetch = (...args) => {
|
|
558
|
-
customFetchCalled = true;
|
|
559
|
-
return fetch(...args);
|
|
560
|
-
};
|
|
561
|
-
const scope = nock(url).post('/').reply(204);
|
|
562
|
-
const res = await request({
|
|
563
|
-
url,
|
|
564
|
-
method: 'POST',
|
|
565
|
-
fetchImplementation: myFetch,
|
|
566
|
-
// This `data` ensures the 'duplex' option has been set
|
|
567
|
-
data: { sample: 'data' },
|
|
568
|
-
});
|
|
569
|
-
assert(customFetchCalled);
|
|
570
|
-
assert.equal(res.status, 204);
|
|
571
|
-
scope.done();
|
|
572
|
-
});
|
|
573
|
-
it('should be able to disable the `errorRedactor`', async () => {
|
|
574
|
-
const scope = nock(url).get('/').reply(200);
|
|
575
|
-
const instance = new Gaxios({ url, errorRedactor: false });
|
|
576
|
-
assert.equal(instance.defaults.errorRedactor, false);
|
|
577
|
-
await instance.request({ url });
|
|
578
|
-
scope.done();
|
|
579
|
-
assert.equal(instance.defaults.errorRedactor, false);
|
|
580
|
-
});
|
|
581
|
-
it('should be able to set a custom `errorRedactor`', async () => {
|
|
582
|
-
const scope = nock(url).get('/').reply(200);
|
|
583
|
-
const errorRedactor = (t) => t;
|
|
584
|
-
const instance = new Gaxios({ url, errorRedactor });
|
|
585
|
-
assert.equal(instance.defaults.errorRedactor, errorRedactor);
|
|
586
|
-
await instance.request({ url });
|
|
587
|
-
scope.done();
|
|
588
|
-
assert.equal(instance.defaults.errorRedactor, errorRedactor);
|
|
589
|
-
});
|
|
590
|
-
describe('timeout', () => {
|
|
591
|
-
it('should accept and use a `timeout`', async () => {
|
|
592
|
-
nock(url).get('/').delay(2000).reply(204);
|
|
593
|
-
const gaxios = new Gaxios();
|
|
594
|
-
const timeout = 10;
|
|
595
|
-
await assert.rejects(() => gaxios.request({ url, timeout }), /abort/);
|
|
596
|
-
});
|
|
597
|
-
it('should a `timeout`, an existing `signal`, and be triggered by timeout', async () => {
|
|
598
|
-
nock(url).get('/').delay(2000).reply(204);
|
|
599
|
-
const gaxios = new Gaxios();
|
|
600
|
-
const signal = new AbortController().signal;
|
|
601
|
-
const timeout = 10;
|
|
602
|
-
await assert.rejects(() => gaxios.request({ url, timeout, signal }), /abort/);
|
|
603
|
-
});
|
|
604
|
-
it('should use a `timeout`, a `signal`, and be triggered by signal', async () => {
|
|
605
|
-
nock(url).get('/').delay(2000).reply(204);
|
|
606
|
-
const gaxios = new Gaxios();
|
|
607
|
-
const ac = new AbortController();
|
|
608
|
-
const signal = ac.signal;
|
|
609
|
-
const timeout = 4000; // after network delay, so this shouldn't trigger
|
|
610
|
-
const message = 'Changed my mind - no request please';
|
|
611
|
-
setTimeout(() => ac.abort(message), 10);
|
|
612
|
-
await assert.rejects(() => gaxios.request({ url, timeout, signal }),
|
|
613
|
-
// `node-fetch` always rejects with the generic 'abort' error:
|
|
614
|
-
/abort/);
|
|
615
|
-
});
|
|
616
|
-
});
|
|
617
|
-
});
|
|
618
|
-
describe('🎏 data handling', () => {
|
|
619
|
-
it('should accept a ReadableStream as request data', async () => {
|
|
620
|
-
const scope = nock(url).post('/', 'test').reply(200, {});
|
|
621
|
-
const res = await request({
|
|
622
|
-
url,
|
|
623
|
-
method: 'POST',
|
|
624
|
-
data: Readable.from('test'),
|
|
625
|
-
});
|
|
626
|
-
scope.done();
|
|
627
|
-
assert.deepStrictEqual(res.data, {});
|
|
628
|
-
});
|
|
629
|
-
it('should accept a string in the request data', async () => {
|
|
630
|
-
const body = { hello: '🌎' };
|
|
631
|
-
const encoded = new URLSearchParams(body);
|
|
632
|
-
const scope = nock(url)
|
|
633
|
-
.matchHeader('content-type', 'application/x-www-form-urlencoded')
|
|
634
|
-
.post('/', encoded.toString())
|
|
635
|
-
.reply(200, {});
|
|
636
|
-
const res = await request({
|
|
637
|
-
url,
|
|
638
|
-
method: 'POST',
|
|
639
|
-
data: encoded,
|
|
640
|
-
headers: new Headers({
|
|
641
|
-
'content-type': 'application/x-www-form-urlencoded',
|
|
642
|
-
}),
|
|
643
|
-
});
|
|
644
|
-
scope.done();
|
|
645
|
-
assert.deepStrictEqual(res.data, {});
|
|
646
|
-
});
|
|
647
|
-
it('should set application/json content-type for object request by default', async () => {
|
|
648
|
-
const body = { hello: '🌎' };
|
|
649
|
-
const scope = nock(url)
|
|
650
|
-
.matchHeader('Content-Type', 'application/json')
|
|
651
|
-
.post('/', JSON.stringify(body))
|
|
652
|
-
.reply(200, {});
|
|
653
|
-
const res = await request({
|
|
654
|
-
url,
|
|
655
|
-
method: 'POST',
|
|
656
|
-
data: body,
|
|
657
|
-
});
|
|
658
|
-
scope.done();
|
|
659
|
-
assert.deepStrictEqual(res.data, {});
|
|
660
|
-
});
|
|
661
|
-
it('should allow other JSON content-types to be specified', async () => {
|
|
662
|
-
const body = { hello: '🌎' };
|
|
663
|
-
const scope = nock(url)
|
|
664
|
-
.matchHeader('Content-Type', 'application/json-patch+json')
|
|
665
|
-
.post('/', JSON.stringify(body))
|
|
666
|
-
.reply(200, {});
|
|
667
|
-
const res = await request({
|
|
668
|
-
url,
|
|
669
|
-
method: 'POST',
|
|
670
|
-
data: body,
|
|
671
|
-
headers: new Headers({
|
|
672
|
-
'Content-Type': 'application/json-patch+json',
|
|
673
|
-
}),
|
|
674
|
-
});
|
|
675
|
-
scope.done();
|
|
676
|
-
assert.deepStrictEqual(res.data, {});
|
|
677
|
-
});
|
|
678
|
-
it('should stringify with qs when content-type is set to application/x-www-form-urlencoded', async () => {
|
|
679
|
-
const body = { hello: '🌎' };
|
|
680
|
-
const scope = nock(url)
|
|
681
|
-
.matchHeader('Content-Type', 'application/x-www-form-urlencoded')
|
|
682
|
-
.post('/', new URLSearchParams(body).toString())
|
|
683
|
-
.reply(200, {});
|
|
684
|
-
const res = await request({
|
|
685
|
-
url,
|
|
686
|
-
method: 'POST',
|
|
687
|
-
data: body,
|
|
688
|
-
headers: new Headers({
|
|
689
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
690
|
-
}),
|
|
691
|
-
});
|
|
692
|
-
scope.done();
|
|
693
|
-
assert.deepStrictEqual(res.data, {});
|
|
694
|
-
});
|
|
695
|
-
it('should return stream if asked nicely', async () => {
|
|
696
|
-
const body = { hello: '🌎' };
|
|
697
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
698
|
-
const res = await request({ url, responseType: 'stream' });
|
|
699
|
-
scope.done();
|
|
700
|
-
assert(res.data instanceof stream.Readable);
|
|
701
|
-
});
|
|
702
|
-
it('should return a `ReadableStream` when `fetch` has been provided ', async () => {
|
|
703
|
-
const body = { hello: '🌎' };
|
|
704
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
705
|
-
const res = await request({
|
|
706
|
-
url,
|
|
707
|
-
responseType: 'stream',
|
|
708
|
-
fetchImplementation: fetch,
|
|
709
|
-
});
|
|
710
|
-
scope.done();
|
|
711
|
-
assert(res.data instanceof ReadableStream);
|
|
712
|
-
});
|
|
713
|
-
it('should return an ArrayBuffer if asked nicely', async () => {
|
|
714
|
-
const body = { hello: '🌎' };
|
|
715
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
716
|
-
const res = await request({
|
|
717
|
-
url,
|
|
718
|
-
responseType: 'arraybuffer',
|
|
719
|
-
});
|
|
720
|
-
scope.done();
|
|
721
|
-
assert(res.data instanceof ArrayBuffer);
|
|
722
|
-
assert.deepStrictEqual(Buffer.from(JSON.stringify(body)), Buffer.from(res.data));
|
|
723
|
-
});
|
|
724
|
-
it('should return a blob if asked nicely', async () => {
|
|
725
|
-
const body = { hello: '🌎' };
|
|
726
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
727
|
-
const res = await request({ url, responseType: 'blob' });
|
|
728
|
-
scope.done();
|
|
729
|
-
assert.ok(res.data);
|
|
730
|
-
});
|
|
731
|
-
it('should return text if asked nicely', async () => {
|
|
732
|
-
const body = 'hello 🌎';
|
|
733
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
734
|
-
const res = await request({ url, responseType: 'text' });
|
|
735
|
-
scope.done();
|
|
736
|
-
assert.strictEqual(res.data, body);
|
|
737
|
-
});
|
|
738
|
-
it('should return status text', async () => {
|
|
739
|
-
const body = { hello: '🌎' };
|
|
740
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
741
|
-
const res = await request({ url });
|
|
742
|
-
scope.done();
|
|
743
|
-
assert.ok(res.data);
|
|
744
|
-
// node-fetch and native fetch specs differ...
|
|
745
|
-
// https://github.com/node-fetch/node-fetch/issues/1066
|
|
746
|
-
assert.strictEqual(typeof res.statusText, 'string');
|
|
747
|
-
// assert.strictEqual(res.statusText, 'OK');
|
|
748
|
-
});
|
|
749
|
-
it('should return JSON when response Content-Type=application/json', async () => {
|
|
750
|
-
const body = { hello: 'world' };
|
|
751
|
-
const scope = nock(url)
|
|
752
|
-
.get('/')
|
|
753
|
-
.reply(200, body, { 'Content-Type': 'application/json' });
|
|
754
|
-
const res = await request({ url });
|
|
755
|
-
scope.done();
|
|
756
|
-
assert.ok(res.data);
|
|
757
|
-
assert.deepStrictEqual(res.data, body);
|
|
758
|
-
});
|
|
759
|
-
it('should return invalid JSON as text when response Content-Type=application/json', async () => {
|
|
760
|
-
const body = 'hello world';
|
|
761
|
-
const scope = nock(url)
|
|
762
|
-
.get('/')
|
|
763
|
-
.reply(200, body, { 'Content-Type': 'application/json' });
|
|
764
|
-
const res = await request({ url });
|
|
765
|
-
scope.done();
|
|
766
|
-
assert.ok(res.data);
|
|
767
|
-
assert.deepStrictEqual(res.data, body);
|
|
768
|
-
});
|
|
769
|
-
it('should return text when response Content-Type=text/plain', async () => {
|
|
770
|
-
const body = 'hello world';
|
|
771
|
-
const scope = nock(url)
|
|
772
|
-
.get('/')
|
|
773
|
-
.reply(200, body, { 'Content-Type': 'text/plain' });
|
|
774
|
-
const res = await request({ url });
|
|
775
|
-
scope.done();
|
|
776
|
-
assert.ok(res.data);
|
|
777
|
-
assert.deepStrictEqual(res.data, body);
|
|
778
|
-
});
|
|
779
|
-
it('should return text when response Content-Type=text/csv', async () => {
|
|
780
|
-
const body = '"col1","col2"\n"hello","world"';
|
|
781
|
-
const scope = nock(url)
|
|
782
|
-
.get('/')
|
|
783
|
-
.reply(200, body, { 'Content-Type': 'text/csv' });
|
|
784
|
-
const res = await request({ url });
|
|
785
|
-
scope.done();
|
|
786
|
-
assert.ok(res.data);
|
|
787
|
-
assert.deepStrictEqual(res.data, body);
|
|
788
|
-
});
|
|
789
|
-
it('should return raw data when Content-Type is unable to be parsed', async () => {
|
|
790
|
-
const body = Buffer.from('hello world', 'utf-8');
|
|
791
|
-
const scope = nock(url)
|
|
792
|
-
.get('/')
|
|
793
|
-
.reply(200, body, { 'Content-Type': 'image/gif' });
|
|
794
|
-
const res = await request({ url });
|
|
795
|
-
scope.done();
|
|
796
|
-
assert.ok(res.data);
|
|
797
|
-
assert.notEqual(res.data, body);
|
|
798
|
-
});
|
|
799
|
-
it('should handle multipart/related when options.multipart is set and a single part', async () => {
|
|
800
|
-
const bodyContent = { hello: '🌎' };
|
|
801
|
-
const body = new Readable();
|
|
802
|
-
body.push(JSON.stringify(bodyContent));
|
|
803
|
-
body.push(null);
|
|
804
|
-
const scope = nock(url)
|
|
805
|
-
.matchHeader('Content-Type', /multipart\/related; boundary=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)
|
|
806
|
-
.post('/', /^(--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[\r\n]+Content-Type: application\/json[\r\n\r\n]+{"hello":"🌎"}[\r\n]+--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}--)$/)
|
|
807
|
-
.reply(200, {});
|
|
808
|
-
const res = await request({
|
|
809
|
-
url,
|
|
810
|
-
method: 'POST',
|
|
811
|
-
multipart: [
|
|
812
|
-
{
|
|
813
|
-
headers: new Headers({ 'Content-Type': 'application/json' }),
|
|
814
|
-
content: body,
|
|
815
|
-
},
|
|
816
|
-
],
|
|
817
|
-
});
|
|
818
|
-
scope.done();
|
|
819
|
-
assert.ok(res.data);
|
|
820
|
-
});
|
|
821
|
-
it('should handle multipart/related when options.multipart is set and a multiple parts', async () => {
|
|
822
|
-
const jsonContent = { hello: '🌎' };
|
|
823
|
-
const textContent = 'hello world';
|
|
824
|
-
const body = new Readable();
|
|
825
|
-
body.push(JSON.stringify(jsonContent));
|
|
826
|
-
body.push(null);
|
|
827
|
-
const scope = nock(url)
|
|
828
|
-
.matchHeader('Content-Type', /multipart\/related; boundary=[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)
|
|
829
|
-
.post('/', /^(--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[\r\n]+Content-Type: application\/json[\r\n\r\n]+{"hello":"🌎"}[\r\n]+--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[\r\n]+Content-Type: text\/plain[\r\n\r\n]+hello world[\r\n]+--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}--)$/)
|
|
830
|
-
.reply(200, {});
|
|
831
|
-
const res = await request({
|
|
832
|
-
url,
|
|
833
|
-
method: 'POST',
|
|
834
|
-
multipart: [
|
|
835
|
-
{
|
|
836
|
-
headers: new Headers({ 'Content-Type': 'application/json' }),
|
|
837
|
-
content: body,
|
|
838
|
-
},
|
|
839
|
-
{
|
|
840
|
-
headers: new Headers({ 'Content-Type': 'text/plain' }),
|
|
841
|
-
content: textContent,
|
|
842
|
-
},
|
|
843
|
-
],
|
|
844
|
-
});
|
|
845
|
-
scope.done();
|
|
846
|
-
assert.ok(res.data);
|
|
847
|
-
});
|
|
848
|
-
it('should redact sensitive props via the `errorRedactor` by default', async () => {
|
|
849
|
-
const REDACT = '<<REDACTED> - See `errorRedactor` option in `gaxios` for configuration>.';
|
|
850
|
-
const customURL = new URL(url);
|
|
851
|
-
customURL.searchParams.append('token', 'sensitive');
|
|
852
|
-
customURL.searchParams.append('client_secret', 'data');
|
|
853
|
-
customURL.searchParams.append('random', 'non-sensitive');
|
|
854
|
-
const config = {
|
|
855
|
-
headers: {
|
|
856
|
-
Authentication: 'My Auth',
|
|
857
|
-
/**
|
|
858
|
-
* Ensure casing is properly handled
|
|
859
|
-
*/
|
|
860
|
-
AUTHORIZATION: 'My Auth',
|
|
861
|
-
'content-type': 'application/x-www-form-urlencoded',
|
|
862
|
-
random: 'data',
|
|
863
|
-
},
|
|
864
|
-
data: {
|
|
865
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
866
|
-
assertion: 'somesensitivedata',
|
|
867
|
-
unrelated: 'data',
|
|
868
|
-
client_secret: 'data',
|
|
869
|
-
},
|
|
870
|
-
body: 'grant_type=somesensitivedata&assertion=somesensitivedata&client_secret=data',
|
|
871
|
-
};
|
|
872
|
-
// simulate JSON response
|
|
873
|
-
const responseHeaders = {
|
|
874
|
-
...config.headers,
|
|
875
|
-
'content-type': 'application/json',
|
|
876
|
-
};
|
|
877
|
-
const response = { ...config.data };
|
|
878
|
-
const scope = nock(url)
|
|
879
|
-
.post('/')
|
|
880
|
-
.query(() => true)
|
|
881
|
-
.reply(404, response, responseHeaders);
|
|
882
|
-
const instance = new Gaxios(JSON.parse(JSON.stringify(config)));
|
|
883
|
-
const requestConfig = {
|
|
884
|
-
url: customURL.toString(),
|
|
885
|
-
method: 'POST',
|
|
886
|
-
};
|
|
887
|
-
const requestConfigCopy = JSON.parse(JSON.stringify({ ...requestConfig }));
|
|
888
|
-
try {
|
|
889
|
-
await instance.request(requestConfig);
|
|
890
|
-
throw new Error('Expected a GaxiosError');
|
|
891
|
-
}
|
|
892
|
-
catch (e) {
|
|
893
|
-
assert(e instanceof GaxiosError);
|
|
894
|
-
// config should not be mutated
|
|
895
|
-
assert.deepStrictEqual(instance.defaults, config);
|
|
896
|
-
assert.deepStrictEqual(requestConfig, requestConfigCopy);
|
|
897
|
-
assert.notStrictEqual(e.config, config);
|
|
898
|
-
// config redactions - headers
|
|
899
|
-
const expectedRequestHeaders = new Headers({
|
|
900
|
-
...config.headers, // non-redactables should be present
|
|
901
|
-
Authentication: REDACT,
|
|
902
|
-
AUTHORIZATION: REDACT,
|
|
903
|
-
});
|
|
904
|
-
const actualHeaders = e.config.headers;
|
|
905
|
-
expectedRequestHeaders.forEach((value, key) => {
|
|
906
|
-
assert.equal(actualHeaders.get(key), value);
|
|
907
|
-
});
|
|
908
|
-
// config redactions - data
|
|
909
|
-
assert.deepStrictEqual(e.config.data, {
|
|
910
|
-
...config.data, // non-redactables should be present
|
|
911
|
-
grant_type: REDACT,
|
|
912
|
-
assertion: REDACT,
|
|
913
|
-
client_secret: REDACT,
|
|
914
|
-
});
|
|
915
|
-
assert.deepStrictEqual(Object.fromEntries(e.config.body), {
|
|
916
|
-
...config.data, // non-redactables should be present
|
|
917
|
-
grant_type: REDACT,
|
|
918
|
-
assertion: REDACT,
|
|
919
|
-
client_secret: REDACT,
|
|
920
|
-
});
|
|
921
|
-
expectedRequestHeaders.forEach((value, key) => {
|
|
922
|
-
assert.equal(actualHeaders.get(key), value);
|
|
923
|
-
});
|
|
924
|
-
// config redactions - url
|
|
925
|
-
assert(e.config.url);
|
|
926
|
-
const resultURL = new URL(e.config.url);
|
|
927
|
-
assert.notDeepStrictEqual(resultURL.toString(), customURL.toString());
|
|
928
|
-
customURL.searchParams.set('token', REDACT);
|
|
929
|
-
customURL.searchParams.set('client_secret', REDACT);
|
|
930
|
-
assert.deepStrictEqual(resultURL.toString(), customURL.toString());
|
|
931
|
-
// response redactions
|
|
932
|
-
assert(e.response);
|
|
933
|
-
assert.deepStrictEqual(e.response.config, e.config);
|
|
934
|
-
const expectedResponseHeaders = new Headers({
|
|
935
|
-
...responseHeaders, // non-redactables should be present
|
|
936
|
-
});
|
|
937
|
-
expectedResponseHeaders.set('authentication', REDACT);
|
|
938
|
-
expectedResponseHeaders.set('authorization', REDACT);
|
|
939
|
-
expectedResponseHeaders.forEach((value, key) => {
|
|
940
|
-
assert.equal(e.response?.headers.get(key), value);
|
|
941
|
-
});
|
|
942
|
-
assert.deepStrictEqual(e.response.data, {
|
|
943
|
-
...response, // non-redactables should be present
|
|
944
|
-
assertion: REDACT,
|
|
945
|
-
client_secret: REDACT,
|
|
946
|
-
grant_type: REDACT,
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
finally {
|
|
950
|
-
scope.done();
|
|
951
|
-
}
|
|
952
|
-
});
|
|
953
|
-
it('should redact after final retry', async () => {
|
|
954
|
-
const customURL = new URL(url);
|
|
955
|
-
customURL.searchParams.append('token', 'sensitive');
|
|
956
|
-
customURL.searchParams.append('client_secret', 'data');
|
|
957
|
-
customURL.searchParams.append('random', 'non-sensitive');
|
|
958
|
-
const data = {
|
|
959
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
960
|
-
assertion: 'somesensitivedata',
|
|
961
|
-
unrelated: 'data',
|
|
962
|
-
client_secret: 'data',
|
|
963
|
-
};
|
|
964
|
-
let retryAttempted = false;
|
|
965
|
-
const config = {
|
|
966
|
-
url: customURL,
|
|
967
|
-
method: 'POST',
|
|
968
|
-
data: new URLSearchParams(data),
|
|
969
|
-
retry: true,
|
|
970
|
-
retryConfig: {
|
|
971
|
-
httpMethodsToRetry: ['POST'],
|
|
972
|
-
onRetryAttempt: err => {
|
|
973
|
-
assert.deepStrictEqual(err.config.data, new URLSearchParams(data));
|
|
974
|
-
retryAttempted = true;
|
|
975
|
-
},
|
|
976
|
-
},
|
|
977
|
-
};
|
|
978
|
-
const scope = nock(url)
|
|
979
|
-
.post('/', data)
|
|
980
|
-
.query(() => true)
|
|
981
|
-
.reply(500)
|
|
982
|
-
.post('/', data)
|
|
983
|
-
.query(() => true)
|
|
984
|
-
.reply(204);
|
|
985
|
-
const gaxios = new Gaxios();
|
|
986
|
-
try {
|
|
987
|
-
await gaxios.request(config);
|
|
988
|
-
assert(retryAttempted);
|
|
989
|
-
}
|
|
990
|
-
finally {
|
|
991
|
-
scope.done();
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
it('should handle "204 No Content" responses when response type is "json"', async () => {
|
|
995
|
-
const scope = nock(url)
|
|
996
|
-
.matchHeader('content-type', 'application/json')
|
|
997
|
-
.put('/')
|
|
998
|
-
.reply(204, '', { 'Content-Type': 'application/json' });
|
|
999
|
-
const res = await request({
|
|
1000
|
-
url,
|
|
1001
|
-
method: 'PUT',
|
|
1002
|
-
data: {},
|
|
1003
|
-
headers: new Headers({
|
|
1004
|
-
'content-type': 'application/json',
|
|
1005
|
-
accept: 'application/json',
|
|
1006
|
-
}),
|
|
1007
|
-
responseType: 'json',
|
|
1008
|
-
});
|
|
1009
|
-
scope.done();
|
|
1010
|
-
assert.deepStrictEqual(res.data, '');
|
|
1011
|
-
});
|
|
1012
|
-
it('should not throw an error in case of invalid json and "json" response type', async () => {
|
|
1013
|
-
const invalidJsonText = '{foo: 1}', scope = nock(url)
|
|
1014
|
-
.matchHeader('content-type', 'application/json')
|
|
1015
|
-
.put('/')
|
|
1016
|
-
.reply(200, invalidJsonText, { 'Content-Type': 'application/json' });
|
|
1017
|
-
const res = await request({
|
|
1018
|
-
url,
|
|
1019
|
-
method: 'PUT',
|
|
1020
|
-
data: {},
|
|
1021
|
-
headers: new Headers({
|
|
1022
|
-
'content-type': 'application/json',
|
|
1023
|
-
accept: 'application/json',
|
|
1024
|
-
}),
|
|
1025
|
-
responseType: 'json',
|
|
1026
|
-
});
|
|
1027
|
-
scope.done();
|
|
1028
|
-
assert.deepStrictEqual(res.data, invalidJsonText);
|
|
1029
|
-
});
|
|
1030
|
-
});
|
|
1031
|
-
describe('🍂 defaults & instances', () => {
|
|
1032
|
-
it('should allow creating a new instance', () => {
|
|
1033
|
-
const requestInstance = new Gaxios();
|
|
1034
|
-
assert.strictEqual(typeof requestInstance.request, 'function');
|
|
1035
|
-
});
|
|
1036
|
-
it('should allow passing empty options', async () => {
|
|
1037
|
-
const body = { hello: '🌎' };
|
|
1038
|
-
const scope = nock(url).get('/').reply(200, body);
|
|
1039
|
-
const gax = new Gaxios({ url });
|
|
1040
|
-
const res = await gax.request();
|
|
1041
|
-
scope.done();
|
|
1042
|
-
assert.deepStrictEqual(res.data, body);
|
|
1043
|
-
});
|
|
1044
|
-
it('should allow buffer to be posted', async () => {
|
|
1045
|
-
const pkg = fs.readFileSync('./package.json');
|
|
1046
|
-
const pkgJson = JSON.parse(pkg.toString('utf8'));
|
|
1047
|
-
const scope = nock(url)
|
|
1048
|
-
.matchHeader('content-type', 'application/dicom')
|
|
1049
|
-
.post('/', pkgJson)
|
|
1050
|
-
.reply(200, {});
|
|
1051
|
-
const res = await request({
|
|
1052
|
-
url,
|
|
1053
|
-
method: 'POST',
|
|
1054
|
-
data: pkg,
|
|
1055
|
-
headers: new Headers({ 'content-type': 'application/dicom' }),
|
|
1056
|
-
});
|
|
1057
|
-
scope.done();
|
|
1058
|
-
assert.deepStrictEqual(res.data, {});
|
|
1059
|
-
});
|
|
1060
|
-
it('should not set a default content-type for buffers', async () => {
|
|
1061
|
-
const jsonLike = '{}';
|
|
1062
|
-
const data = Buffer.from(jsonLike);
|
|
1063
|
-
const scope = nock(url)
|
|
1064
|
-
// no content type should be present
|
|
1065
|
-
.matchHeader('content-type', v => v === undefined)
|
|
1066
|
-
.post('/', jsonLike)
|
|
1067
|
-
.reply(204);
|
|
1068
|
-
const res = await request({ url, method: 'POST', data });
|
|
1069
|
-
scope.done();
|
|
1070
|
-
assert.equal(res.status, 204);
|
|
1071
|
-
});
|
|
1072
|
-
describe('mtls', () => {
|
|
1073
|
-
class GaxiosAssertAgentCache extends Gaxios {
|
|
1074
|
-
getAgentCache() {
|
|
1075
|
-
return this.agentCache;
|
|
1076
|
-
}
|
|
1077
|
-
async _request(opts) {
|
|
1078
|
-
assert(opts.agent);
|
|
1079
|
-
return super._request(opts);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
it('uses HTTPS agent if cert and key provided, on first request', async () => {
|
|
1083
|
-
const key = fs.readFileSync('./test/fixtures/fake.key', 'utf8');
|
|
1084
|
-
const scope = nock(url).get('/').reply(200);
|
|
1085
|
-
const inst = new GaxiosAssertAgentCache({
|
|
1086
|
-
headers: new Headers({ apple: 'juice' }),
|
|
1087
|
-
cert: fs.readFileSync('./test/fixtures/fake.cert', 'utf8'),
|
|
1088
|
-
key,
|
|
1089
|
-
});
|
|
1090
|
-
const res = await inst.request({
|
|
1091
|
-
url,
|
|
1092
|
-
headers: new Headers({ figgy: 'pudding' }),
|
|
1093
|
-
});
|
|
1094
|
-
scope.done();
|
|
1095
|
-
assert.strictEqual(res.config.headers.get('apple'), 'juice');
|
|
1096
|
-
assert.strictEqual(res.config.headers.get('figgy'), 'pudding');
|
|
1097
|
-
const agentCache = inst.getAgentCache();
|
|
1098
|
-
assert(agentCache.get(key));
|
|
1099
|
-
});
|
|
1100
|
-
it('uses HTTPS agent if cert and key provided, on subsequent requests', async () => {
|
|
1101
|
-
const key = fs.readFileSync('./test/fixtures/fake.key', 'utf8');
|
|
1102
|
-
const scope = nock(url).get('/').reply(200).get('/').reply(200);
|
|
1103
|
-
const inst = new GaxiosAssertAgentCache({
|
|
1104
|
-
headers: new Headers({ apple: 'juice' }),
|
|
1105
|
-
cert: fs.readFileSync('./test/fixtures/fake.cert', 'utf8'),
|
|
1106
|
-
key,
|
|
1107
|
-
});
|
|
1108
|
-
await inst.request({ url, headers: new Headers({ figgy: 'pudding' }) });
|
|
1109
|
-
await inst.request({ url, headers: new Headers({ figgy: 'pudding' }) });
|
|
1110
|
-
scope.done();
|
|
1111
|
-
const agentCache = inst.getAgentCache();
|
|
1112
|
-
assert(agentCache.get(key));
|
|
1113
|
-
});
|
|
1114
|
-
});
|
|
1115
|
-
});
|
|
1116
|
-
describe('interceptors', () => {
|
|
1117
|
-
describe('request', () => {
|
|
1118
|
-
it('should invoke a request interceptor when one is provided', async () => {
|
|
1119
|
-
const scope = nock(url)
|
|
1120
|
-
.matchHeader('hello', 'world')
|
|
1121
|
-
.get('/')
|
|
1122
|
-
.reply(200, {});
|
|
1123
|
-
const instance = new Gaxios();
|
|
1124
|
-
instance.interceptors.request.add({
|
|
1125
|
-
resolved: config => {
|
|
1126
|
-
config.headers.set('hello', 'world');
|
|
1127
|
-
return Promise.resolve(config);
|
|
1128
|
-
},
|
|
1129
|
-
});
|
|
1130
|
-
await instance.request({ url });
|
|
1131
|
-
scope.done();
|
|
1132
|
-
});
|
|
1133
|
-
it('should not invoke a request interceptor after it is removed', async () => {
|
|
1134
|
-
const scope = nock(url).persist().get('/').reply(200, {});
|
|
1135
|
-
const spyFunc = sinon.fake(() => Promise.resolve({
|
|
1136
|
-
url,
|
|
1137
|
-
validateStatus: () => {
|
|
1138
|
-
return true;
|
|
1139
|
-
},
|
|
1140
|
-
}));
|
|
1141
|
-
const instance = new Gaxios();
|
|
1142
|
-
const interceptor = { resolved: spyFunc };
|
|
1143
|
-
instance.interceptors.request.add(interceptor);
|
|
1144
|
-
await instance.request({ url });
|
|
1145
|
-
instance.interceptors.request.delete(interceptor);
|
|
1146
|
-
await instance.request({ url });
|
|
1147
|
-
scope.done();
|
|
1148
|
-
assert.strictEqual(spyFunc.callCount, 1);
|
|
1149
|
-
});
|
|
1150
|
-
it('should invoke multiple request interceptors in the order they were added', async () => {
|
|
1151
|
-
const scope = nock(url)
|
|
1152
|
-
.matchHeader('foo', 'bar')
|
|
1153
|
-
.matchHeader('bar', 'baz')
|
|
1154
|
-
.matchHeader('baz', 'buzz')
|
|
1155
|
-
.get('/')
|
|
1156
|
-
.reply(200, {});
|
|
1157
|
-
const instance = new Gaxios();
|
|
1158
|
-
instance.interceptors.request.add({
|
|
1159
|
-
resolved: config => {
|
|
1160
|
-
config.headers.set('foo', 'bar');
|
|
1161
|
-
return Promise.resolve(config);
|
|
1162
|
-
},
|
|
1163
|
-
});
|
|
1164
|
-
instance.interceptors.request.add({
|
|
1165
|
-
resolved: config => {
|
|
1166
|
-
assert.strictEqual(config.headers.get('foo'), 'bar');
|
|
1167
|
-
config.headers.set('bar', 'baz');
|
|
1168
|
-
return Promise.resolve(config);
|
|
1169
|
-
},
|
|
1170
|
-
});
|
|
1171
|
-
instance.interceptors.request.add({
|
|
1172
|
-
resolved: config => {
|
|
1173
|
-
assert.strictEqual(config.headers.get('foo'), 'bar');
|
|
1174
|
-
assert.strictEqual(config.headers.get('bar'), 'baz');
|
|
1175
|
-
config.headers.set('baz', 'buzz');
|
|
1176
|
-
return Promise.resolve(config);
|
|
1177
|
-
},
|
|
1178
|
-
});
|
|
1179
|
-
await instance.request({ url });
|
|
1180
|
-
scope.done();
|
|
1181
|
-
});
|
|
1182
|
-
it('should not invoke a any request interceptors after they are removed', async () => {
|
|
1183
|
-
const scope = nock(url).persist().get('/').reply(200, {});
|
|
1184
|
-
const spyFunc = sinon.fake(() => Promise.resolve({
|
|
1185
|
-
url,
|
|
1186
|
-
validateStatus: () => {
|
|
1187
|
-
return true;
|
|
1188
|
-
},
|
|
1189
|
-
}));
|
|
1190
|
-
const instance = new Gaxios();
|
|
1191
|
-
instance.interceptors.request.add({
|
|
1192
|
-
resolved: spyFunc,
|
|
1193
|
-
});
|
|
1194
|
-
instance.interceptors.request.add({
|
|
1195
|
-
resolved: spyFunc,
|
|
1196
|
-
});
|
|
1197
|
-
instance.interceptors.request.add({
|
|
1198
|
-
resolved: spyFunc,
|
|
1199
|
-
});
|
|
1200
|
-
await instance.request({ url });
|
|
1201
|
-
instance.interceptors.request.clear();
|
|
1202
|
-
await instance.request({ url });
|
|
1203
|
-
scope.done();
|
|
1204
|
-
assert.strictEqual(spyFunc.callCount, 3);
|
|
1205
|
-
});
|
|
1206
|
-
it('should invoke the rejected function when a previous request interceptor rejects', async () => {
|
|
1207
|
-
const instance = new Gaxios();
|
|
1208
|
-
instance.interceptors.request.add({
|
|
1209
|
-
resolved: () => {
|
|
1210
|
-
throw new Error('Something went wrong');
|
|
1211
|
-
},
|
|
1212
|
-
});
|
|
1213
|
-
instance.interceptors.request.add({
|
|
1214
|
-
resolved: config => {
|
|
1215
|
-
config.headers.set('hello', 'world');
|
|
1216
|
-
return Promise.resolve(config);
|
|
1217
|
-
},
|
|
1218
|
-
rejected: err => {
|
|
1219
|
-
assert.strictEqual(err.message, 'Something went wrong');
|
|
1220
|
-
},
|
|
1221
|
-
});
|
|
1222
|
-
// Because the options wind up being invalid the call will reject with a URL problem.
|
|
1223
|
-
await assert.rejects(instance.request({ url }));
|
|
1224
|
-
});
|
|
1225
|
-
});
|
|
1226
|
-
describe('response', () => {
|
|
1227
|
-
it('should invoke a response interceptor when one is provided', async () => {
|
|
1228
|
-
const scope = nock(url).get('/').reply(200, {});
|
|
1229
|
-
const instance = new Gaxios();
|
|
1230
|
-
instance.interceptors.response.add({
|
|
1231
|
-
resolved(response) {
|
|
1232
|
-
response.headers.set('hello', 'world');
|
|
1233
|
-
return Promise.resolve(response);
|
|
1234
|
-
},
|
|
1235
|
-
});
|
|
1236
|
-
const resp = await instance.request({ url });
|
|
1237
|
-
scope.done();
|
|
1238
|
-
assert.strictEqual(resp.headers.get('hello'), 'world');
|
|
1239
|
-
});
|
|
1240
|
-
it('should not invoke a response interceptor after it is removed', async () => {
|
|
1241
|
-
const scope = nock(url).persist().get('/').reply(200, {});
|
|
1242
|
-
const spyFunc = sinon.fake(() => Promise.resolve({
|
|
1243
|
-
url,
|
|
1244
|
-
validateStatus: () => {
|
|
1245
|
-
return true;
|
|
1246
|
-
},
|
|
1247
|
-
}));
|
|
1248
|
-
const instance = new Gaxios();
|
|
1249
|
-
const interceptor = { resolved: spyFunc };
|
|
1250
|
-
instance.interceptors.response.add(interceptor);
|
|
1251
|
-
await instance.request({ url });
|
|
1252
|
-
instance.interceptors.response.delete(interceptor);
|
|
1253
|
-
await instance.request({ url });
|
|
1254
|
-
scope.done();
|
|
1255
|
-
assert.strictEqual(spyFunc.callCount, 1);
|
|
1256
|
-
});
|
|
1257
|
-
it('should invoke multiple response interceptors in the order they were added', async () => {
|
|
1258
|
-
const scope = nock(url).get('/').reply(200, {});
|
|
1259
|
-
const instance = new Gaxios();
|
|
1260
|
-
instance.interceptors.response.add({
|
|
1261
|
-
resolved: response => {
|
|
1262
|
-
response.headers.set('foo', 'bar');
|
|
1263
|
-
return Promise.resolve(response);
|
|
1264
|
-
},
|
|
1265
|
-
});
|
|
1266
|
-
instance.interceptors.response.add({
|
|
1267
|
-
resolved: response => {
|
|
1268
|
-
assert.strictEqual(response.headers.get('foo'), 'bar');
|
|
1269
|
-
response.headers.set('bar', 'baz');
|
|
1270
|
-
return Promise.resolve(response);
|
|
1271
|
-
},
|
|
1272
|
-
});
|
|
1273
|
-
instance.interceptors.response.add({
|
|
1274
|
-
resolved: response => {
|
|
1275
|
-
assert.strictEqual(response.headers.get('foo'), 'bar');
|
|
1276
|
-
assert.strictEqual(response.headers.get('bar'), 'baz');
|
|
1277
|
-
response.headers.set('baz', 'buzz');
|
|
1278
|
-
return Promise.resolve(response);
|
|
1279
|
-
},
|
|
1280
|
-
});
|
|
1281
|
-
const resp = await instance.request({ url });
|
|
1282
|
-
scope.done();
|
|
1283
|
-
assert.strictEqual(resp.headers.get('foo'), 'bar');
|
|
1284
|
-
assert.strictEqual(resp.headers.get('bar'), 'baz');
|
|
1285
|
-
assert.strictEqual(resp.headers.get('baz'), 'buzz');
|
|
1286
|
-
});
|
|
1287
|
-
it('should not invoke a any response interceptors after they are removed', async () => {
|
|
1288
|
-
const scope = nock(url).persist().get('/').reply(200, {});
|
|
1289
|
-
const spyFunc = sinon.fake(() => Promise.resolve({
|
|
1290
|
-
url,
|
|
1291
|
-
validateStatus: () => {
|
|
1292
|
-
return true;
|
|
1293
|
-
},
|
|
1294
|
-
}));
|
|
1295
|
-
const instance = new Gaxios();
|
|
1296
|
-
instance.interceptors.response.add({
|
|
1297
|
-
resolved: spyFunc,
|
|
1298
|
-
});
|
|
1299
|
-
instance.interceptors.response.add({
|
|
1300
|
-
resolved: spyFunc,
|
|
1301
|
-
});
|
|
1302
|
-
instance.interceptors.response.add({
|
|
1303
|
-
resolved: spyFunc,
|
|
1304
|
-
});
|
|
1305
|
-
await instance.request({ url });
|
|
1306
|
-
instance.interceptors.response.clear();
|
|
1307
|
-
await instance.request({ url });
|
|
1308
|
-
scope.done();
|
|
1309
|
-
assert.strictEqual(spyFunc.callCount, 3);
|
|
1310
|
-
});
|
|
1311
|
-
it('should invoke the rejected function when a request has an error', async () => {
|
|
1312
|
-
const scope = nock(url).get('/').reply(404, {});
|
|
1313
|
-
const instance = new Gaxios();
|
|
1314
|
-
instance.interceptors.response.add({
|
|
1315
|
-
rejected: err => {
|
|
1316
|
-
assert.strictEqual(err.status, 404);
|
|
1317
|
-
},
|
|
1318
|
-
});
|
|
1319
|
-
await instance.request({ url });
|
|
1320
|
-
scope.done();
|
|
1321
|
-
});
|
|
1322
|
-
});
|
|
1323
|
-
});
|
|
1324
|
-
/**
|
|
1325
|
-
* Fetch-compliant API testing.
|
|
1326
|
-
*
|
|
1327
|
-
* Documentation:
|
|
1328
|
-
* - https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
|
|
1329
|
-
* - https://nodejs.org/docs/latest/api/globals.html#fetch
|
|
1330
|
-
*/
|
|
1331
|
-
describe('fetch-compatible API', () => {
|
|
1332
|
-
it('should accept a `string`', async () => {
|
|
1333
|
-
const scope = nock(url).get('/').reply(200, {});
|
|
1334
|
-
const gaxios = new Gaxios();
|
|
1335
|
-
const res = await gaxios.fetch(url);
|
|
1336
|
-
scope.done();
|
|
1337
|
-
assert(typeof url === 'string');
|
|
1338
|
-
assert.deepStrictEqual(res.data, {});
|
|
1339
|
-
});
|
|
1340
|
-
it('should accept a `URL`', async () => {
|
|
1341
|
-
const scope = nock(url).get('/').reply(200, {});
|
|
1342
|
-
const gaxios = new Gaxios();
|
|
1343
|
-
const res = await gaxios.fetch(new URL(url));
|
|
1344
|
-
scope.done();
|
|
1345
|
-
assert.deepStrictEqual(res.data, {});
|
|
1346
|
-
});
|
|
1347
|
-
it('should accept an input with initialization', async () => {
|
|
1348
|
-
const scope = nock(url).post('/', 'abc').reply(200, {});
|
|
1349
|
-
const gaxios = new Gaxios();
|
|
1350
|
-
const res = await gaxios.fetch(url, {
|
|
1351
|
-
body: Buffer.from('abc'),
|
|
1352
|
-
method: 'POST',
|
|
1353
|
-
});
|
|
1354
|
-
scope.done();
|
|
1355
|
-
assert.deepStrictEqual(res.data, {});
|
|
1356
|
-
});
|
|
1357
|
-
it('should accept `GaxiosOptions`', async () => {
|
|
1358
|
-
const scope = nock(url).post('/', 'abc').reply(200, {});
|
|
1359
|
-
const gaxios = new Gaxios();
|
|
1360
|
-
const options = {
|
|
1361
|
-
body: Buffer.from('abc'),
|
|
1362
|
-
method: 'POST',
|
|
1363
|
-
};
|
|
1364
|
-
const res = await gaxios.fetch(url, options);
|
|
1365
|
-
scope.done();
|
|
1366
|
-
assert.deepStrictEqual(res.data, {});
|
|
1367
|
-
});
|
|
1368
|
-
});
|
|
1369
|
-
describe('merge headers', () => {
|
|
1370
|
-
it('should merge Headers', () => {
|
|
1371
|
-
const base = { a: 'a' };
|
|
1372
|
-
const append = { b: 'b' };
|
|
1373
|
-
const expected = new Headers({ ...base, ...append });
|
|
1374
|
-
const matrixBase = [{ ...base }, Object.entries(base), new Headers(base)];
|
|
1375
|
-
const matrixAppend = [
|
|
1376
|
-
{ ...append },
|
|
1377
|
-
Object.entries(append),
|
|
1378
|
-
new Headers(append),
|
|
1379
|
-
];
|
|
1380
|
-
for (const base of matrixBase) {
|
|
1381
|
-
for (const append of matrixAppend) {
|
|
1382
|
-
const headers = Gaxios.mergeHeaders(base, append);
|
|
1383
|
-
assert.deepStrictEqual(headers, expected);
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
});
|
|
1387
|
-
it('should merge multiple Headers', () => {
|
|
1388
|
-
const base = { a: 'a' };
|
|
1389
|
-
const append = { b: 'b' };
|
|
1390
|
-
const appendMore = { c: 'c' };
|
|
1391
|
-
const expected = new Headers({ ...base, ...append, ...appendMore });
|
|
1392
|
-
const headers = Gaxios.mergeHeaders(base, append, appendMore);
|
|
1393
|
-
assert.deepStrictEqual(headers, expected);
|
|
1394
|
-
});
|
|
1395
|
-
it('should merge Set-Cookie Headers', () => {
|
|
1396
|
-
const base = { 'set-cookie': 'a=a' };
|
|
1397
|
-
const append = { 'set-cookie': 'b=b' };
|
|
1398
|
-
const expected = new Headers([
|
|
1399
|
-
['set-cookie', 'a=a'],
|
|
1400
|
-
['set-cookie', 'b=b'],
|
|
1401
|
-
]);
|
|
1402
|
-
const headers = Gaxios.mergeHeaders(base, append);
|
|
1403
|
-
assert.deepStrictEqual(headers.getSetCookie(), expected.getSetCookie());
|
|
1404
|
-
});
|
|
1405
|
-
});
|
|
1406
|
-
//# sourceMappingURL=test.getch.js.map
|