@tryfinch/finch-api 5.1.0 → 5.3.0
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/CHANGELOG.md +43 -0
- package/README.md +28 -21
- package/_shims/MultipartBody.d.ts +9 -0
- package/_shims/MultipartBody.d.ts.map +1 -0
- package/_shims/MultipartBody.js +16 -0
- package/_shims/MultipartBody.js.map +1 -0
- package/_shims/MultipartBody.mjs +12 -0
- package/_shims/MultipartBody.mjs.map +1 -0
- package/_shims/README.md +46 -0
- package/{src/_shims/ReadableStream-node.ts → _shims/auto/runtime-bun.d.ts} +2 -3
- package/_shims/auto/runtime-bun.d.ts.map +1 -0
- package/_shims/auto/runtime-bun.js +21 -0
- package/_shims/auto/runtime-bun.js.map +1 -0
- package/_shims/auto/runtime-bun.mjs +2 -0
- package/_shims/auto/runtime-bun.mjs.map +1 -0
- package/_shims/auto/runtime-node.d.ts +5 -0
- package/_shims/auto/runtime-node.d.ts.map +1 -0
- package/_shims/auto/runtime-node.js +21 -0
- package/_shims/auto/runtime-node.js.map +1 -0
- package/_shims/auto/runtime-node.mjs +2 -0
- package/_shims/auto/runtime-node.mjs.map +1 -0
- package/_shims/auto/runtime.d.ts +5 -0
- package/_shims/auto/runtime.d.ts.map +1 -0
- package/_shims/auto/runtime.js +21 -0
- package/_shims/auto/runtime.js.map +1 -0
- package/_shims/auto/runtime.mjs +2 -0
- package/_shims/auto/runtime.mjs.map +1 -0
- package/_shims/auto/types-node.d.ts +5 -0
- package/_shims/auto/types-node.d.ts.map +1 -0
- package/_shims/auto/types-node.js +21 -0
- package/_shims/auto/types-node.js.map +1 -0
- package/_shims/auto/types-node.mjs +2 -0
- package/_shims/auto/types-node.mjs.map +1 -0
- package/_shims/auto/types.d.ts +99 -0
- package/_shims/{ReadableStream.js → auto/types.js} +0 -2
- package/{src/_shims/ReadableStream.js → _shims/auto/types.mjs} +0 -2
- package/_shims/bun-runtime.d.ts +6 -0
- package/_shims/bun-runtime.d.ts.map +1 -0
- package/_shims/bun-runtime.js +14 -0
- package/_shims/bun-runtime.js.map +1 -0
- package/_shims/bun-runtime.mjs +10 -0
- package/_shims/bun-runtime.mjs.map +1 -0
- package/_shims/index.d.ts +79 -0
- package/_shims/index.js +13 -0
- package/_shims/index.mjs +7 -0
- package/_shims/manual-types.d.ts +12 -0
- package/_shims/manual-types.js +3 -0
- package/_shims/manual-types.mjs +3 -0
- package/_shims/node-runtime.d.ts +3 -0
- package/_shims/node-runtime.d.ts.map +1 -0
- package/_shims/node-runtime.js +87 -0
- package/_shims/node-runtime.js.map +1 -0
- package/_shims/node-runtime.mjs +54 -0
- package/_shims/node-runtime.mjs.map +1 -0
- package/_shims/node-types.d.ts +42 -0
- package/_shims/node-types.js +3 -0
- package/_shims/node-types.mjs +3 -0
- package/_shims/registry.d.ts +35 -0
- package/_shims/registry.d.ts.map +1 -0
- package/_shims/registry.js +39 -0
- package/_shims/registry.js.map +1 -0
- package/_shims/registry.mjs +35 -0
- package/_shims/registry.mjs.map +1 -0
- package/_shims/web-runtime.d.ts +5 -0
- package/_shims/web-runtime.d.ts.map +1 -0
- package/_shims/web-runtime.js +70 -0
- package/_shims/web-runtime.js.map +1 -0
- package/_shims/web-runtime.mjs +63 -0
- package/_shims/web-runtime.mjs.map +1 -0
- package/_shims/web-types.d.ts +82 -0
- package/_shims/web-types.js +3 -0
- package/_shims/web-types.mjs +3 -0
- package/core.d.ts +170 -223
- package/core.d.ts.map +1 -1
- package/core.js +682 -729
- package/core.js.map +1 -1
- package/core.mjs +676 -680
- package/core.mjs.map +1 -1
- package/error.d.ts +32 -32
- package/error.d.ts.map +1 -1
- package/error.js +95 -106
- package/error.js.map +1 -1
- package/error.mjs +91 -91
- package/error.mjs.map +1 -1
- package/index.d.mts +145 -178
- package/index.d.ts +145 -178
- package/index.d.ts.map +1 -1
- package/index.js +145 -201
- package/index.js.map +1 -1
- package/index.mjs +123 -149
- package/index.mjs.map +1 -1
- package/package.json +31 -23
- package/pagination.d.ts +47 -167
- package/pagination.d.ts.map +1 -1
- package/pagination.js +72 -202
- package/pagination.js.map +1 -1
- package/pagination.mjs +68 -187
- package/pagination.mjs.map +1 -1
- package/resource.d.ts +10 -10
- package/resource.js +12 -12
- package/resource.mjs +10 -10
- package/resources/account.d.ts +44 -44
- package/resources/account.js +20 -19
- package/resources/account.mjs +17 -16
- package/resources/hris/benefits/benefits.d.ts +127 -154
- package/resources/hris/benefits/benefits.js +74 -89
- package/resources/hris/benefits/benefits.mjs +50 -48
- package/resources/hris/benefits/index.d.ts +3 -28
- package/resources/hris/benefits/index.js +13 -55
- package/resources/hris/benefits/index.mjs +3 -8
- package/resources/hris/benefits/individuals.d.ts +129 -147
- package/resources/hris/benefits/individuals.js +59 -59
- package/resources/hris/benefits/individuals.mjs +53 -49
- package/resources/hris/company.d.ts +80 -80
- package/resources/hris/company.js +12 -13
- package/resources/hris/company.mjs +9 -8
- package/resources/hris/directory.d.ts +53 -55
- package/resources/hris/directory.js +13 -12
- package/resources/hris/directory.mjs +8 -7
- package/resources/hris/employments.d.ts +124 -126
- package/resources/hris/employments.js +23 -21
- package/resources/hris/employments.mjs +19 -17
- package/resources/hris/hris.d.ts +113 -123
- package/resources/hris/hris.js +54 -71
- package/resources/hris/hris.mjs +32 -32
- package/resources/hris/index.d.ts +9 -41
- package/resources/hris/index.js +26 -110
- package/resources/hris/index.mjs +9 -9
- package/resources/hris/individuals.d.ts +65 -67
- package/resources/hris/individuals.js +19 -17
- package/resources/hris/individuals.mjs +14 -12
- package/resources/hris/pay-statements.d.ts +146 -162
- package/resources/hris/pay-statements.js +22 -20
- package/resources/hris/pay-statements.mjs +18 -16
- package/resources/hris/payments.d.ts +47 -49
- package/resources/hris/payments.js +15 -13
- package/resources/hris/payments.mjs +11 -9
- package/resources/index.d.ts +5 -7
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js +13 -51
- package/resources/index.js.map +1 -1
- package/resources/index.mjs +5 -6
- package/resources/index.mjs.map +1 -1
- package/resources/providers.d.ts +43 -42
- package/resources/providers.js +15 -13
- package/resources/providers.mjs +11 -9
- package/resources/top-level.d.ts +1 -1
- package/resources/top-level.js +3 -3
- package/resources/top-level.mjs +1 -1
- package/resources/webhooks.d.ts +18 -18
- package/resources/webhooks.js +103 -107
- package/resources/webhooks.mjs +98 -102
- package/shims/node.d.ts +29 -0
- package/shims/node.d.ts.map +1 -0
- package/shims/node.js +31 -0
- package/shims/node.js.map +1 -0
- package/shims/node.mjs +5 -0
- package/shims/node.mjs.map +1 -0
- package/shims/web.d.ts +26 -0
- package/shims/web.d.ts.map +1 -0
- package/shims/web.js +31 -0
- package/shims/web.js.map +1 -0
- package/shims/web.mjs +5 -0
- package/shims/web.mjs.map +1 -0
- package/src/_shims/MultipartBody.ts +9 -0
- package/src/_shims/README.md +46 -0
- package/src/_shims/auto/runtime-bun.ts +4 -0
- package/src/_shims/auto/runtime-node.ts +4 -0
- package/src/_shims/auto/runtime.ts +4 -0
- package/src/_shims/auto/types-node.ts +4 -0
- package/src/_shims/auto/types.d.ts +99 -0
- package/src/_shims/auto/types.js +3 -0
- package/src/_shims/auto/types.mjs +3 -0
- package/src/_shims/bun-runtime.ts +14 -0
- package/src/_shims/index.d.ts +79 -0
- package/src/_shims/index.js +13 -0
- package/src/_shims/index.mjs +7 -0
- package/src/_shims/manual-types.d.ts +12 -0
- package/src/_shims/manual-types.js +3 -0
- package/src/_shims/manual-types.mjs +3 -0
- package/src/_shims/node-runtime.ts +79 -0
- package/src/_shims/node-types.d.ts +42 -0
- package/src/_shims/node-types.js +3 -0
- package/src/_shims/node-types.mjs +3 -0
- package/src/_shims/registry.ts +64 -0
- package/src/_shims/web-runtime.ts +91 -0
- package/src/_shims/web-types.d.ts +82 -0
- package/src/_shims/web-types.js +3 -0
- package/src/_shims/web-types.mjs +3 -0
- package/src/core.ts +75 -44
- package/src/error.ts +6 -4
- package/src/index.ts +8 -25
- package/src/pagination.ts +2 -261
- package/src/resource.ts +1 -1
- package/src/resources/account.ts +3 -3
- package/src/resources/hris/benefits/benefits.ts +6 -6
- package/src/resources/hris/benefits/index.ts +2 -2
- package/src/resources/hris/benefits/individuals.ts +6 -6
- package/src/resources/hris/company.ts +4 -4
- package/src/resources/hris/directory.ts +5 -5
- package/src/resources/hris/employments.ts +5 -5
- package/src/resources/hris/hris.ts +9 -9
- package/src/resources/hris/index.ts +8 -8
- package/src/resources/hris/individuals.ts +6 -6
- package/src/resources/hris/pay-statements.ts +6 -6
- package/src/resources/hris/payments.ts +5 -5
- package/src/resources/index.ts +4 -6
- package/src/resources/providers.ts +4 -4
- package/src/resources/webhooks.ts +2 -2
- package/src/shims/node.ts +50 -0
- package/src/shims/web.ts +50 -0
- package/src/uploads.ts +12 -16
- package/src/version.ts +1 -1
- package/uploads.d.ts +23 -39
- package/uploads.d.ts.map +1 -1
- package/uploads.js +115 -157
- package/uploads.js.map +1 -1
- package/uploads.mjs +111 -133
- package/uploads.mjs.map +1 -1
- package/version.d.ts +2 -2
- package/version.js +4 -4
- package/version.mjs +2 -2
- package/_shims/ReadableStream-node.d.ts +0 -6
- package/_shims/ReadableStream-node.d.ts.map +0 -1
- package/_shims/ReadableStream-node.js +0 -14
- package/_shims/ReadableStream-node.js.map +0 -1
- package/_shims/ReadableStream-node.mjs +0 -3
- package/_shims/ReadableStream-node.mjs.map +0 -1
- package/_shims/ReadableStream.d.ts +0 -38
- package/_shims/ReadableStream.mjs +0 -7
- package/_shims/agent-node.d.ts +0 -7
- package/_shims/agent-node.d.ts.map +0 -1
- package/_shims/agent-node.js +0 -28
- package/_shims/agent-node.js.map +0 -1
- package/_shims/agent-node.mjs +0 -16
- package/_shims/agent-node.mjs.map +0 -1
- package/_shims/agent.d.ts +0 -9
- package/_shims/agent.d.ts.map +0 -1
- package/_shims/agent.js +0 -14
- package/_shims/agent.js.map +0 -1
- package/_shims/agent.mjs +0 -10
- package/_shims/agent.mjs.map +0 -1
- package/_shims/fetch-node.d.ts +0 -64
- package/_shims/fetch-node.js +0 -12
- package/_shims/fetch-node.mjs +0 -14
- package/_shims/fetch.d.ts +0 -60
- package/_shims/fetch.js +0 -13
- package/_shims/fetch.mjs +0 -15
- package/_shims/fileFromPath-node.d.ts +0 -17
- package/_shims/fileFromPath-node.d.ts.map +0 -1
- package/_shims/fileFromPath-node.js +0 -17
- package/_shims/fileFromPath-node.js.map +0 -1
- package/_shims/fileFromPath-node.mjs +0 -13
- package/_shims/fileFromPath-node.mjs.map +0 -1
- package/_shims/fileFromPath.d.ts +0 -22
- package/_shims/fileFromPath.d.ts.map +0 -1
- package/_shims/fileFromPath.js +0 -16
- package/_shims/fileFromPath.js.map +0 -1
- package/_shims/fileFromPath.mjs +0 -12
- package/_shims/fileFromPath.mjs.map +0 -1
- package/_shims/form-data-node.d.ts +0 -45
- package/_shims/form-data-node.js +0 -11
- package/_shims/form-data-node.mjs +0 -9
- package/_shims/form-data.d.ts +0 -43
- package/_shims/form-data.js +0 -17
- package/_shims/form-data.mjs +0 -20
- package/_shims/getMultipartRequestOptions-node.d.ts +0 -10
- package/_shims/getMultipartRequestOptions-node.d.ts.map +0 -1
- package/_shims/getMultipartRequestOptions-node.js +0 -22
- package/_shims/getMultipartRequestOptions-node.js.map +0 -1
- package/_shims/getMultipartRequestOptions-node.mjs +0 -18
- package/_shims/getMultipartRequestOptions-node.mjs.map +0 -1
- package/_shims/getMultipartRequestOptions.d.ts +0 -10
- package/_shims/getMultipartRequestOptions.d.ts.map +0 -1
- package/_shims/getMultipartRequestOptions.js +0 -12
- package/_shims/getMultipartRequestOptions.js.map +0 -1
- package/_shims/getMultipartRequestOptions.mjs +0 -8
- package/_shims/getMultipartRequestOptions.mjs.map +0 -1
- package/_shims/node-readable-node.d.ts +0 -8
- package/_shims/node-readable-node.d.ts.map +0 -1
- package/_shims/node-readable-node.js +0 -9
- package/_shims/node-readable-node.js.map +0 -1
- package/_shims/node-readable-node.mjs +0 -5
- package/_shims/node-readable-node.mjs.map +0 -1
- package/_shims/node-readable.d.ts +0 -23
- package/_shims/node-readable.d.ts.map +0 -1
- package/_shims/node-readable.js +0 -11
- package/_shims/node-readable.js.map +0 -1
- package/_shims/node-readable.mjs +0 -7
- package/_shims/node-readable.mjs.map +0 -1
- package/resources/ats/applications.d.ts +0 -39
- package/resources/ats/applications.d.ts.map +0 -1
- package/resources/ats/applications.js +0 -24
- package/resources/ats/applications.js.map +0 -1
- package/resources/ats/applications.mjs +0 -20
- package/resources/ats/applications.mjs.map +0 -1
- package/resources/ats/ats.d.ts +0 -32
- package/resources/ats/ats.d.ts.map +0 -1
- package/resources/ats/ats.js +0 -71
- package/resources/ats/ats.js.map +0 -1
- package/resources/ats/ats.mjs +0 -27
- package/resources/ats/ats.mjs.map +0 -1
- package/resources/ats/candidates.d.ts +0 -53
- package/resources/ats/candidates.d.ts.map +0 -1
- package/resources/ats/candidates.js +0 -25
- package/resources/ats/candidates.js.map +0 -1
- package/resources/ats/candidates.mjs +0 -21
- package/resources/ats/candidates.mjs.map +0 -1
- package/resources/ats/index.d.ts +0 -7
- package/resources/ats/index.d.ts.map +0 -1
- package/resources/ats/index.js +0 -60
- package/resources/ats/index.js.map +0 -1
- package/resources/ats/index.mjs +0 -8
- package/resources/ats/index.mjs.map +0 -1
- package/resources/ats/jobs.d.ts +0 -47
- package/resources/ats/jobs.d.ts.map +0 -1
- package/resources/ats/jobs.js +0 -24
- package/resources/ats/jobs.js.map +0 -1
- package/resources/ats/jobs.mjs +0 -20
- package/resources/ats/jobs.mjs.map +0 -1
- package/resources/ats/offers.d.ts +0 -39
- package/resources/ats/offers.d.ts.map +0 -1
- package/resources/ats/offers.js +0 -24
- package/resources/ats/offers.js.map +0 -1
- package/resources/ats/offers.mjs +0 -20
- package/resources/ats/offers.mjs.map +0 -1
- package/resources/ats/stages.d.ts +0 -30
- package/resources/ats/stages.d.ts.map +0 -1
- package/resources/ats/stages.js +0 -22
- package/resources/ats/stages.js.map +0 -1
- package/resources/ats/stages.mjs +0 -17
- package/resources/ats/stages.mjs.map +0 -1
- package/src/_shims/ReadableStream.d.ts +0 -38
- package/src/_shims/ReadableStream.mjs +0 -7
- package/src/_shims/agent-node.ts +0 -22
- package/src/_shims/agent.ts +0 -12
- package/src/_shims/fetch-node.d.ts +0 -64
- package/src/_shims/fetch-node.js +0 -12
- package/src/_shims/fetch-node.mjs +0 -14
- package/src/_shims/fetch.d.ts +0 -60
- package/src/_shims/fetch.js +0 -13
- package/src/_shims/fetch.mjs +0 -15
- package/src/_shims/fileFromPath-node.ts +0 -29
- package/src/_shims/fileFromPath.ts +0 -29
- package/src/_shims/form-data-node.d.ts +0 -45
- package/src/_shims/form-data-node.js +0 -11
- package/src/_shims/form-data-node.mjs +0 -9
- package/src/_shims/form-data.d.ts +0 -43
- package/src/_shims/form-data.js +0 -17
- package/src/_shims/form-data.mjs +0 -20
- package/src/_shims/getMultipartRequestOptions-node.ts +0 -25
- package/src/_shims/getMultipartRequestOptions.ts +0 -14
- package/src/_shims/node-readable-node.ts +0 -10
- package/src/_shims/node-readable.ts +0 -30
- package/src/resources/ats/applications.ts +0 -64
- package/src/resources/ats/ats.ts +0 -39
- package/src/resources/ats/candidates.ts +0 -83
- package/src/resources/ats/index.ts +0 -8
- package/src/resources/ats/jobs.ts +0 -76
- package/src/resources/ats/offers.ts +0 -63
- package/src/resources/ats/stages.ts +0 -39
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
const shims = require('./registry');
|
|
5
|
+
const auto = require('@tryfinch/finch-api/_shims/auto/runtime');
|
|
6
|
+
if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
|
|
7
|
+
for (const property of Object.keys(shims)) {
|
|
8
|
+
Object.defineProperty(exports, property, {
|
|
9
|
+
get() {
|
|
10
|
+
return shims[property];
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
import * as shims from './registry.mjs';
|
|
5
|
+
import * as auto from "../ch/finch-api/_shims/auto/runtime";
|
|
6
|
+
if (!shims.kind) shims.setShims(auto.getRuntime(), { auto: true });
|
|
7
|
+
export * from './registry.mjs';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Types will get added to this namespace when you import one of the following:
|
|
6
|
+
*
|
|
7
|
+
* import '@tryfinch/finch-api/shims/node'
|
|
8
|
+
* import '@tryfinch/finch-api/shims/web'
|
|
9
|
+
*
|
|
10
|
+
* Importing more than one will cause type and runtime errors.
|
|
11
|
+
*/
|
|
12
|
+
export namespace manual {}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
import * as nf from 'node-fetch';
|
|
5
|
+
import * as fd from 'formdata-node';
|
|
6
|
+
import { type File, type FilePropertyBag } from 'formdata-node';
|
|
7
|
+
import KeepAliveAgent from 'agentkeepalive';
|
|
8
|
+
import { AbortController as AbortControllerPolyfill } from 'abort-controller';
|
|
9
|
+
import { ReadStream as FsReadStream } from 'node:fs';
|
|
10
|
+
import { type Agent } from 'node:http';
|
|
11
|
+
import { FormDataEncoder } from 'form-data-encoder';
|
|
12
|
+
import { Readable } from 'node:stream';
|
|
13
|
+
import { type RequestOptions } from '../core';
|
|
14
|
+
import { MultipartBody } from './MultipartBody';
|
|
15
|
+
import { type Shims } from './registry';
|
|
16
|
+
|
|
17
|
+
type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
|
|
18
|
+
|
|
19
|
+
let fileFromPathWarned = false;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated use fs.createReadStream('./my/file.txt') instead
|
|
23
|
+
*/
|
|
24
|
+
async function fileFromPath(path: string): Promise<File>;
|
|
25
|
+
async function fileFromPath(path: string, filename?: string): Promise<File>;
|
|
26
|
+
async function fileFromPath(path: string, options?: FileFromPathOptions): Promise<File>;
|
|
27
|
+
async function fileFromPath(path: string, filename?: string, options?: FileFromPathOptions): Promise<File>;
|
|
28
|
+
async function fileFromPath(path: string, ...args: any[]): Promise<File> {
|
|
29
|
+
// this import fails in environments that don't handle export maps correctly, like old versions of Jest
|
|
30
|
+
const { fileFromPath: _fileFromPath } = await import('formdata-node/file-from-path');
|
|
31
|
+
|
|
32
|
+
if (!fileFromPathWarned) {
|
|
33
|
+
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path)}) instead`);
|
|
34
|
+
fileFromPathWarned = true;
|
|
35
|
+
}
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
return await _fileFromPath(path, ...args);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const defaultHttpAgent: Agent = new KeepAliveAgent({ keepAlive: true, timeout: 5 * 60 * 1000 });
|
|
41
|
+
const defaultHttpsAgent: Agent = new KeepAliveAgent.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1000 });
|
|
42
|
+
|
|
43
|
+
async function getMultipartRequestOptions<T extends {} = Record<string, unknown>>(
|
|
44
|
+
form: fd.FormData,
|
|
45
|
+
opts: RequestOptions<T>,
|
|
46
|
+
): Promise<RequestOptions<T>> {
|
|
47
|
+
const encoder = new FormDataEncoder(form);
|
|
48
|
+
const readable = Readable.from(encoder);
|
|
49
|
+
const body = new MultipartBody(readable);
|
|
50
|
+
const headers = {
|
|
51
|
+
...opts.headers,
|
|
52
|
+
...encoder.headers,
|
|
53
|
+
'Content-Length': encoder.contentLength,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return { ...opts, body: body as any, headers };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getRuntime(): Shims {
|
|
60
|
+
// Polyfill global object if needed.
|
|
61
|
+
if (typeof AbortController === 'undefined') {
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
AbortController = AbortControllerPolyfill;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
kind: 'node',
|
|
67
|
+
fetch: nf.default,
|
|
68
|
+
Request: nf.Request,
|
|
69
|
+
Response: nf.Response,
|
|
70
|
+
Headers: nf.Headers,
|
|
71
|
+
FormData: fd.FormData,
|
|
72
|
+
Blob: fd.Blob,
|
|
73
|
+
File: fd.File,
|
|
74
|
+
getMultipartRequestOptions,
|
|
75
|
+
getDefaultAgent: (url: string): Agent => (url.startsWith('https') ? defaultHttpsAgent : defaultHttpAgent),
|
|
76
|
+
fileFromPath,
|
|
77
|
+
isFsReadStream: (value: any): value is FsReadStream => value instanceof FsReadStream,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
import * as nf from 'node-fetch';
|
|
5
|
+
import * as fd from 'formdata-node';
|
|
6
|
+
|
|
7
|
+
export { type Agent } from 'node:http';
|
|
8
|
+
export { type Readable } from 'node:stream';
|
|
9
|
+
export { type ReadStream as FsReadStream } from 'node:fs';
|
|
10
|
+
export { type ReadableStream } from 'web-streams-polyfill';
|
|
11
|
+
|
|
12
|
+
export const fetch: typeof nf.default;
|
|
13
|
+
|
|
14
|
+
export type Request = nf.Request;
|
|
15
|
+
export type RequestInfo = nf.RequestInfo;
|
|
16
|
+
export type RequestInit = nf.RequestInit;
|
|
17
|
+
|
|
18
|
+
export type Response = nf.Response;
|
|
19
|
+
export type ResponseInit = nf.ResponseInit;
|
|
20
|
+
export type ResponseType = nf.ResponseType;
|
|
21
|
+
export type BodyInit = nf.BodyInit;
|
|
22
|
+
export type Headers = nf.Headers;
|
|
23
|
+
export type HeadersInit = nf.HeadersInit;
|
|
24
|
+
|
|
25
|
+
type EndingType = 'native' | 'transparent';
|
|
26
|
+
export interface BlobPropertyBag {
|
|
27
|
+
endings?: EndingType;
|
|
28
|
+
type?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface FilePropertyBag extends BlobPropertyBag {
|
|
32
|
+
lastModified?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
|
|
36
|
+
|
|
37
|
+
export type FormData = fd.FormData;
|
|
38
|
+
export const FormData: typeof fd.FormData;
|
|
39
|
+
export type File = fd.File;
|
|
40
|
+
export const File: typeof fd.File;
|
|
41
|
+
export type Blob = fd.Blob;
|
|
42
|
+
export const Blob: typeof fd.Blob;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
import { type RequestOptions } from '../core';
|
|
5
|
+
|
|
6
|
+
export interface Shims {
|
|
7
|
+
kind: string;
|
|
8
|
+
fetch: any;
|
|
9
|
+
Request: any;
|
|
10
|
+
Response: any;
|
|
11
|
+
Headers: any;
|
|
12
|
+
FormData: any;
|
|
13
|
+
Blob: any;
|
|
14
|
+
File: any;
|
|
15
|
+
getMultipartRequestOptions: <T extends {} = Record<string, unknown>>(
|
|
16
|
+
form: Shims['FormData'],
|
|
17
|
+
opts: RequestOptions<T>,
|
|
18
|
+
) => Promise<RequestOptions<T>>;
|
|
19
|
+
getDefaultAgent: (url: string) => any;
|
|
20
|
+
fileFromPath:
|
|
21
|
+
| ((path: string, filename?: string, options?: {}) => Promise<Shims['File']>)
|
|
22
|
+
| ((path: string, options?: {}) => Promise<Shims['File']>);
|
|
23
|
+
isFsReadStream: (value: any) => boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export let auto = false;
|
|
27
|
+
export let kind: Shims['kind'] | undefined = undefined;
|
|
28
|
+
export let fetch: Shims['fetch'] | undefined = undefined;
|
|
29
|
+
export let Request: Shims['Request'] | undefined = undefined;
|
|
30
|
+
export let Response: Shims['Response'] | undefined = undefined;
|
|
31
|
+
export let Headers: Shims['Headers'] | undefined = undefined;
|
|
32
|
+
export let FormData: Shims['FormData'] | undefined = undefined;
|
|
33
|
+
export let Blob: Shims['Blob'] | undefined = undefined;
|
|
34
|
+
export let File: Shims['File'] | undefined = undefined;
|
|
35
|
+
export let getMultipartRequestOptions: Shims['getMultipartRequestOptions'] | undefined = undefined;
|
|
36
|
+
export let getDefaultAgent: Shims['getDefaultAgent'] | undefined = undefined;
|
|
37
|
+
export let fileFromPath: Shims['fileFromPath'] | undefined = undefined;
|
|
38
|
+
export let isFsReadStream: Shims['isFsReadStream'] | undefined = undefined;
|
|
39
|
+
|
|
40
|
+
export function setShims(shims: Shims, options: { auto: boolean } = { auto: false }) {
|
|
41
|
+
if (auto) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`you must \`import '@tryfinch/finch-api/shims/${shims.kind}'\` before importing anything else from @tryfinch/finch-api`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (kind) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`can't \`import '@tryfinch/finch-api/shims/${shims.kind}'\` after \`import '@tryfinch/finch-api/shims/${kind}'\``,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
auto = options.auto;
|
|
52
|
+
kind = shims.kind;
|
|
53
|
+
fetch = shims.fetch;
|
|
54
|
+
Request = shims.Request;
|
|
55
|
+
Response = shims.Response;
|
|
56
|
+
Headers = shims.Headers;
|
|
57
|
+
FormData = shims.FormData;
|
|
58
|
+
Blob = shims.Blob;
|
|
59
|
+
File = shims.File;
|
|
60
|
+
getMultipartRequestOptions = shims.getMultipartRequestOptions;
|
|
61
|
+
getDefaultAgent = shims.getDefaultAgent;
|
|
62
|
+
fileFromPath = shims.fileFromPath;
|
|
63
|
+
isFsReadStream = shims.isFsReadStream;
|
|
64
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
import { MultipartBody } from './MultipartBody';
|
|
5
|
+
import { type RequestOptions } from '../core';
|
|
6
|
+
import { type Shims } from './registry';
|
|
7
|
+
|
|
8
|
+
export function getRuntime({ manuallyImported }: { manuallyImported?: boolean } = {}): Shims {
|
|
9
|
+
const recommendation =
|
|
10
|
+
manuallyImported ?
|
|
11
|
+
`You may need to use polyfills`
|
|
12
|
+
: `Add one of these imports before your first \`import … from '@tryfinch/finch-api'\`:
|
|
13
|
+
- \`import '@tryfinch/finch-api/shims/node'\` (if you're running on Node)
|
|
14
|
+
- \`import '@tryfinch/finch-api/shims/web'\` (otherwise)
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
let _fetch, _Request, _Response, _Headers;
|
|
18
|
+
try {
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
_fetch = fetch;
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
_Request = Request;
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
_Response = Response;
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
_Headers = Headers;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`this environment is missing the following Web Fetch API type: ${
|
|
30
|
+
(error as any).message
|
|
31
|
+
}. ${recommendation}`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
kind: 'web',
|
|
37
|
+
fetch: _fetch,
|
|
38
|
+
Request: _Request,
|
|
39
|
+
Response: _Response,
|
|
40
|
+
Headers: _Headers,
|
|
41
|
+
FormData:
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
typeof FormData !== 'undefined' ? FormData : (
|
|
44
|
+
class FormData {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
constructor() {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`file uploads aren't supported in this environment yet as 'FormData' is undefined. ${recommendation}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
Blob:
|
|
54
|
+
typeof Blob !== 'undefined' ? Blob : (
|
|
55
|
+
class Blob {
|
|
56
|
+
constructor() {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`file uploads aren't supported in this environment yet as 'Blob' is undefined. ${recommendation}`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
File:
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
typeof File !== 'undefined' ? File : (
|
|
66
|
+
class File {
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
constructor() {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`file uploads aren't supported in this environment yet as 'File' is undefined. ${recommendation}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
getMultipartRequestOptions: async <T extends {} = Record<string, unknown>>(
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
form: FormData,
|
|
78
|
+
opts: RequestOptions<T>,
|
|
79
|
+
): Promise<RequestOptions<T>> => ({
|
|
80
|
+
...opts,
|
|
81
|
+
body: new MultipartBody(form) as any,
|
|
82
|
+
}),
|
|
83
|
+
getDefaultAgent: (url: string) => undefined,
|
|
84
|
+
fileFromPath: () => {
|
|
85
|
+
throw new Error(
|
|
86
|
+
'The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/Finch-API/finch-api-node#file-uploads',
|
|
87
|
+
);
|
|
88
|
+
},
|
|
89
|
+
isFsReadStream: (value: any) => false,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimer: modules in _shims aren't intended to be imported by SDK users.
|
|
3
|
+
*/
|
|
4
|
+
export type Agent = any;
|
|
5
|
+
|
|
6
|
+
declare const _fetch: typeof fetch;
|
|
7
|
+
export { _fetch as fetch };
|
|
8
|
+
|
|
9
|
+
type _Request = Request;
|
|
10
|
+
export { _Request as Request };
|
|
11
|
+
|
|
12
|
+
type _RequestInfo = RequestInfo;
|
|
13
|
+
export { type _RequestInfo as RequestInfo };
|
|
14
|
+
|
|
15
|
+
type _RequestInit = RequestInit;
|
|
16
|
+
export { type _RequestInit as RequestInit };
|
|
17
|
+
|
|
18
|
+
type _Response = Response;
|
|
19
|
+
export { _Response as Response };
|
|
20
|
+
|
|
21
|
+
type _ResponseInit = ResponseInit;
|
|
22
|
+
export { type _ResponseInit as ResponseInit };
|
|
23
|
+
|
|
24
|
+
type _ResponseType = ResponseType;
|
|
25
|
+
export { type _ResponseType as ResponseType };
|
|
26
|
+
|
|
27
|
+
type _BodyInit = BodyInit;
|
|
28
|
+
export { type _BodyInit as BodyInit };
|
|
29
|
+
|
|
30
|
+
type _Headers = Headers;
|
|
31
|
+
export { _Headers as Headers };
|
|
32
|
+
|
|
33
|
+
type _HeadersInit = HeadersInit;
|
|
34
|
+
export { type _HeadersInit as HeadersInit };
|
|
35
|
+
|
|
36
|
+
type EndingType = 'native' | 'transparent';
|
|
37
|
+
|
|
38
|
+
export interface BlobPropertyBag {
|
|
39
|
+
endings?: EndingType;
|
|
40
|
+
type?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface FilePropertyBag extends BlobPropertyBag {
|
|
44
|
+
lastModified?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type FileFromPathOptions = Omit<FilePropertyBag, 'lastModified'>;
|
|
48
|
+
|
|
49
|
+
type _FormData = FormData;
|
|
50
|
+
declare const _FormData: typeof FormData;
|
|
51
|
+
export { _FormData as FormData };
|
|
52
|
+
|
|
53
|
+
type _File = File;
|
|
54
|
+
declare const _File: typeof File;
|
|
55
|
+
export { _File as File };
|
|
56
|
+
|
|
57
|
+
type _Blob = Blob;
|
|
58
|
+
declare const _Blob: typeof Blob;
|
|
59
|
+
export { _Blob as Blob };
|
|
60
|
+
|
|
61
|
+
export declare class Readable {
|
|
62
|
+
readable: boolean;
|
|
63
|
+
readonly readableEnded: boolean;
|
|
64
|
+
readonly readableFlowing: boolean | null;
|
|
65
|
+
readonly readableHighWaterMark: number;
|
|
66
|
+
readonly readableLength: number;
|
|
67
|
+
readonly readableObjectMode: boolean;
|
|
68
|
+
destroyed: boolean;
|
|
69
|
+
read(size?: number): any;
|
|
70
|
+
pause(): this;
|
|
71
|
+
resume(): this;
|
|
72
|
+
isPaused(): boolean;
|
|
73
|
+
destroy(error?: Error): this;
|
|
74
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<any>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export declare class FsReadStream extends Readable {
|
|
78
|
+
path: {}; // node type is string | Buffer
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type _ReadableStream<R = any> = ReadableStream<R>;
|
|
82
|
+
export { type _ReadableStream as ReadableStream };
|
package/src/core.ts
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
|
-
import { VERSION } from './version
|
|
2
|
-
import { APIError, APIConnectionError, APIConnectionTimeoutError, APIUserAbortError } from './error.js';
|
|
3
|
-
import type { Readable } from './_shims/node-readable.js';
|
|
4
|
-
import { getDefaultAgent, type Agent } from './_shims/agent.js';
|
|
1
|
+
import { VERSION } from './version';
|
|
5
2
|
import {
|
|
3
|
+
FinchError,
|
|
4
|
+
APIError,
|
|
5
|
+
APIConnectionError,
|
|
6
|
+
APIConnectionTimeoutError,
|
|
7
|
+
APIUserAbortError,
|
|
8
|
+
} from './error';
|
|
9
|
+
import {
|
|
10
|
+
kind as shimsKind,
|
|
11
|
+
type Readable,
|
|
12
|
+
getDefaultAgent,
|
|
13
|
+
type Agent,
|
|
6
14
|
fetch,
|
|
7
|
-
isPolyfilled as fetchIsPolyfilled,
|
|
8
15
|
type RequestInfo,
|
|
9
16
|
type RequestInit,
|
|
10
17
|
type Response,
|
|
11
18
|
type HeadersInit,
|
|
12
|
-
} from './_shims/
|
|
19
|
+
} from './_shims/index';
|
|
13
20
|
export { type Response };
|
|
14
|
-
import { isMultipartBody } from './uploads
|
|
21
|
+
import { isMultipartBody } from './uploads';
|
|
15
22
|
export {
|
|
16
23
|
maybeMultipartFormRequestOptions,
|
|
17
24
|
multipartFormRequestOptions,
|
|
18
25
|
createForm,
|
|
19
26
|
type Uploadable,
|
|
20
|
-
} from './uploads
|
|
27
|
+
} from './uploads';
|
|
21
28
|
|
|
22
29
|
const MAX_RETRIES = 2;
|
|
23
30
|
|
|
@@ -77,6 +84,12 @@ export class APIPromise<T> extends Promise<T> {
|
|
|
77
84
|
*
|
|
78
85
|
* If you want to parse the response body but still get the `Response`
|
|
79
86
|
* instance, you can use {@link withResponse()}.
|
|
87
|
+
*
|
|
88
|
+
* 👋 Getting the wrong TypeScript type for `Response`?
|
|
89
|
+
* Try setting `"moduleResolution": "NodeNext"` if you can,
|
|
90
|
+
* or add one of these imports before your first `import … from '@tryfinch/finch-api'`:
|
|
91
|
+
* - `import '@tryfinch/finch-api/shims/node'` (if you're running on Node)
|
|
92
|
+
* - `import '@tryfinch/finch-api/shims/web'` (otherwise)
|
|
80
93
|
*/
|
|
81
94
|
asResponse(): Promise<Response> {
|
|
82
95
|
return this.responsePromise.then((p) => p.response);
|
|
@@ -86,6 +99,13 @@ export class APIPromise<T> extends Promise<T> {
|
|
|
86
99
|
*
|
|
87
100
|
* If you just want to get the raw `Response` instance without parsing it,
|
|
88
101
|
* you can use {@link asResponse()}.
|
|
102
|
+
*
|
|
103
|
+
*
|
|
104
|
+
* 👋 Getting the wrong TypeScript type for `Response`?
|
|
105
|
+
* Try setting `"moduleResolution": "NodeNext"` if you can,
|
|
106
|
+
* or add one of these imports before your first `import … from '@tryfinch/finch-api'`:
|
|
107
|
+
* - `import '@tryfinch/finch-api/shims/node'` (if you're running on Node)
|
|
108
|
+
* - `import '@tryfinch/finch-api/shims/web'` (otherwise)
|
|
89
109
|
*/
|
|
90
110
|
async withResponse(): Promise<{ data: T; response: Response }> {
|
|
91
111
|
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
|
|
@@ -270,7 +290,7 @@ export abstract class APIClient {
|
|
|
270
290
|
...headers,
|
|
271
291
|
};
|
|
272
292
|
// let builtin fetch set the Content-Type for multipart bodies
|
|
273
|
-
if (isMultipartBody(options.body) &&
|
|
293
|
+
if (isMultipartBody(options.body) && shimsKind !== 'node') {
|
|
274
294
|
delete reqHeaders['Content-Type'];
|
|
275
295
|
}
|
|
276
296
|
|
|
@@ -370,7 +390,7 @@ export abstract class APIClient {
|
|
|
370
390
|
return this.retryRequest(options, retriesRemaining, responseHeaders);
|
|
371
391
|
}
|
|
372
392
|
|
|
373
|
-
const errText = await response.text().catch(() =>
|
|
393
|
+
const errText = await response.text().catch((e) => castToError(e).message);
|
|
374
394
|
const errJSON = safeJSON(errText);
|
|
375
395
|
const errMessage = errJSON ? undefined : errText;
|
|
376
396
|
|
|
@@ -419,7 +439,7 @@ export abstract class APIClient {
|
|
|
419
439
|
if (value === null) {
|
|
420
440
|
return `${encodeURIComponent(key)}=`;
|
|
421
441
|
}
|
|
422
|
-
throw new
|
|
442
|
+
throw new FinchError(
|
|
423
443
|
`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
|
|
424
444
|
);
|
|
425
445
|
})
|
|
@@ -437,11 +457,14 @@ export abstract class APIClient {
|
|
|
437
457
|
|
|
438
458
|
const timeout = setTimeout(() => controller.abort(), ms);
|
|
439
459
|
|
|
440
|
-
return
|
|
441
|
-
.
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
460
|
+
return (
|
|
461
|
+
this.getRequestClient()
|
|
462
|
+
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
|
|
463
|
+
.fetch.call(undefined, url, { signal: controller.signal as any, ...options })
|
|
464
|
+
.finally(() => {
|
|
465
|
+
clearTimeout(timeout);
|
|
466
|
+
})
|
|
467
|
+
);
|
|
445
468
|
}
|
|
446
469
|
|
|
447
470
|
protected getRequestClient(): RequestClient {
|
|
@@ -456,6 +479,9 @@ export abstract class APIClient {
|
|
|
456
479
|
if (shouldRetryHeader === 'true') return true;
|
|
457
480
|
if (shouldRetryHeader === 'false') return false;
|
|
458
481
|
|
|
482
|
+
// Retry on request timeouts.
|
|
483
|
+
if (response.status === 408) return true;
|
|
484
|
+
|
|
459
485
|
// Retry on lock timeouts.
|
|
460
486
|
if (response.status === 409) return true;
|
|
461
487
|
|
|
@@ -476,32 +502,37 @@ export abstract class APIClient {
|
|
|
476
502
|
retriesRemaining -= 1;
|
|
477
503
|
|
|
478
504
|
// About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
505
|
+
let timeoutMillis: number | undefined;
|
|
506
|
+
const retryAfterHeader = responseHeaders?.['retry-after'];
|
|
507
|
+
if (retryAfterHeader) {
|
|
508
|
+
const timeoutSeconds = parseInt(retryAfterHeader);
|
|
509
|
+
if (!Number.isNaN(timeoutSeconds)) {
|
|
510
|
+
timeoutMillis = timeoutSeconds * 1000;
|
|
511
|
+
} else {
|
|
512
|
+
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
483
515
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
516
|
+
// If the API asks us to wait a certain amount of time (and it's a reasonable amount),
|
|
517
|
+
// just do what it says, but otherwise calculate a default
|
|
518
|
+
if (
|
|
519
|
+
!timeoutMillis ||
|
|
520
|
+
!Number.isInteger(timeoutMillis) ||
|
|
521
|
+
timeoutMillis <= 0 ||
|
|
522
|
+
timeoutMillis > 60 * 1000
|
|
523
|
+
) {
|
|
524
|
+
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
525
|
+
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
526
|
+
}
|
|
527
|
+
await sleep(timeoutMillis);
|
|
487
528
|
|
|
488
529
|
return this.makeRequest(options, retriesRemaining);
|
|
489
530
|
}
|
|
490
531
|
|
|
491
|
-
private
|
|
492
|
-
retriesRemaining: number,
|
|
493
|
-
retryAfter: number,
|
|
494
|
-
maxRetries: number,
|
|
495
|
-
): number {
|
|
532
|
+
private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
|
|
496
533
|
const initialRetryDelay = 0.5;
|
|
497
534
|
const maxRetryDelay = 2;
|
|
498
535
|
|
|
499
|
-
// If the API asks us to wait a certain amount of time (and it's a reasonable amount),
|
|
500
|
-
// just do what it says.
|
|
501
|
-
if (Number.isInteger(retryAfter) && retryAfter <= 60) {
|
|
502
|
-
return retryAfter;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
536
|
const numRetries = maxRetries - retriesRemaining;
|
|
506
537
|
|
|
507
538
|
// Apply exponential backoff, but not more than the max.
|
|
@@ -510,7 +541,7 @@ export abstract class APIClient {
|
|
|
510
541
|
// Apply some jitter, plus-or-minus half a second.
|
|
511
542
|
const jitter = Math.random() - 0.5;
|
|
512
543
|
|
|
513
|
-
return sleepSeconds + jitter;
|
|
544
|
+
return (sleepSeconds + jitter) * 1000;
|
|
514
545
|
}
|
|
515
546
|
|
|
516
547
|
private getUserAgent(): string {
|
|
@@ -572,7 +603,7 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
|
|
|
572
603
|
async getNextPage(): Promise<this> {
|
|
573
604
|
const nextInfo = this.nextPageInfo();
|
|
574
605
|
if (!nextInfo) {
|
|
575
|
-
throw new
|
|
606
|
+
throw new FinchError(
|
|
576
607
|
'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.',
|
|
577
608
|
);
|
|
578
609
|
}
|
|
@@ -582,7 +613,7 @@ export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
|
|
|
582
613
|
} else if ('url' in nextInfo) {
|
|
583
614
|
const params = [...Object.entries(nextOptions.query || {}), ...nextInfo.url.searchParams.entries()];
|
|
584
615
|
for (const [key, value] of params) {
|
|
585
|
-
nextInfo.url.searchParams.set(key, value);
|
|
616
|
+
nextInfo.url.searchParams.set(key, value as any);
|
|
586
617
|
}
|
|
587
618
|
nextOptions.query = undefined;
|
|
588
619
|
nextOptions.path = nextInfo.url.toString();
|
|
@@ -708,7 +739,7 @@ const requestOptionsKeys: KeysEnum<RequestOptions> = {
|
|
|
708
739
|
idempotencyKey: true,
|
|
709
740
|
};
|
|
710
741
|
|
|
711
|
-
export const isRequestOptions = (obj: unknown): obj is RequestOptions => {
|
|
742
|
+
export const isRequestOptions = (obj: unknown): obj is RequestOptions<Record<string, unknown> | Readable> => {
|
|
712
743
|
return (
|
|
713
744
|
typeof obj === 'object' &&
|
|
714
745
|
obj !== null &&
|
|
@@ -898,10 +929,10 @@ export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve
|
|
|
898
929
|
|
|
899
930
|
const validatePositiveInteger = (name: string, n: unknown): number => {
|
|
900
931
|
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
901
|
-
throw new
|
|
932
|
+
throw new FinchError(`${name} must be an integer`);
|
|
902
933
|
}
|
|
903
934
|
if (n < 0) {
|
|
904
|
-
throw new
|
|
935
|
+
throw new FinchError(`${name} must be a positive integer`);
|
|
905
936
|
}
|
|
906
937
|
return n;
|
|
907
938
|
};
|
|
@@ -912,7 +943,7 @@ export const castToError = (err: any): Error => {
|
|
|
912
943
|
};
|
|
913
944
|
|
|
914
945
|
export const ensurePresent = <T>(value: T | null | undefined): T => {
|
|
915
|
-
if (value == null) throw new
|
|
946
|
+
if (value == null) throw new FinchError(`Expected a value to be given but received ${value} instead.`);
|
|
916
947
|
return value;
|
|
917
948
|
};
|
|
918
949
|
|
|
@@ -935,14 +966,14 @@ export const coerceInteger = (value: unknown): number => {
|
|
|
935
966
|
if (typeof value === 'number') return Math.round(value);
|
|
936
967
|
if (typeof value === 'string') return parseInt(value, 10);
|
|
937
968
|
|
|
938
|
-
throw new
|
|
969
|
+
throw new FinchError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
|
|
939
970
|
};
|
|
940
971
|
|
|
941
972
|
export const coerceFloat = (value: unknown): number => {
|
|
942
973
|
if (typeof value === 'number') return value;
|
|
943
974
|
if (typeof value === 'string') return parseFloat(value);
|
|
944
975
|
|
|
945
|
-
throw new
|
|
976
|
+
throw new FinchError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
|
|
946
977
|
};
|
|
947
978
|
|
|
948
979
|
export const coerceBoolean = (value: unknown): boolean => {
|
|
@@ -1046,5 +1077,5 @@ export const toBase64 = (str: string | null | undefined): string => {
|
|
|
1046
1077
|
return btoa(str);
|
|
1047
1078
|
}
|
|
1048
1079
|
|
|
1049
|
-
throw new
|
|
1080
|
+
throw new FinchError('Cannot generate b64 string; Expected `Buffer` or `btoa` to be defined');
|
|
1050
1081
|
};
|