@nangohq/runner-sdk 0.70.6 → 0.70.7
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/action.d.ts +4 -8
- package/dist/action.js +0 -102
- package/dist/action.js.map +1 -1
- package/dist/baseUrlOverrideDenylist.d.ts +11 -11
- package/dist/baseUrlOverrideDenylist.js +46 -26
- package/dist/baseUrlOverrideDenylist.js.map +1 -1
- package/dist/baseUrlOverrideDenylist.unit.test.js +76 -0
- package/dist/baseUrlOverrideDenylist.unit.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/paginate.service.unit.test.js +28 -19
- package/dist/paginate.service.unit.test.js.map +1 -1
- package/dist/uncontrolledFetch.d.ts +17 -0
- package/dist/uncontrolledFetch.js +192 -0
- package/dist/uncontrolledFetch.js.map +1 -0
- package/dist/uncontrolledFetch.unit.test.d.ts +1 -0
- package/dist/uncontrolledFetch.unit.test.js +490 -0
- package/dist/uncontrolledFetch.unit.test.js.map +1 -0
- package/models.d.ts +1 -0
- package/package.json +5 -5
- package/dist/action.uncontrolledFetch.unit.test.js +0 -182
- package/dist/action.uncontrolledFetch.unit.test.js.map +0 -1
- /package/dist/{action.uncontrolledFetch.unit.test.d.ts → baseUrlOverrideDenylist.unit.test.d.ts} +0 -0
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
function makeProps() {
|
|
3
|
+
// Only the fields used by the base constructor are required for these tests.
|
|
4
|
+
return {
|
|
5
|
+
connectionId: 'connection-id',
|
|
6
|
+
environmentId: 1,
|
|
7
|
+
team: { id: 1, name: 'test-team' },
|
|
8
|
+
providerConfigKey: 'provider-config-key',
|
|
9
|
+
activityLogId: 'activity-log-id',
|
|
10
|
+
runnerFlags: {},
|
|
11
|
+
scriptType: 'action',
|
|
12
|
+
isCLI: false
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
async function makeActionInstance() {
|
|
16
|
+
const mod = await import('./action.js');
|
|
17
|
+
const uncontrolledFetchMod = await import('./uncontrolledFetch.js');
|
|
18
|
+
const { NangoActionBase } = mod;
|
|
19
|
+
const { executeUncontrolledFetch } = uncontrolledFetchMod;
|
|
20
|
+
const transfers = [];
|
|
21
|
+
class TestAction extends NangoActionBase {
|
|
22
|
+
// minimal shape for places that may touch user agent
|
|
23
|
+
nango = { userAgent: 'runner-sdk-test' };
|
|
24
|
+
async uncontrolledFetch(options) {
|
|
25
|
+
return executeUncontrolledFetch(options, (p) => transfers.push(p));
|
|
26
|
+
}
|
|
27
|
+
proxy() {
|
|
28
|
+
throw new Error('not implemented');
|
|
29
|
+
}
|
|
30
|
+
log() {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
triggerSync() {
|
|
34
|
+
throw new Error('not implemented');
|
|
35
|
+
}
|
|
36
|
+
startSync() {
|
|
37
|
+
throw new Error('not implemented');
|
|
38
|
+
}
|
|
39
|
+
tryAcquireLock() {
|
|
40
|
+
return Promise.resolve(false);
|
|
41
|
+
}
|
|
42
|
+
async releaseLock() {
|
|
43
|
+
return Promise.resolve(false);
|
|
44
|
+
}
|
|
45
|
+
async releaseAllLocks() {
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
}
|
|
48
|
+
async getCheckpoint() {
|
|
49
|
+
return Promise.resolve(null);
|
|
50
|
+
}
|
|
51
|
+
async saveCheckpoint() {
|
|
52
|
+
return Promise.resolve();
|
|
53
|
+
}
|
|
54
|
+
async clearCheckpoint() {
|
|
55
|
+
return Promise.resolve();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { action: new TestAction(makeProps()), transfers };
|
|
59
|
+
}
|
|
60
|
+
describe('uncontrolledFetch', () => {
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
vi.resetModules();
|
|
63
|
+
vi.unstubAllEnvs();
|
|
64
|
+
});
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
vi.restoreAllMocks();
|
|
67
|
+
vi.unstubAllGlobals();
|
|
68
|
+
vi.unstubAllEnvs();
|
|
69
|
+
});
|
|
70
|
+
it('rejects redirects to non-HTTP(S) schemes', async () => {
|
|
71
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response(null, { status: 302, headers: { Location: 'data:text/plain,hello' } }));
|
|
72
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
73
|
+
const { action } = await makeActionInstance();
|
|
74
|
+
await expect(action.uncontrolledFetch({ url: new URL('https://example.com/start') })).rejects.toMatchObject({
|
|
75
|
+
type: 'action_script_runtime_error',
|
|
76
|
+
payload: { code: 'invalid_redirect' }
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
it('honors NANGO_PROXY_BASE_URL_OVERRIDE_ENABLED=false by ignoring custom denylist env', async () => {
|
|
80
|
+
const customOnlyHost = 'https://custom-deny-only.invalid/path';
|
|
81
|
+
vi.stubEnv('NANGO_PROXY_BASE_URL_OVERRIDE_ENABLED', 'true');
|
|
82
|
+
vi.stubEnv('NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST', JSON.stringify(['custom-deny-only.invalid']));
|
|
83
|
+
const fetchMockEnabled = vi.fn().mockResolvedValue(new Response('ok'));
|
|
84
|
+
vi.stubGlobal('fetch', fetchMockEnabled);
|
|
85
|
+
const { action: actionEnabled } = await makeActionInstance();
|
|
86
|
+
await expect(actionEnabled.uncontrolledFetch({ url: new URL(customOnlyHost) })).rejects.toMatchObject({
|
|
87
|
+
type: 'action_script_runtime_error',
|
|
88
|
+
payload: { code: 'url_not_allowed' }
|
|
89
|
+
});
|
|
90
|
+
expect(fetchMockEnabled).not.toHaveBeenCalled();
|
|
91
|
+
vi.resetModules();
|
|
92
|
+
vi.unstubAllEnvs();
|
|
93
|
+
vi.stubEnv('NANGO_PROXY_BASE_URL_OVERRIDE_ENABLED', 'false');
|
|
94
|
+
vi.stubEnv('NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST', JSON.stringify(['custom-deny-only.invalid']));
|
|
95
|
+
const fetchMockDisabled = vi.fn().mockResolvedValue(new Response('ok'));
|
|
96
|
+
vi.stubGlobal('fetch', fetchMockDisabled);
|
|
97
|
+
const { action: actionDisabled } = await makeActionInstance();
|
|
98
|
+
await expect(actionDisabled.uncontrolledFetch({ url: new URL(customOnlyHost) })).resolves.toBeDefined();
|
|
99
|
+
expect(fetchMockDisabled).toHaveBeenCalled();
|
|
100
|
+
});
|
|
101
|
+
it('blocks a redirect hop to a denylisted host', async () => {
|
|
102
|
+
vi.stubEnv('NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST', JSON.stringify(['metadata.google.internal']));
|
|
103
|
+
const fetchMock = vi
|
|
104
|
+
.fn()
|
|
105
|
+
.mockResolvedValue(new Response(null, { status: 302, headers: { Location: 'https://metadata.google.internal/latest/meta-data/' } }));
|
|
106
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
107
|
+
const { action } = await makeActionInstance();
|
|
108
|
+
await expect(action.uncontrolledFetch({
|
|
109
|
+
url: new URL('https://example.com/start')
|
|
110
|
+
})).rejects.toMatchObject({ type: 'action_script_runtime_error', payload: { code: 'url_not_allowed' } });
|
|
111
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
112
|
+
});
|
|
113
|
+
it('strips sensitive headers when redirecting to a different origin', async () => {
|
|
114
|
+
const fetchMock = vi
|
|
115
|
+
.fn()
|
|
116
|
+
.mockResolvedValueOnce(new Response(null, { status: 302, headers: { Location: 'https://b.example/next' } }))
|
|
117
|
+
.mockResolvedValueOnce(new Response('ok', { status: 200 }));
|
|
118
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
119
|
+
const { action } = await makeActionInstance();
|
|
120
|
+
const res = await action.uncontrolledFetch({
|
|
121
|
+
url: new URL('https://a.example/start'),
|
|
122
|
+
headers: { Authorization: 'Bearer secret', 'X-Test': '1' }
|
|
123
|
+
});
|
|
124
|
+
expect(await res.text()).toBe('ok');
|
|
125
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
126
|
+
const secondCallInit = fetchMock.mock.calls[1][1];
|
|
127
|
+
const headers = secondCallInit.headers;
|
|
128
|
+
expect(headers.get('authorization')).toBeNull();
|
|
129
|
+
expect(headers.get('cookie')).toBeNull();
|
|
130
|
+
expect(headers.get('proxy-authorization')).toBeNull();
|
|
131
|
+
expect(headers.get('x-test')).toBe('1');
|
|
132
|
+
});
|
|
133
|
+
it('preserves redirect response body when status is 3xx without Location', async () => {
|
|
134
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response('diagnostic payload', { status: 302 }));
|
|
135
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
136
|
+
const { action } = await makeActionInstance();
|
|
137
|
+
const res = await action.uncontrolledFetch({ url: new URL('https://example.com/redirect-without-location') });
|
|
138
|
+
expect(res.status).toBe(302);
|
|
139
|
+
expect(await res.text()).toBe('diagnostic payload');
|
|
140
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
141
|
+
});
|
|
142
|
+
it('preserves non-POST methods on 301/302 redirects (e.g. PUT)', async () => {
|
|
143
|
+
const fetchMock = vi
|
|
144
|
+
.fn()
|
|
145
|
+
.mockResolvedValueOnce(new Response(null, { status: 301, headers: { Location: 'https://example.com/next' } }))
|
|
146
|
+
.mockResolvedValueOnce(new Response('ok', { status: 200 }));
|
|
147
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
148
|
+
const { action } = await makeActionInstance();
|
|
149
|
+
const res = await action.uncontrolledFetch({
|
|
150
|
+
url: new URL('https://example.com/start'),
|
|
151
|
+
method: 'PUT',
|
|
152
|
+
body: 'body',
|
|
153
|
+
headers: { 'content-type': 'text/plain' }
|
|
154
|
+
});
|
|
155
|
+
expect(await res.text()).toBe('ok');
|
|
156
|
+
const secondCallInit = fetchMock.mock.calls[1][1];
|
|
157
|
+
expect(secondCallInit.method).toBe('PUT');
|
|
158
|
+
expect(secondCallInit.body).toBe('body');
|
|
159
|
+
expect(secondCallInit.headers.get('content-type')).toBe('text/plain');
|
|
160
|
+
});
|
|
161
|
+
it('rewrites POST to GET on 302 and drops request-body headers', async () => {
|
|
162
|
+
const fetchMock = vi
|
|
163
|
+
.fn()
|
|
164
|
+
.mockResolvedValueOnce(new Response(null, { status: 302, headers: { Location: 'https://example.com/next' } }))
|
|
165
|
+
.mockResolvedValueOnce(new Response('ok', { status: 200 }));
|
|
166
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
167
|
+
const { action } = await makeActionInstance();
|
|
168
|
+
const res = await action.uncontrolledFetch({
|
|
169
|
+
url: new URL('https://example.com/start'),
|
|
170
|
+
method: 'POST',
|
|
171
|
+
body: 'hello',
|
|
172
|
+
headers: {
|
|
173
|
+
'content-type': 'application/json',
|
|
174
|
+
'content-language': 'en',
|
|
175
|
+
'content-encoding': 'gzip',
|
|
176
|
+
'x-test': '1'
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
expect(await res.text()).toBe('ok');
|
|
180
|
+
const secondCallInit = fetchMock.mock.calls[1][1];
|
|
181
|
+
expect(secondCallInit.method).toBe('GET');
|
|
182
|
+
expect(secondCallInit.body).toBeUndefined();
|
|
183
|
+
const headers = secondCallInit.headers;
|
|
184
|
+
expect(headers.get('content-type')).toBeNull();
|
|
185
|
+
expect(headers.get('content-language')).toBeNull();
|
|
186
|
+
expect(headers.get('content-encoding')).toBeNull();
|
|
187
|
+
expect(headers.get('x-test')).toBe('1');
|
|
188
|
+
});
|
|
189
|
+
it('preserves GET on 303 redirects (no forced rewrite)', async () => {
|
|
190
|
+
const fetchMock = vi
|
|
191
|
+
.fn()
|
|
192
|
+
.mockResolvedValueOnce(new Response(null, { status: 303, headers: { Location: 'https://example.com/next' } }))
|
|
193
|
+
.mockResolvedValueOnce(new Response(null, { status: 200 }));
|
|
194
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
195
|
+
const { action } = await makeActionInstance();
|
|
196
|
+
const res = await action.uncontrolledFetch({
|
|
197
|
+
url: new URL('https://example.com/start'),
|
|
198
|
+
method: 'GET',
|
|
199
|
+
headers: { authorization: 'Bearer secret' }
|
|
200
|
+
});
|
|
201
|
+
expect(res.status).toBe(200);
|
|
202
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
203
|
+
const secondCallInit = fetchMock.mock.calls[1][1];
|
|
204
|
+
expect(secondCallInit.method).toBe('GET');
|
|
205
|
+
expect(secondCallInit.body).toBeUndefined();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe('uncontrolledFetch byte metering helpers', () => {
|
|
209
|
+
it('parseContentLength returns null for missing header', async () => {
|
|
210
|
+
const { parseContentLength } = await import('./uncontrolledFetch.js');
|
|
211
|
+
expect(parseContentLength(new Headers())).toBeNull();
|
|
212
|
+
});
|
|
213
|
+
it('parseContentLength returns null for non-numeric value', async () => {
|
|
214
|
+
const { parseContentLength } = await import('./uncontrolledFetch.js');
|
|
215
|
+
expect(parseContentLength(new Headers({ 'content-length': 'abc' }))).toBeNull();
|
|
216
|
+
});
|
|
217
|
+
it('parseContentLength returns null for negative value', async () => {
|
|
218
|
+
const { parseContentLength } = await import('./uncontrolledFetch.js');
|
|
219
|
+
expect(parseContentLength(new Headers({ 'content-length': '-1' }))).toBeNull();
|
|
220
|
+
});
|
|
221
|
+
it('parseContentLength returns integer for valid value', async () => {
|
|
222
|
+
const { parseContentLength } = await import('./uncontrolledFetch.js');
|
|
223
|
+
expect(parseContentLength(new Headers({ 'content-length': '42' }))).toBe(42);
|
|
224
|
+
expect(parseContentLength(new Headers({ 'content-length': '0' }))).toBe(0);
|
|
225
|
+
});
|
|
226
|
+
it('countRequestBytes includes body bytes', async () => {
|
|
227
|
+
const { countRequestBytes } = await import('./uncontrolledFetch.js');
|
|
228
|
+
const body = 'hello world';
|
|
229
|
+
const withBody = countRequestBytes(new Headers(), body);
|
|
230
|
+
const withoutBody = countRequestBytes(new Headers());
|
|
231
|
+
expect(withBody - withoutBody).toBe(Buffer.byteLength(body, 'utf8'));
|
|
232
|
+
});
|
|
233
|
+
it('countRequestBytes includes caller-set header name and value bytes', async () => {
|
|
234
|
+
const { countRequestBytes } = await import('./uncontrolledFetch.js');
|
|
235
|
+
const headers = new Headers({ 'x-custom': 'value', 'content-type': 'application/json' });
|
|
236
|
+
const withHeaders = countRequestBytes(headers);
|
|
237
|
+
const withoutHeaders = countRequestBytes(new Headers());
|
|
238
|
+
const expectedDelta = Buffer.byteLength('x-custom', 'utf8') +
|
|
239
|
+
Buffer.byteLength('value', 'utf8') +
|
|
240
|
+
Buffer.byteLength('content-type', 'utf8') +
|
|
241
|
+
Buffer.byteLength('application/json', 'utf8');
|
|
242
|
+
expect(withHeaders - withoutHeaders).toBe(expectedDelta);
|
|
243
|
+
});
|
|
244
|
+
it('countHeaderBytes sums response header name and value bytes', async () => {
|
|
245
|
+
const { countHeaderBytes } = await import('./uncontrolledFetch.js');
|
|
246
|
+
const headers = new Headers({ 'content-type': 'application/json', 'x-req-id': 'abc' });
|
|
247
|
+
const bytes = countHeaderBytes(headers);
|
|
248
|
+
const expected = Buffer.byteLength('content-type', 'utf8') +
|
|
249
|
+
Buffer.byteLength('application/json', 'utf8') +
|
|
250
|
+
Buffer.byteLength('x-req-id', 'utf8') +
|
|
251
|
+
Buffer.byteLength('abc', 'utf8');
|
|
252
|
+
expect(bytes).toBe(expected);
|
|
253
|
+
});
|
|
254
|
+
it('tapResponseStreamAndCount returns original response when body is null', async () => {
|
|
255
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
256
|
+
const response = new Response(null);
|
|
257
|
+
const callback = vi.fn();
|
|
258
|
+
const returned = tapResponseStreamAndCount(response, callback);
|
|
259
|
+
expect(returned).toBe(response);
|
|
260
|
+
expect(callback).not.toHaveBeenCalled();
|
|
261
|
+
});
|
|
262
|
+
it('tapResponseStreamAndCount wraps stream and calls callback with bytes on consumption', async () => {
|
|
263
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
264
|
+
const body = 'streamed content';
|
|
265
|
+
const response = new Response(body);
|
|
266
|
+
const calls = [];
|
|
267
|
+
const callback = (p) => calls.push(p);
|
|
268
|
+
const wrapped = tapResponseStreamAndCount(response, callback);
|
|
269
|
+
expect(wrapped).not.toBe(response);
|
|
270
|
+
const text = await wrapped.text();
|
|
271
|
+
expect(text).toBe(body);
|
|
272
|
+
expect(calls.length).toBe(1);
|
|
273
|
+
expect(calls[0].bytes).toBe(Buffer.byteLength(body, 'utf8'));
|
|
274
|
+
});
|
|
275
|
+
it('tapResponseStreamAndCount calls callback with 0 bytes for empty body stream', async () => {
|
|
276
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
277
|
+
const response = new Response('');
|
|
278
|
+
const calls = [];
|
|
279
|
+
const callback = (p) => calls.push(p);
|
|
280
|
+
const wrapped = tapResponseStreamAndCount(response, callback);
|
|
281
|
+
await wrapped.text();
|
|
282
|
+
expect(calls.length).toBe(1);
|
|
283
|
+
expect(calls[0].bytes).toBe(0);
|
|
284
|
+
});
|
|
285
|
+
it('tapResponseStreamAndCount preserves status and headers on wrapped response', async () => {
|
|
286
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
287
|
+
const response = new Response('body', { status: 206, headers: { 'x-custom': 'val' } });
|
|
288
|
+
const wrapped = tapResponseStreamAndCount(response, vi.fn());
|
|
289
|
+
expect(wrapped.status).toBe(206);
|
|
290
|
+
expect(wrapped.headers.get('x-custom')).toBe('val');
|
|
291
|
+
});
|
|
292
|
+
it('tapResponseStreamAndCount preserves url and type from original response', async () => {
|
|
293
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
294
|
+
const response = new Response('body');
|
|
295
|
+
const wrapped = tapResponseStreamAndCount(response, vi.fn());
|
|
296
|
+
expect(wrapped.url).toBe(response.url);
|
|
297
|
+
expect(wrapped.type).toBe(response.type);
|
|
298
|
+
});
|
|
299
|
+
it('tapResponseStreamAndCount clone reads body correctly', async () => {
|
|
300
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
301
|
+
const body = 'cloned content';
|
|
302
|
+
const response = new Response(body);
|
|
303
|
+
const wrapped = tapResponseStreamAndCount(response, vi.fn());
|
|
304
|
+
const cloned = wrapped.clone();
|
|
305
|
+
expect(await cloned.text()).toBe(body);
|
|
306
|
+
});
|
|
307
|
+
it('tapResponseStreamAndCount bytes() reads from tapped stream, not locked original', async () => {
|
|
308
|
+
const { tapResponseStreamAndCount } = await import('./uncontrolledFetch.js');
|
|
309
|
+
const body = 'bytes content';
|
|
310
|
+
const response = new Response(body);
|
|
311
|
+
const calls = [];
|
|
312
|
+
const wrapped = tapResponseStreamAndCount(response, (p) => calls.push(p));
|
|
313
|
+
if (typeof wrapped.bytes !== 'function') {
|
|
314
|
+
return; // runtime does not implement bytes() — skip
|
|
315
|
+
}
|
|
316
|
+
const result = await wrapped.bytes();
|
|
317
|
+
expect(result).toBeInstanceOf(Uint8Array);
|
|
318
|
+
expect(Buffer.from(result).toString('utf8')).toBe(body);
|
|
319
|
+
expect(calls.length).toBe(1);
|
|
320
|
+
expect(calls[0].bytes).toBe(Buffer.byteLength(body, 'utf8'));
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
describe('uncontrolledFetch transfer metering', () => {
|
|
324
|
+
beforeEach(() => {
|
|
325
|
+
vi.resetModules();
|
|
326
|
+
vi.unstubAllEnvs();
|
|
327
|
+
});
|
|
328
|
+
afterEach(() => {
|
|
329
|
+
vi.restoreAllMocks();
|
|
330
|
+
vi.unstubAllGlobals();
|
|
331
|
+
vi.unstubAllEnvs();
|
|
332
|
+
});
|
|
333
|
+
it('records request and response transfer bytes for a simple GET', async () => {
|
|
334
|
+
const responseBody = 'hello';
|
|
335
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response(responseBody, {
|
|
336
|
+
status: 200,
|
|
337
|
+
headers: { 'content-length': String(Buffer.byteLength(responseBody, 'utf8')) }
|
|
338
|
+
}));
|
|
339
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
340
|
+
const { action, transfers } = await makeActionInstance();
|
|
341
|
+
await action.uncontrolledFetch({
|
|
342
|
+
url: new URL('https://example.com/data'),
|
|
343
|
+
headers: { 'x-test': '1' }
|
|
344
|
+
});
|
|
345
|
+
expect(transfers.length).toBe(1);
|
|
346
|
+
expect(transfers[0].bytesSent).toBeGreaterThan(0);
|
|
347
|
+
expect(transfers[0].bytesReceived).toBeGreaterThanOrEqual(Buffer.byteLength(responseBody, 'utf8'));
|
|
348
|
+
});
|
|
349
|
+
it('records request bytes for POST with body', async () => {
|
|
350
|
+
const body = '{"key":"value"}';
|
|
351
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response('ok', { status: 200, headers: { 'content-length': '2' } }));
|
|
352
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
353
|
+
const { action, transfers } = await makeActionInstance();
|
|
354
|
+
await action.uncontrolledFetch({
|
|
355
|
+
url: new URL('https://example.com/api'),
|
|
356
|
+
method: 'POST',
|
|
357
|
+
body,
|
|
358
|
+
headers: { 'content-type': 'application/json' }
|
|
359
|
+
});
|
|
360
|
+
expect(transfers.length).toBe(1);
|
|
361
|
+
expect(transfers[0].bytesSent).toBeGreaterThanOrEqual(Buffer.byteLength(body, 'utf8'));
|
|
362
|
+
});
|
|
363
|
+
it('records transfer bytes for each hop on redirect, POST body dropped on 302', async () => {
|
|
364
|
+
const fetchMock = vi
|
|
365
|
+
.fn()
|
|
366
|
+
.mockResolvedValueOnce(new Response(null, { status: 302, headers: { Location: 'https://example.com/next' } }))
|
|
367
|
+
.mockResolvedValueOnce(new Response('done', { status: 200, headers: { 'content-length': '4' } }));
|
|
368
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
369
|
+
const { action, transfers } = await makeActionInstance();
|
|
370
|
+
await action.uncontrolledFetch({
|
|
371
|
+
url: new URL('https://example.com/start'),
|
|
372
|
+
method: 'POST',
|
|
373
|
+
body: 'hello',
|
|
374
|
+
headers: { 'content-type': 'text/plain', 'x-hop': '1' }
|
|
375
|
+
});
|
|
376
|
+
// Two records: one per hop
|
|
377
|
+
expect(transfers.length).toBe(2);
|
|
378
|
+
// First hop is POST with body — more bytesSent than second hop (GET, no body)
|
|
379
|
+
expect(transfers[0].bytesSent).toBeGreaterThan(transfers[1].bytesSent);
|
|
380
|
+
expect(transfers[1].bytesSent).toBeGreaterThan(0);
|
|
381
|
+
// Both hops have response headers
|
|
382
|
+
expect(transfers[0].bytesReceived).toBeGreaterThan(0);
|
|
383
|
+
expect(transfers[1].bytesReceived).toBeGreaterThan(0);
|
|
384
|
+
});
|
|
385
|
+
it('does not count redirect response Content-Length in bytesReceived', async () => {
|
|
386
|
+
const largeContentLength = 1_000_000; // 1 MB body that is never consumed
|
|
387
|
+
const fetchMock = vi
|
|
388
|
+
.fn()
|
|
389
|
+
.mockResolvedValueOnce(new Response(null, {
|
|
390
|
+
status: 302,
|
|
391
|
+
headers: { Location: 'https://example.com/next', 'content-length': String(largeContentLength) }
|
|
392
|
+
}))
|
|
393
|
+
.mockResolvedValueOnce(new Response('ok', { status: 200 }));
|
|
394
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
395
|
+
const { action, transfers } = await makeActionInstance();
|
|
396
|
+
await action.uncontrolledFetch({ url: new URL('https://example.com/start') });
|
|
397
|
+
expect(transfers.length).toBe(2);
|
|
398
|
+
// Redirect hop must only count header bytes, not the body Content-Length.
|
|
399
|
+
expect(transfers[0].bytesReceived).toBeLessThan(largeContentLength);
|
|
400
|
+
});
|
|
401
|
+
it('records streamed response body bytes when Content-Length is absent', async () => {
|
|
402
|
+
const responseBody = 'streaming data here';
|
|
403
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response(responseBody)); // no Content-Length
|
|
404
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
405
|
+
const { action, transfers } = await makeActionInstance();
|
|
406
|
+
const res = await action.uncontrolledFetch({ url: new URL('https://example.com/stream') });
|
|
407
|
+
// Consume body to trigger streamed byte count
|
|
408
|
+
await res.text();
|
|
409
|
+
// Two records: (1) request+headers emitted immediately, (2) body bytes on stream flush
|
|
410
|
+
expect(transfers.length).toBe(2);
|
|
411
|
+
expect(transfers[0].bytesSent).toBeGreaterThanOrEqual(0);
|
|
412
|
+
expect(transfers[0].bytesReceived).toBeGreaterThan(0);
|
|
413
|
+
expect(transfers[1].bytesSent).toBe(0);
|
|
414
|
+
expect(transfers[1].bytesReceived).toBe(Buffer.byteLength(responseBody, 'utf8'));
|
|
415
|
+
});
|
|
416
|
+
it.each([
|
|
417
|
+
{ method: 'HEAD', status: 200 },
|
|
418
|
+
{ method: 'GET', status: 204 },
|
|
419
|
+
{ method: 'GET', status: 304 }
|
|
420
|
+
])('does not count Content-Length as body bytes when response.body is null ($method $status)', async ({ method, status }) => {
|
|
421
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response(null, {
|
|
422
|
+
status,
|
|
423
|
+
headers: { 'content-length': '1000000' }
|
|
424
|
+
}));
|
|
425
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
426
|
+
const { action, transfers } = await makeActionInstance();
|
|
427
|
+
await action.uncontrolledFetch({ url: new URL('https://example.com/resource'), method });
|
|
428
|
+
expect(transfers.length).toBe(1);
|
|
429
|
+
// Only header bytes counted — Content-Length must not be added
|
|
430
|
+
expect(transfers[0].bytesReceived).toBeLessThan(1000000);
|
|
431
|
+
});
|
|
432
|
+
it('implementation with no-op telemetry callback does not throw and emits no transfers', async () => {
|
|
433
|
+
const mod = await import('./action.js');
|
|
434
|
+
const uncontrolledFetchMod = await import('./uncontrolledFetch.js');
|
|
435
|
+
const { NangoActionBase } = mod;
|
|
436
|
+
const { executeUncontrolledFetch } = uncontrolledFetchMod;
|
|
437
|
+
class NoOpTestAction extends NangoActionBase {
|
|
438
|
+
nango = { userAgent: 'test' };
|
|
439
|
+
async uncontrolledFetch(options) {
|
|
440
|
+
return executeUncontrolledFetch(options, () => { });
|
|
441
|
+
}
|
|
442
|
+
proxy() {
|
|
443
|
+
throw new Error('not implemented');
|
|
444
|
+
}
|
|
445
|
+
log() {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
triggerSync() {
|
|
449
|
+
throw new Error('not implemented');
|
|
450
|
+
}
|
|
451
|
+
startSync() {
|
|
452
|
+
throw new Error('not implemented');
|
|
453
|
+
}
|
|
454
|
+
tryAcquireLock() {
|
|
455
|
+
return Promise.resolve(false);
|
|
456
|
+
}
|
|
457
|
+
releaseLock() {
|
|
458
|
+
return Promise.resolve(false);
|
|
459
|
+
}
|
|
460
|
+
releaseAllLocks() {
|
|
461
|
+
return Promise.resolve();
|
|
462
|
+
}
|
|
463
|
+
getCheckpoint() {
|
|
464
|
+
return Promise.resolve();
|
|
465
|
+
}
|
|
466
|
+
saveCheckpoint() {
|
|
467
|
+
return Promise.resolve();
|
|
468
|
+
}
|
|
469
|
+
clearCheckpoint() {
|
|
470
|
+
return Promise.resolve();
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response('ok', { status: 200, headers: { 'content-length': '2' } }));
|
|
474
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
475
|
+
const props = {
|
|
476
|
+
connectionId: 'c',
|
|
477
|
+
environmentId: 1,
|
|
478
|
+
team: { id: 1, name: 'test-team' },
|
|
479
|
+
providerConfigKey: 'p',
|
|
480
|
+
activityLogId: 'a',
|
|
481
|
+
runnerFlags: {},
|
|
482
|
+
scriptType: 'action',
|
|
483
|
+
isCLI: false
|
|
484
|
+
};
|
|
485
|
+
const action = new NoOpTestAction(props);
|
|
486
|
+
// Should not throw even though hook is a no-op
|
|
487
|
+
await expect(action.uncontrolledFetch({ url: new URL('https://example.com/') })).resolves.toBeDefined();
|
|
488
|
+
});
|
|
489
|
+
});
|
|
490
|
+
//# sourceMappingURL=uncontrolledFetch.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uncontrolledFetch.unit.test.js","sourceRoot":"","sources":["../lib/uncontrolledFetch.unit.test.ts"],"names":[],"mappings":"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"}
|
package/models.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nangohq/runner-sdk",
|
|
3
|
-
"version": "0.70.
|
|
3
|
+
"version": "0.70.7",
|
|
4
4
|
"description": "Nango's Runner SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
"directory": "packages/runner-sdk"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nangohq/node": "0.70.
|
|
14
|
-
"@nangohq/providers": "0.70.
|
|
13
|
+
"@nangohq/node": "0.70.7",
|
|
14
|
+
"@nangohq/providers": "0.70.7",
|
|
15
15
|
"ajv": "8.18.0",
|
|
16
16
|
"ajv-formats": "3.0.1",
|
|
17
17
|
"lodash-es": "4.18.1",
|
|
18
18
|
"parse-link-header": "2.0.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@nangohq/types": "0.70.
|
|
21
|
+
"@nangohq/types": "0.70.7",
|
|
22
22
|
"@types/json-schema": "7.0.15",
|
|
23
23
|
"axios": "1.16.1",
|
|
24
24
|
"json-schema": "0.4.0",
|
|
25
|
-
"vitest": "
|
|
25
|
+
"vitest": "4.1.8"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"zod": "4.3.6"
|