@tryfinch/finch-api 8.2.1 → 9.8.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.
Files changed (267) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/README.md +2 -2
  3. package/client.d.mts +8 -4
  4. package/client.d.mts.map +1 -1
  5. package/client.d.ts +8 -4
  6. package/client.d.ts.map +1 -1
  7. package/client.js +43 -13
  8. package/client.js.map +1 -1
  9. package/client.mjs +43 -13
  10. package/client.mjs.map +1 -1
  11. package/internal/parse.d.mts.map +1 -1
  12. package/internal/parse.d.ts.map +1 -1
  13. package/internal/parse.js +5 -0
  14. package/internal/parse.js.map +1 -1
  15. package/internal/parse.mjs +5 -0
  16. package/internal/parse.mjs.map +1 -1
  17. package/internal/request-options.d.mts +4 -0
  18. package/internal/request-options.d.mts.map +1 -1
  19. package/internal/request-options.d.ts +4 -0
  20. package/internal/request-options.d.ts.map +1 -1
  21. package/internal/request-options.js.map +1 -1
  22. package/internal/request-options.mjs.map +1 -1
  23. package/internal/tslib.js +17 -17
  24. package/internal/types.d.mts +6 -6
  25. package/internal/types.d.mts.map +1 -1
  26. package/internal/types.d.ts +6 -6
  27. package/internal/types.d.ts.map +1 -1
  28. package/internal/utils/env.js +2 -2
  29. package/internal/utils/env.js.map +1 -1
  30. package/internal/utils/env.mjs +2 -2
  31. package/internal/utils/env.mjs.map +1 -1
  32. package/internal/utils/log.d.mts.map +1 -1
  33. package/internal/utils/log.d.ts.map +1 -1
  34. package/internal/utils/log.js +2 -0
  35. package/internal/utils/log.js.map +1 -1
  36. package/internal/utils/log.mjs +2 -0
  37. package/internal/utils/log.mjs.map +1 -1
  38. package/internal/utils/query.d.mts +2 -0
  39. package/internal/utils/query.d.mts.map +1 -0
  40. package/internal/utils/query.d.ts +2 -0
  41. package/internal/utils/query.d.ts.map +1 -0
  42. package/internal/utils/query.js +10 -0
  43. package/internal/utils/query.js.map +1 -0
  44. package/internal/utils/query.mjs +6 -0
  45. package/internal/utils/query.mjs.map +1 -0
  46. package/internal/utils.d.mts +1 -0
  47. package/internal/utils.d.ts +1 -0
  48. package/internal/utils.js +1 -0
  49. package/internal/utils.js.map +1 -1
  50. package/internal/utils.mjs +1 -0
  51. package/package.json +12 -1
  52. package/resources/access-tokens.d.mts +5 -0
  53. package/resources/access-tokens.d.mts.map +1 -1
  54. package/resources/access-tokens.d.ts +5 -0
  55. package/resources/access-tokens.d.ts.map +1 -1
  56. package/resources/access-tokens.js +1 -0
  57. package/resources/access-tokens.js.map +1 -1
  58. package/resources/access-tokens.mjs +1 -0
  59. package/resources/access-tokens.mjs.map +1 -1
  60. package/resources/account.d.mts +4 -0
  61. package/resources/account.d.mts.map +1 -1
  62. package/resources/account.d.ts +4 -0
  63. package/resources/account.d.ts.map +1 -1
  64. package/resources/account.js +2 -2
  65. package/resources/account.js.map +1 -1
  66. package/resources/account.mjs +2 -2
  67. package/resources/account.mjs.map +1 -1
  68. package/resources/connect/sessions.d.mts +6 -2
  69. package/resources/connect/sessions.d.mts.map +1 -1
  70. package/resources/connect/sessions.d.ts +6 -2
  71. package/resources/connect/sessions.d.ts.map +1 -1
  72. package/resources/connect/sessions.js +6 -2
  73. package/resources/connect/sessions.js.map +1 -1
  74. package/resources/connect/sessions.mjs +6 -2
  75. package/resources/connect/sessions.mjs.map +1 -1
  76. package/resources/hris/benefits/benefits.d.mts +6 -6
  77. package/resources/hris/benefits/benefits.d.mts.map +1 -1
  78. package/resources/hris/benefits/benefits.d.ts +6 -6
  79. package/resources/hris/benefits/benefits.d.ts.map +1 -1
  80. package/resources/hris/benefits/benefits.js +18 -3
  81. package/resources/hris/benefits/benefits.js.map +1 -1
  82. package/resources/hris/benefits/benefits.mjs +18 -3
  83. package/resources/hris/benefits/benefits.mjs.map +1 -1
  84. package/resources/hris/benefits/individuals.d.mts +12 -12
  85. package/resources/hris/benefits/individuals.d.mts.map +1 -1
  86. package/resources/hris/benefits/individuals.d.ts +12 -12
  87. package/resources/hris/benefits/individuals.d.ts.map +1 -1
  88. package/resources/hris/benefits/individuals.js +8 -2
  89. package/resources/hris/benefits/individuals.js.map +1 -1
  90. package/resources/hris/benefits/individuals.mjs +8 -2
  91. package/resources/hris/benefits/individuals.mjs.map +1 -1
  92. package/resources/hris/company/company.js +1 -1
  93. package/resources/hris/company/company.js.map +1 -1
  94. package/resources/hris/company/company.mjs +1 -1
  95. package/resources/hris/company/company.mjs.map +1 -1
  96. package/resources/hris/company/pay-statement-item/pay-statement-item.js +1 -1
  97. package/resources/hris/company/pay-statement-item/pay-statement-item.js.map +1 -1
  98. package/resources/hris/company/pay-statement-item/pay-statement-item.mjs +1 -1
  99. package/resources/hris/company/pay-statement-item/pay-statement-item.mjs.map +1 -1
  100. package/resources/hris/company/pay-statement-item/rules.d.mts.map +1 -1
  101. package/resources/hris/company/pay-statement-item/rules.d.ts.map +1 -1
  102. package/resources/hris/company/pay-statement-item/rules.js +4 -0
  103. package/resources/hris/company/pay-statement-item/rules.js.map +1 -1
  104. package/resources/hris/company/pay-statement-item/rules.mjs +4 -0
  105. package/resources/hris/company/pay-statement-item/rules.mjs.map +1 -1
  106. package/resources/hris/directory.d.mts +9 -1
  107. package/resources/hris/directory.d.mts.map +1 -1
  108. package/resources/hris/directory.d.ts +9 -1
  109. package/resources/hris/directory.d.ts.map +1 -1
  110. package/resources/hris/directory.js +1 -0
  111. package/resources/hris/directory.js.map +1 -1
  112. package/resources/hris/directory.mjs +1 -0
  113. package/resources/hris/directory.mjs.map +1 -1
  114. package/resources/hris/documents.d.mts.map +1 -1
  115. package/resources/hris/documents.d.ts.map +1 -1
  116. package/resources/hris/documents.js +6 -2
  117. package/resources/hris/documents.js.map +1 -1
  118. package/resources/hris/documents.mjs +6 -2
  119. package/resources/hris/documents.mjs.map +1 -1
  120. package/resources/hris/employments.d.mts +12 -7
  121. package/resources/hris/employments.d.mts.map +1 -1
  122. package/resources/hris/employments.d.ts +12 -7
  123. package/resources/hris/employments.d.ts.map +1 -1
  124. package/resources/hris/employments.js +1 -0
  125. package/resources/hris/employments.js.map +1 -1
  126. package/resources/hris/employments.mjs +1 -0
  127. package/resources/hris/employments.mjs.map +1 -1
  128. package/resources/hris/individuals.d.mts +5 -5
  129. package/resources/hris/individuals.d.mts.map +1 -1
  130. package/resources/hris/individuals.d.ts +5 -5
  131. package/resources/hris/individuals.d.ts.map +1 -1
  132. package/resources/hris/individuals.js +1 -0
  133. package/resources/hris/individuals.js.map +1 -1
  134. package/resources/hris/individuals.mjs +1 -0
  135. package/resources/hris/individuals.mjs.map +1 -1
  136. package/resources/hris/pay-statements.d.mts.map +1 -1
  137. package/resources/hris/pay-statements.d.ts.map +1 -1
  138. package/resources/hris/pay-statements.js +1 -0
  139. package/resources/hris/pay-statements.js.map +1 -1
  140. package/resources/hris/pay-statements.mjs +1 -0
  141. package/resources/hris/pay-statements.mjs.map +1 -1
  142. package/resources/hris/payments.d.mts.map +1 -1
  143. package/resources/hris/payments.d.ts.map +1 -1
  144. package/resources/hris/payments.js +5 -1
  145. package/resources/hris/payments.js.map +1 -1
  146. package/resources/hris/payments.mjs +5 -1
  147. package/resources/hris/payments.mjs.map +1 -1
  148. package/resources/jobs/automated.js +3 -3
  149. package/resources/jobs/automated.js.map +1 -1
  150. package/resources/jobs/automated.mjs +3 -3
  151. package/resources/jobs/automated.mjs.map +1 -1
  152. package/resources/jobs/manual.js +1 -1
  153. package/resources/jobs/manual.js.map +1 -1
  154. package/resources/jobs/manual.mjs +1 -1
  155. package/resources/jobs/manual.mjs.map +1 -1
  156. package/resources/payroll/pay-groups.d.mts.map +1 -1
  157. package/resources/payroll/pay-groups.d.ts.map +1 -1
  158. package/resources/payroll/pay-groups.js +6 -1
  159. package/resources/payroll/pay-groups.js.map +1 -1
  160. package/resources/payroll/pay-groups.mjs +6 -1
  161. package/resources/payroll/pay-groups.mjs.map +1 -1
  162. package/resources/providers.d.mts.map +1 -1
  163. package/resources/providers.d.ts.map +1 -1
  164. package/resources/providers.js +4 -1
  165. package/resources/providers.js.map +1 -1
  166. package/resources/providers.mjs +4 -1
  167. package/resources/providers.mjs.map +1 -1
  168. package/resources/request-forwarding.js +1 -1
  169. package/resources/request-forwarding.js.map +1 -1
  170. package/resources/request-forwarding.mjs +1 -1
  171. package/resources/request-forwarding.mjs.map +1 -1
  172. package/resources/sandbox/company.js +1 -1
  173. package/resources/sandbox/company.js.map +1 -1
  174. package/resources/sandbox/company.mjs +1 -1
  175. package/resources/sandbox/company.mjs.map +1 -1
  176. package/resources/sandbox/connections/accounts.d.mts.map +1 -1
  177. package/resources/sandbox/connections/accounts.d.ts.map +1 -1
  178. package/resources/sandbox/connections/accounts.js +10 -2
  179. package/resources/sandbox/connections/accounts.js.map +1 -1
  180. package/resources/sandbox/connections/accounts.mjs +10 -2
  181. package/resources/sandbox/connections/accounts.mjs.map +1 -1
  182. package/resources/sandbox/connections/connections.js +1 -1
  183. package/resources/sandbox/connections/connections.js.map +1 -1
  184. package/resources/sandbox/connections/connections.mjs +1 -1
  185. package/resources/sandbox/connections/connections.mjs.map +1 -1
  186. package/resources/sandbox/directory.d.mts +5 -0
  187. package/resources/sandbox/directory.d.mts.map +1 -1
  188. package/resources/sandbox/directory.d.ts +5 -0
  189. package/resources/sandbox/directory.d.ts.map +1 -1
  190. package/resources/sandbox/directory.js +5 -1
  191. package/resources/sandbox/directory.js.map +1 -1
  192. package/resources/sandbox/directory.mjs +5 -1
  193. package/resources/sandbox/directory.mjs.map +1 -1
  194. package/resources/sandbox/employment.d.mts +10 -0
  195. package/resources/sandbox/employment.d.mts.map +1 -1
  196. package/resources/sandbox/employment.d.ts +10 -0
  197. package/resources/sandbox/employment.d.ts.map +1 -1
  198. package/resources/sandbox/employment.js +5 -1
  199. package/resources/sandbox/employment.js.map +1 -1
  200. package/resources/sandbox/employment.mjs +5 -1
  201. package/resources/sandbox/employment.mjs.map +1 -1
  202. package/resources/sandbox/individual.d.mts.map +1 -1
  203. package/resources/sandbox/individual.d.ts.map +1 -1
  204. package/resources/sandbox/individual.js +5 -1
  205. package/resources/sandbox/individual.js.map +1 -1
  206. package/resources/sandbox/individual.mjs +5 -1
  207. package/resources/sandbox/individual.mjs.map +1 -1
  208. package/resources/sandbox/jobs/configuration.d.mts.map +1 -1
  209. package/resources/sandbox/jobs/configuration.d.ts.map +1 -1
  210. package/resources/sandbox/jobs/configuration.js +6 -2
  211. package/resources/sandbox/jobs/configuration.js.map +1 -1
  212. package/resources/sandbox/jobs/configuration.mjs +6 -2
  213. package/resources/sandbox/jobs/configuration.mjs.map +1 -1
  214. package/resources/sandbox/jobs/jobs.js +1 -1
  215. package/resources/sandbox/jobs/jobs.js.map +1 -1
  216. package/resources/sandbox/jobs/jobs.mjs +1 -1
  217. package/resources/sandbox/jobs/jobs.mjs.map +1 -1
  218. package/resources/sandbox/payment.js +1 -1
  219. package/resources/sandbox/payment.js.map +1 -1
  220. package/resources/sandbox/payment.mjs +1 -1
  221. package/resources/sandbox/payment.mjs.map +1 -1
  222. package/resources/webhooks.d.mts +5 -1
  223. package/resources/webhooks.d.mts.map +1 -1
  224. package/resources/webhooks.d.ts +5 -1
  225. package/resources/webhooks.d.ts.map +1 -1
  226. package/src/client.ts +57 -18
  227. package/src/internal/parse.ts +6 -0
  228. package/src/internal/request-options.ts +2 -0
  229. package/src/internal/types.ts +6 -8
  230. package/src/internal/utils/env.ts +2 -2
  231. package/src/internal/utils/log.ts +2 -0
  232. package/src/internal/utils/query.ts +7 -0
  233. package/src/internal/utils.ts +1 -0
  234. package/src/resources/access-tokens.ts +7 -0
  235. package/src/resources/account.ts +14 -2
  236. package/src/resources/connect/sessions.ts +12 -4
  237. package/src/resources/hris/benefits/benefits.ts +26 -11
  238. package/src/resources/hris/benefits/individuals.ts +25 -16
  239. package/src/resources/hris/company/company.ts +1 -1
  240. package/src/resources/hris/company/pay-statement-item/pay-statement-item.ts +1 -1
  241. package/src/resources/hris/company/pay-statement-item/rules.ts +4 -0
  242. package/src/resources/hris/directory.ts +12 -1
  243. package/src/resources/hris/documents.ts +6 -2
  244. package/src/resources/hris/employments.ts +14 -7
  245. package/src/resources/hris/individuals.ts +6 -5
  246. package/src/resources/hris/pay-statements.ts +1 -0
  247. package/src/resources/hris/payments.ts +5 -1
  248. package/src/resources/jobs/automated.ts +3 -3
  249. package/src/resources/jobs/manual.ts +1 -1
  250. package/src/resources/payroll/pay-groups.ts +6 -1
  251. package/src/resources/providers.ts +4 -1
  252. package/src/resources/request-forwarding.ts +1 -1
  253. package/src/resources/sandbox/company.ts +1 -1
  254. package/src/resources/sandbox/connections/accounts.ts +10 -2
  255. package/src/resources/sandbox/connections/connections.ts +1 -1
  256. package/src/resources/sandbox/directory.ts +11 -1
  257. package/src/resources/sandbox/employment.ts +17 -1
  258. package/src/resources/sandbox/individual.ts +5 -1
  259. package/src/resources/sandbox/jobs/configuration.ts +6 -2
  260. package/src/resources/sandbox/jobs/jobs.ts +1 -1
  261. package/src/resources/sandbox/payment.ts +1 -1
  262. package/src/resources/webhooks.ts +9 -1
  263. package/src/version.ts +1 -1
  264. package/version.d.mts +1 -1
  265. package/version.d.ts +1 -1
  266. package/version.js +1 -1
  267. package/version.mjs +1 -1
package/src/client.ts CHANGED
@@ -11,7 +11,7 @@ import type { APIResponseProps } from './internal/parse';
11
11
  import { getPlatformHeaders } from './internal/detect-platform';
12
12
  import * as Shims from './internal/shims';
13
13
  import * as Opts from './internal/request-options';
14
- import * as qs from './internal/qs';
14
+ import { stringifyQuery } from './internal/utils/query';
15
15
  import { VERSION } from './version';
16
16
  import * as Errors from './core/error';
17
17
  import * as Pagination from './core/pagination';
@@ -241,6 +241,18 @@ export class Finch {
241
241
  this.fetch = options.fetch ?? Shims.getDefaultFetch();
242
242
  this.#encoder = Opts.FallbackEncoder;
243
243
 
244
+ const customHeadersEnv = readEnv('FINCH_CUSTOM_HEADERS');
245
+ if (customHeadersEnv) {
246
+ const parsed: Record<string, string> = {};
247
+ for (const line of customHeadersEnv.split('\n')) {
248
+ const colon = line.indexOf(':');
249
+ if (colon >= 0) {
250
+ parsed[line.substring(0, colon).trim()] = line.substring(colon + 1).trim();
251
+ }
252
+ }
253
+ options.defaultHeaders = { ...parsed, ...options.defaultHeaders };
254
+ }
255
+
244
256
  this._options = options;
245
257
 
246
258
  this.accessToken = accessToken;
@@ -302,8 +314,14 @@ export class Finch {
302
314
  );
303
315
  }
304
316
 
305
- protected async authHeaders(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
306
- return buildHeaders([await this.bearerAuth(opts), await this.basicAuth(opts)]);
317
+ protected async authHeaders(
318
+ opts: FinalRequestOptions,
319
+ schemes: { bearerAuth?: boolean; basicAuth?: boolean },
320
+ ): Promise<NullableHeaders | undefined> {
321
+ return buildHeaders([
322
+ schemes.bearerAuth ? await this.bearerAuth(opts) : null,
323
+ schemes.basicAuth ? await this.basicAuth(opts) : null,
324
+ ]);
307
325
  }
308
326
 
309
327
  protected async bearerAuth(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
@@ -327,8 +345,8 @@ export class Finch {
327
345
  return buildHeaders([{ Authorization }]);
328
346
  }
329
347
 
330
- protected stringifyQuery(query: Record<string, unknown>): string {
331
- return qs.stringify(query, { arrayFormat: 'brackets' });
348
+ protected stringifyQuery(query: object | Record<string, unknown>): string {
349
+ return stringifyQuery(query);
332
350
  }
333
351
 
334
352
  private getUserAgent(): string {
@@ -360,12 +378,13 @@ export class Finch {
360
378
  : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
361
379
 
362
380
  const defaultQuery = this.defaultQuery();
363
- if (!isEmptyObj(defaultQuery)) {
364
- query = { ...defaultQuery, ...query };
381
+ const pathQuery = Object.fromEntries(url.searchParams);
382
+ if (!isEmptyObj(defaultQuery) || !isEmptyObj(pathQuery)) {
383
+ query = { ...pathQuery, ...defaultQuery, ...query };
365
384
  }
366
385
 
367
386
  if (typeof query === 'object' && query && !Array.isArray(query)) {
368
- url.search = this.stringifyQuery(query as Record<string, unknown>);
387
+ url.search = this.stringifyQuery(query);
369
388
  }
370
389
 
371
390
  return url.toString();
@@ -549,7 +568,7 @@ export class Finch {
549
568
  loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
550
569
 
551
570
  const errText = await response.text().catch((err: any) => castToError(err).message);
552
- const errJSON = safeJSON(errText);
571
+ const errJSON = safeJSON(errText) as any;
553
572
  const errMessage = errJSON ? undefined : errText;
554
573
 
555
574
  loggerFor(this).debug(
@@ -586,9 +605,14 @@ export class Finch {
586
605
  getAPIList<Item, PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>>(
587
606
  path: string,
588
607
  Page: new (...args: any[]) => PageClass,
589
- opts?: RequestOptions,
608
+ opts?: PromiseOrValue<RequestOptions>,
590
609
  ): Pagination.PagePromise<PageClass, Item> {
591
- return this.requestAPIList(Page, { method: 'get', path, ...opts });
610
+ return this.requestAPIList(
611
+ Page,
612
+ opts && 'then' in opts ?
613
+ opts.then((opts) => ({ method: 'get', path, ...opts }))
614
+ : { method: 'get', path, ...opts },
615
+ );
592
616
  }
593
617
 
594
618
  requestAPIList<
@@ -596,7 +620,7 @@ export class Finch {
596
620
  PageClass extends Pagination.AbstractPage<Item> = Pagination.AbstractPage<Item>,
597
621
  >(
598
622
  Page: new (...args: ConstructorParameters<typeof Pagination.AbstractPage>) => PageClass,
599
- options: FinalRequestOptions,
623
+ options: PromiseOrValue<FinalRequestOptions>,
600
624
  ): Pagination.PagePromise<PageClass, Item> {
601
625
  const request = this.makeRequest(options, null, undefined);
602
626
  return new Pagination.PagePromise<PageClass, Item>(this as any as Finch, request, Page);
@@ -609,9 +633,10 @@ export class Finch {
609
633
  controller: AbortController,
610
634
  ): Promise<Response> {
611
635
  const { signal, method, ...options } = init || {};
612
- if (signal) signal.addEventListener('abort', () => controller.abort());
636
+ const abort = this._makeAbort(controller);
637
+ if (signal) signal.addEventListener('abort', abort, { once: true });
613
638
 
614
- const timeout = setTimeout(() => controller.abort(), ms);
639
+ const timeout = setTimeout(abort, ms);
615
640
 
616
641
  const isReadableBody =
617
642
  ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
@@ -688,9 +713,9 @@ export class Finch {
688
713
  }
689
714
  }
690
715
 
691
- // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
692
- // just do what it says, but otherwise calculate a default
693
- if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
716
+ // If the API asks us to wait a certain amount of time, just do what it
717
+ // says, but otherwise calculate a default
718
+ if (timeoutMillis === undefined) {
694
719
  const maxRetries = options.maxRetries ?? this.maxRetries;
695
720
  timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
696
721
  }
@@ -768,7 +793,7 @@ export class Finch {
768
793
  ...getPlatformHeaders(),
769
794
  'Finch-API-Version': '2020-09-17',
770
795
  },
771
- await this.authHeaders(options),
796
+ await this.authHeaders(options, options.__security ?? { bearerAuth: true, basicAuth: true }),
772
797
  this._options.defaultHeaders,
773
798
  bodyHeaders,
774
799
  options.headers,
@@ -779,6 +804,12 @@ export class Finch {
779
804
  return headers.values;
780
805
  }
781
806
 
807
+ private _makeAbort(controller: AbortController) {
808
+ // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
809
+ // would capture all request options, and cause a memory leak.
810
+ return () => controller.abort();
811
+ }
812
+
782
813
  private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
783
814
  bodyHeaders: HeadersLike;
784
815
  body: BodyInit | undefined;
@@ -811,6 +842,14 @@ export class Finch {
811
842
  (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))
812
843
  ) {
813
844
  return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body as AsyncIterable<Uint8Array>) };
845
+ } else if (
846
+ typeof body === 'object' &&
847
+ headers.values.get('content-type') === 'application/x-www-form-urlencoded'
848
+ ) {
849
+ return {
850
+ bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
851
+ body: this.stringifyQuery(body),
852
+ };
814
853
  } else {
815
854
  return this.#encoder({ body, headers });
816
855
  }
@@ -29,6 +29,12 @@ export async function defaultParseResponse<T>(client: Finch, props: APIResponseP
29
29
  const mediaType = contentType?.split(';')[0]?.trim();
30
30
  const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json');
31
31
  if (isJSON) {
32
+ const contentLength = response.headers.get('content-length');
33
+ if (contentLength === '0') {
34
+ // if there is no content we can't do anything
35
+ return undefined as T;
36
+ }
37
+
32
38
  const json = await response.json();
33
39
  return json as T;
34
40
  }
@@ -75,6 +75,8 @@ export type RequestOptions = {
75
75
  */
76
76
  defaultBaseURL?: string | undefined;
77
77
 
78
+ __security?: { bearerAuth?: boolean; basicAuth?: boolean };
79
+
78
80
  __binaryResponse?: boolean | undefined;
79
81
  };
80
82
 
@@ -40,7 +40,6 @@ type OverloadedParameters<T> =
40
40
  : T extends (...args: infer A) => unknown ? A
41
41
  : never;
42
42
 
43
- /* eslint-disable */
44
43
  /**
45
44
  * These imports attempt to get types from a parent package's dependencies.
46
45
  * Unresolved bare specifiers can trigger [automatic type acquisition][1] in some projects, which
@@ -63,19 +62,18 @@ type OverloadedParameters<T> =
63
62
  *
64
63
  * [1]: https://www.typescriptlang.org/tsconfig/#typeAcquisition
65
64
  */
66
- /** @ts-ignore For users with \@types/node */
65
+ /** @ts-ignore For users with \@types/node */ /* prettier-ignore */
67
66
  type UndiciTypesRequestInit = NotAny<import('../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/undici-types/index.d.ts').RequestInit>;
68
- /** @ts-ignore For users with undici */
67
+ /** @ts-ignore For users with undici */ /* prettier-ignore */
69
68
  type UndiciRequestInit = NotAny<import('../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/undici/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/undici/index.d.ts').RequestInit>;
70
- /** @ts-ignore For users with \@types/bun */
69
+ /** @ts-ignore For users with \@types/bun */ /* prettier-ignore */
71
70
  type BunRequestInit = globalThis.FetchRequestInit;
72
- /** @ts-ignore For users with node-fetch@2 */
71
+ /** @ts-ignore For users with node-fetch@2 */ /* prettier-ignore */
73
72
  type NodeFetch2RequestInit = NotAny<import('../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/@types/node-fetch/index.d.ts').RequestInit>;
74
- /** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */
73
+ /** @ts-ignore For users with node-fetch@3, doesn't need file extension because types are at ./@types/index.d.ts */ /* prettier-ignore */
75
74
  type NodeFetch3RequestInit = NotAny<import('../node_modules/node-fetch').RequestInit> | NotAny<import('../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../../node_modules/node-fetch').RequestInit> | NotAny<import('../../../../../../../../../../node_modules/node-fetch').RequestInit>;
76
- /** @ts-ignore For users who use Deno */
75
+ /** @ts-ignore For users who use Deno */ /* prettier-ignore */
77
76
  type FetchRequestInit = NonNullable<OverloadedParameters<typeof fetch>[1]>;
78
- /* eslint-enable */
79
77
 
80
78
  type RequestInits =
81
79
  | NotAny<UndiciTypesRequestInit>
@@ -9,10 +9,10 @@
9
9
  */
10
10
  export const readEnv = (env: string): string | undefined => {
11
11
  if (typeof (globalThis as any).process !== 'undefined') {
12
- return (globalThis as any).process.env?.[env]?.trim() ?? undefined;
12
+ return (globalThis as any).process.env?.[env]?.trim() || undefined;
13
13
  }
14
14
  if (typeof (globalThis as any).Deno !== 'undefined') {
15
- return (globalThis as any).Deno.env?.get?.(env)?.trim();
15
+ return (globalThis as any).Deno.env?.get?.(env)?.trim() || undefined;
16
16
  }
17
17
  return undefined;
18
18
  };
@@ -107,6 +107,8 @@ export const formatRequestDetails = (details: {
107
107
  name,
108
108
  (
109
109
  name.toLowerCase() === 'authorization' ||
110
+ name.toLowerCase() === 'api-key' ||
111
+ name.toLowerCase() === 'x-api-key' ||
110
112
  name.toLowerCase() === 'cookie' ||
111
113
  name.toLowerCase() === 'set-cookie'
112
114
  ) ?
@@ -0,0 +1,7 @@
1
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ import * as qs from '../qs/stringify';
4
+
5
+ export function stringifyQuery(query: object | Record<string, unknown>) {
6
+ return qs.stringify(query, { arrayFormat: 'brackets' });
7
+ }
@@ -6,3 +6,4 @@ export * from './utils/env';
6
6
  export * from './utils/log';
7
7
  export * from './utils/uuid';
8
8
  export * from './utils/sleep';
9
+ export * from './utils/query';
@@ -32,6 +32,7 @@ export class AccessTokens extends APIResource {
32
32
  body: bodyWithReplacements,
33
33
  ...options,
34
34
  headers: headersWithReplacements,
35
+ __security: {},
35
36
  });
36
37
  }
37
38
  }
@@ -97,6 +98,12 @@ export interface CreateAccessTokenResponse {
97
98
  * for this connection
98
99
  */
99
100
  customer_id?: string | null;
101
+
102
+ /**
103
+ * The name of your customer you provided to Finch when a connect session was
104
+ * created for this connection
105
+ */
106
+ customer_name?: string | null;
100
107
  }
101
108
 
102
109
  export interface AccessTokenCreateParams {
@@ -10,14 +10,14 @@ export class Account extends APIResource {
10
10
  * Disconnect one or more `access_token`s from your application.
11
11
  */
12
12
  disconnect(options?: RequestOptions): APIPromise<DisconnectResponse> {
13
- return this._client.post('/disconnect', options);
13
+ return this._client.post('/disconnect', { ...options, __security: { bearerAuth: true } });
14
14
  }
15
15
 
16
16
  /**
17
17
  * Read account information associated with an `access_token`
18
18
  */
19
19
  introspect(options?: RequestOptions): APIPromise<Introspection> {
20
- return this._client.get('/introspect', options);
20
+ return this._client.get('/introspect', { ...options, __security: { bearerAuth: true } });
21
21
  }
22
22
  }
23
23
 
@@ -180,6 +180,18 @@ export namespace Introspection {
180
180
  * The source ID of the entity
181
181
  */
182
182
  source_id: string | null;
183
+
184
+ /**
185
+ * The status of the entity connection
186
+ */
187
+ status:
188
+ | 'pending'
189
+ | 'processing'
190
+ | 'connected'
191
+ | 'error_no_account_setup'
192
+ | 'error_permissions'
193
+ | 'reauth'
194
+ | 'disconnected';
183
195
  }
184
196
  }
185
197
 
@@ -9,7 +9,7 @@ export class Sessions extends APIResource {
9
9
  * Create a new connect session for an employer
10
10
  */
11
11
  new(body: SessionNewParams, options?: RequestOptions): APIPromise<SessionNewResponse> {
12
- return this._client.post('/connect/sessions', { body, ...options });
12
+ return this._client.post('/connect/sessions', { body, ...options, __security: { basicAuth: true } });
13
13
  }
14
14
 
15
15
  /**
@@ -19,7 +19,11 @@ export class Sessions extends APIResource {
19
19
  body: SessionReauthenticateParams,
20
20
  options?: RequestOptions,
21
21
  ): APIPromise<SessionReauthenticateResponse> {
22
- return this._client.post('/connect/sessions/reauthenticate', { body, ...options });
22
+ return this._client.post('/connect/sessions/reauthenticate', {
23
+ body,
24
+ ...options,
25
+ __security: { basicAuth: true },
26
+ });
23
27
  }
24
28
  }
25
29
 
@@ -59,7 +63,9 @@ export interface SessionNewParams {
59
63
  customer_name: string;
60
64
 
61
65
  /**
62
- * The Finch products to request access to
66
+ * The Finch products to request access to. Use `benefits` to access deductions
67
+ * endpoints — `deduction` is a deprecated alias that is still accepted but should
68
+ * not be combined with `benefits`.
63
69
  */
64
70
  products: Array<
65
71
  | 'benefits'
@@ -136,7 +142,9 @@ export interface SessionReauthenticateParams {
136
142
  minutes_to_expire?: number;
137
143
 
138
144
  /**
139
- * The products to request access to (optional for reauthentication)
145
+ * The products to request access to (optional for reauthentication). Use
146
+ * `benefits` to access deductions endpoints — `deduction` is a deprecated alias
147
+ * that is still accepted but should not be combined with `benefits`.
140
148
  */
141
149
  products?: Array<
142
150
  | 'benefits'
@@ -38,7 +38,12 @@ export class Benefits extends APIResource {
38
38
  options?: RequestOptions,
39
39
  ): APIPromise<CreateCompanyBenefitsResponse> {
40
40
  const { entity_ids, ...body } = params ?? {};
41
- return this._client.post('/employer/benefits', { query: { entity_ids }, body, ...options });
41
+ return this._client.post('/employer/benefits', {
42
+ query: { entity_ids },
43
+ body,
44
+ ...options,
45
+ __security: { bearerAuth: true },
46
+ });
42
47
  }
43
48
 
44
49
  /**
@@ -56,7 +61,11 @@ export class Benefits extends APIResource {
56
61
  query: BenefitRetrieveParams | null | undefined = {},
57
62
  options?: RequestOptions,
58
63
  ): APIPromise<CompanyBenefit> {
59
- return this._client.get(path`/employer/benefits/${benefitID}`, { query, ...options });
64
+ return this._client.get(path`/employer/benefits/${benefitID}`, {
65
+ query,
66
+ ...options,
67
+ __security: { bearerAuth: true },
68
+ });
60
69
  }
61
70
 
62
71
  /**
@@ -78,6 +87,7 @@ export class Benefits extends APIResource {
78
87
  query: { entity_ids },
79
88
  body,
80
89
  ...options,
90
+ __security: { bearerAuth: true },
81
91
  });
82
92
  }
83
93
 
@@ -96,7 +106,11 @@ export class Benefits extends APIResource {
96
106
  query: BenefitListParams | null | undefined = {},
97
107
  options?: RequestOptions,
98
108
  ): PagePromise<CompanyBenefitsSinglePage, CompanyBenefit> {
99
- return this._client.getAPIList('/employer/benefits', SinglePage<CompanyBenefit>, { query, ...options });
109
+ return this._client.getAPIList('/employer/benefits', SinglePage<CompanyBenefit>, {
110
+ query,
111
+ ...options,
112
+ __security: { bearerAuth: true },
113
+ });
100
114
  }
101
115
 
102
116
  /**
@@ -117,6 +131,7 @@ export class Benefits extends APIResource {
117
131
  return this._client.getAPIList('/employer/benefits/meta', SinglePage<SupportedBenefit>, {
118
132
  query,
119
133
  ...options,
134
+ __security: { bearerAuth: true },
120
135
  });
121
136
  }
122
137
  }
@@ -126,12 +141,12 @@ export type CompanyBenefitsSinglePage = SinglePage<CompanyBenefit>;
126
141
  export type SupportedBenefitsSinglePage = SinglePage<SupportedBenefit>;
127
142
 
128
143
  export type BenefitContribution =
129
- | BenefitContribution.UnionMember0
130
- | BenefitContribution.UnionMember1
131
- | BenefitContribution.UnionMember2;
144
+ | BenefitContribution.BenefitContributionFixed
145
+ | BenefitContribution.BenefitContributionPercent
146
+ | BenefitContribution.BenefitContributionTiered;
132
147
 
133
148
  export namespace BenefitContribution {
134
- export interface UnionMember0 {
149
+ export interface BenefitContributionFixed {
135
150
  /**
136
151
  * Contribution amount in cents.
137
152
  */
@@ -143,7 +158,7 @@ export namespace BenefitContribution {
143
158
  type: 'fixed';
144
159
  }
145
160
 
146
- export interface UnionMember1 {
161
+ export interface BenefitContributionPercent {
147
162
  /**
148
163
  * Contribution amount in basis points (1/100th of a percent).
149
164
  */
@@ -155,12 +170,12 @@ export namespace BenefitContribution {
155
170
  type: 'percent';
156
171
  }
157
172
 
158
- export interface UnionMember2 {
173
+ export interface BenefitContributionTiered {
159
174
  /**
160
175
  * Array of tier objects defining employer match tiers based on employee
161
176
  * contribution thresholds.
162
177
  */
163
- tiers: Array<UnionMember2.Tier>;
178
+ tiers: Array<BenefitContributionTiered.Tier>;
164
179
 
165
180
  /**
166
181
  * Tiered contribution type (only valid for company_contribution).
@@ -168,7 +183,7 @@ export namespace BenefitContribution {
168
183
  type: 'tiered';
169
184
  }
170
185
 
171
- export namespace UnionMember2 {
186
+ export namespace BenefitContributionTiered {
172
187
  export interface Tier {
173
188
  match: number;
174
189
 
@@ -31,6 +31,7 @@ export class Individuals extends APIResource {
31
31
  query: { entity_ids },
32
32
  body: individuals,
33
33
  ...options,
34
+ __security: { bearerAuth: true },
34
35
  });
35
36
  }
36
37
 
@@ -50,7 +51,11 @@ export class Individuals extends APIResource {
50
51
  query: IndividualEnrolledIDsParams | null | undefined = {},
51
52
  options?: RequestOptions,
52
53
  ): APIPromise<IndividualEnrolledIDsResponse> {
53
- return this._client.get(path`/employer/benefits/${benefitID}/enrolled`, { query, ...options });
54
+ return this._client.get(path`/employer/benefits/${benefitID}/enrolled`, {
55
+ query,
56
+ ...options,
57
+ __security: { bearerAuth: true },
58
+ });
54
59
  }
55
60
 
56
61
  /**
@@ -74,7 +79,7 @@ export class Individuals extends APIResource {
74
79
  return this._client.getAPIList(
75
80
  path`/employer/benefits/${benefitID}/individuals`,
76
81
  SinglePage<IndividualBenefit>,
77
- { query, ...options },
82
+ { query, ...options, __security: { bearerAuth: true } },
78
83
  );
79
84
  }
80
85
 
@@ -99,6 +104,7 @@ export class Individuals extends APIResource {
99
104
  query: { entity_ids },
100
105
  body,
101
106
  ...options,
107
+ __security: { bearerAuth: true },
102
108
  });
103
109
  }
104
110
  }
@@ -110,7 +116,7 @@ export interface EnrolledIndividualBenefitResponse {
110
116
  }
111
117
 
112
118
  export interface IndividualBenefit {
113
- body: IndividualBenefit.UnionMember0 | IndividualBenefit.BatchError;
119
+ body: IndividualBenefit.IndividualBenefit | IndividualBenefit.BatchError;
114
120
 
115
121
  code: number;
116
122
 
@@ -118,7 +124,7 @@ export interface IndividualBenefit {
118
124
  }
119
125
 
120
126
  export namespace IndividualBenefit {
121
- export interface UnionMember0 {
127
+ export interface IndividualBenefit {
122
128
  /**
123
129
  * If the benefit supports annual maximum, the amount in cents for this individual.
124
130
  */
@@ -136,16 +142,19 @@ export namespace IndividualBenefit {
136
142
  * matching structures.
137
143
  */
138
144
  company_contribution:
139
- | UnionMember0.UnionMember0
140
- | UnionMember0.UnionMember1
141
- | UnionMember0.UnionMember2
145
+ | IndividualBenefit.CompanyContributionFixed
146
+ | IndividualBenefit.CompanyContributionPercent
147
+ | IndividualBenefit.CompanyContributionTiered
142
148
  | null;
143
149
 
144
150
  /**
145
151
  * Employee deduction configuration. Supports both fixed amounts (in cents) and
146
152
  * percentage-based contributions (in basis points where 100 = 1%).
147
153
  */
148
- employee_deduction: UnionMember0.UnionMember0 | UnionMember0.UnionMember1 | null;
154
+ employee_deduction:
155
+ | IndividualBenefit.EmployeeDeductionContributionFixed
156
+ | IndividualBenefit.EmployeeDeductionContributionPercent
157
+ | null;
149
158
 
150
159
  /**
151
160
  * Type for HSA contribution limit if the benefit is a HSA.
@@ -153,8 +162,8 @@ export namespace IndividualBenefit {
153
162
  hsa_contribution_limit?: 'individual' | 'family' | null;
154
163
  }
155
164
 
156
- export namespace UnionMember0 {
157
- export interface UnionMember0 {
165
+ export namespace IndividualBenefit {
166
+ export interface CompanyContributionFixed {
158
167
  /**
159
168
  * Contribution amount in cents (for type=fixed) or basis points (for type=percent,
160
169
  * where 100 = 1%). Not used for type=tiered.
@@ -168,7 +177,7 @@ export namespace IndividualBenefit {
168
177
  type: 'fixed';
169
178
  }
170
179
 
171
- export interface UnionMember1 {
180
+ export interface CompanyContributionPercent {
172
181
  /**
173
182
  * Contribution amount in cents (for type=fixed) or basis points (for type=percent,
174
183
  * where 100 = 1%). Not used for type=tiered.
@@ -182,12 +191,12 @@ export namespace IndividualBenefit {
182
191
  type: 'percent';
183
192
  }
184
193
 
185
- export interface UnionMember2 {
194
+ export interface CompanyContributionTiered {
186
195
  /**
187
196
  * Array of tier objects defining employer match tiers based on employee
188
197
  * contribution thresholds. Required when type=tiered.
189
198
  */
190
- tiers: Array<UnionMember2.Tier>;
199
+ tiers: Array<CompanyContributionTiered.Tier>;
191
200
 
192
201
  /**
193
202
  * Contribution type. Supported values: "fixed" (amount in cents), "percent"
@@ -196,7 +205,7 @@ export namespace IndividualBenefit {
196
205
  type: 'tiered';
197
206
  }
198
207
 
199
- export namespace UnionMember2 {
208
+ export namespace CompanyContributionTiered {
200
209
  export interface Tier {
201
210
  match: number;
202
211
 
@@ -204,7 +213,7 @@ export namespace IndividualBenefit {
204
213
  }
205
214
  }
206
215
 
207
- export interface UnionMember0 {
216
+ export interface EmployeeDeductionContributionFixed {
208
217
  /**
209
218
  * Contribution amount in cents (for type=fixed) or basis points (for type=percent,
210
219
  * where 100 = 1%).
@@ -218,7 +227,7 @@ export namespace IndividualBenefit {
218
227
  type: 'fixed';
219
228
  }
220
229
 
221
- export interface UnionMember1 {
230
+ export interface EmployeeDeductionContributionPercent {
222
231
  /**
223
232
  * Contribution amount in cents (for type=fixed) or basis points (for type=percent,
224
233
  * where 100 = 1%).
@@ -29,7 +29,7 @@ export class CompanyResource extends APIResource {
29
29
  query: CompanyRetrieveParams | null | undefined = {},
30
30
  options?: RequestOptions,
31
31
  ): APIPromise<Company> {
32
- return this._client.get('/employer/company', { query, ...options });
32
+ return this._client.get('/employer/company', { query, ...options, __security: { bearerAuth: true } });
33
33
  }
34
34
  }
35
35
 
@@ -39,7 +39,7 @@ export class PayStatementItem extends APIResource {
39
39
  return this._client.getAPIList(
40
40
  '/employer/pay-statement-item',
41
41
  ResponsesPage<PayStatementItemListResponse>,
42
- { query, ...options },
42
+ { query, ...options, __security: { bearerAuth: true } },
43
43
  );
44
44
  }
45
45
  }
@@ -28,6 +28,7 @@ export class Rules extends APIResource {
28
28
  query: { entity_ids },
29
29
  body,
30
30
  ...options,
31
+ __security: { bearerAuth: true },
31
32
  });
32
33
  }
33
34
 
@@ -52,6 +53,7 @@ export class Rules extends APIResource {
52
53
  query: { entity_ids },
53
54
  body,
54
55
  ...options,
56
+ __security: { bearerAuth: true },
55
57
  });
56
58
  }
57
59
 
@@ -73,6 +75,7 @@ export class Rules extends APIResource {
73
75
  return this._client.getAPIList('/employer/pay-statement-item/rule', ResponsesPage<RuleListResponse>, {
74
76
  query,
75
77
  ...options,
78
+ __security: { bearerAuth: true },
76
79
  });
77
80
  }
78
81
 
@@ -96,6 +99,7 @@ export class Rules extends APIResource {
96
99
  return this._client.delete(path`/employer/pay-statement-item/rule/${ruleID}`, {
97
100
  query: { entity_ids },
98
101
  ...options,
102
+ __security: { bearerAuth: true },
99
103
  });
100
104
  }
101
105
  }