modern-treasury 0.0.1 → 0.2.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 (151) hide show
  1. package/README.md +14 -17
  2. package/build +2 -0
  3. package/check-version.ts +22 -0
  4. package/core.ts +160 -64
  5. package/dist/cjs/check-version.d.ts +1 -0
  6. package/dist/cjs/check-version.js +28 -0
  7. package/dist/cjs/check-version.js.map +1 -0
  8. package/dist/cjs/core.d.ts +14 -3
  9. package/dist/cjs/core.js +129 -64
  10. package/dist/cjs/core.js.map +1 -1
  11. package/dist/cjs/index.d.ts +30 -1
  12. package/dist/cjs/index.js +17 -1
  13. package/dist/cjs/index.js.map +1 -1
  14. package/dist/cjs/pagination.d.ts +1 -1
  15. package/dist/cjs/resources/counterparties.d.ts +63 -63
  16. package/dist/cjs/resources/documents.d.ts +10 -10
  17. package/dist/cjs/resources/events.d.ts +10 -10
  18. package/dist/cjs/resources/expected-payments.d.ts +35 -34
  19. package/dist/cjs/resources/expected-payments.js +4 -1
  20. package/dist/cjs/resources/expected-payments.js.map +1 -1
  21. package/dist/cjs/resources/external-accounts.d.ts +66 -66
  22. package/dist/cjs/resources/incoming-payment-details.d.ts +65 -65
  23. package/dist/cjs/resources/index.d.ts +5 -0
  24. package/dist/cjs/resources/index.js +5 -0
  25. package/dist/cjs/resources/index.js.map +1 -1
  26. package/dist/cjs/resources/internal-accounts.d.ts +74 -65
  27. package/dist/cjs/resources/ledger-account-categories.d.ts +215 -0
  28. package/dist/cjs/resources/ledger-account-categories.js +103 -0
  29. package/dist/cjs/resources/ledger-account-categories.js.map +1 -0
  30. package/dist/cjs/resources/ledger-accounts.d.ts +239 -0
  31. package/dist/cjs/resources/ledger-accounts.js +43 -0
  32. package/dist/cjs/resources/ledger-accounts.js.map +1 -0
  33. package/dist/cjs/resources/ledger-entries.d.ts +101 -0
  34. package/dist/cjs/resources/ledger-entries.js +25 -0
  35. package/dist/cjs/resources/ledger-entries.js.map +1 -0
  36. package/dist/cjs/resources/ledger-transactions.d.ts +298 -0
  37. package/dist/cjs/resources/ledger-transactions.js +41 -0
  38. package/dist/cjs/resources/ledger-transactions.js.map +1 -0
  39. package/dist/cjs/resources/ledgers.d.ts +101 -0
  40. package/dist/cjs/resources/ledgers.js +43 -0
  41. package/dist/cjs/resources/ledgers.js.map +1 -0
  42. package/dist/cjs/resources/line-items.d.ts +12 -12
  43. package/dist/cjs/resources/paper-items.d.ts +17 -17
  44. package/dist/cjs/resources/payment-orders/payment-orders.d.ts +156 -76
  45. package/dist/cjs/resources/payment-orders/payment-orders.js +5 -1
  46. package/dist/cjs/resources/payment-orders/payment-orders.js.map +1 -1
  47. package/dist/cjs/resources/payment-orders/reversals.d.ts +9 -9
  48. package/dist/cjs/resources/returns.d.ts +31 -28
  49. package/dist/cjs/resources/transactions.d.ts +23 -22
  50. package/dist/cjs/resources/validations.d.ts +6 -0
  51. package/dist/cjs/tests/api-resources/counterparties.test.js +9 -9
  52. package/dist/cjs/tests/api-resources/counterparties.test.js.map +1 -1
  53. package/dist/cjs/tests/api-resources/documents.test.js +1 -1
  54. package/dist/cjs/tests/api-resources/documents.test.js.map +1 -1
  55. package/dist/cjs/tests/api-resources/events.test.js +1 -1
  56. package/dist/cjs/tests/api-resources/events.test.js.map +1 -1
  57. package/dist/cjs/tests/api-resources/expected-payments.test.js +56 -14
  58. package/dist/cjs/tests/api-resources/expected-payments.test.js.map +1 -1
  59. package/dist/cjs/tests/api-resources/external-accounts.test.js +6 -6
  60. package/dist/cjs/tests/api-resources/external-accounts.test.js.map +1 -1
  61. package/dist/cjs/tests/api-resources/incoming-payment-details.test.js +7 -5
  62. package/dist/cjs/tests/api-resources/incoming-payment-details.test.js.map +1 -1
  63. package/dist/cjs/tests/api-resources/internal-accounts.test.js +5 -3
  64. package/dist/cjs/tests/api-resources/internal-accounts.test.js.map +1 -1
  65. package/dist/cjs/tests/api-resources/ledger-account-categories.test.d.ts +1 -0
  66. package/dist/cjs/tests/api-resources/ledger-account-categories.test.js +216 -0
  67. package/dist/cjs/tests/api-resources/ledger-account-categories.test.js.map +1 -0
  68. package/dist/cjs/tests/api-resources/ledger-accounts.test.d.ts +1 -0
  69. package/dist/cjs/tests/api-resources/ledger-accounts.test.js +189 -0
  70. package/dist/cjs/tests/api-resources/ledger-accounts.test.js.map +1 -0
  71. package/dist/cjs/tests/api-resources/ledger-entries.test.d.ts +1 -0
  72. package/dist/cjs/tests/api-resources/ledger-entries.test.js +106 -0
  73. package/dist/cjs/tests/api-resources/ledger-entries.test.js.map +1 -0
  74. package/dist/cjs/tests/api-resources/ledger-transactions.test.d.ts +1 -0
  75. package/dist/cjs/tests/api-resources/ledger-transactions.test.js +276 -0
  76. package/dist/cjs/tests/api-resources/ledger-transactions.test.js.map +1 -0
  77. package/dist/cjs/tests/api-resources/ledgers.test.d.ts +1 -0
  78. package/dist/cjs/tests/api-resources/ledgers.test.js +151 -0
  79. package/dist/cjs/tests/api-resources/ledgers.test.js.map +1 -0
  80. package/dist/cjs/tests/api-resources/line-items.test.js +3 -3
  81. package/dist/cjs/tests/api-resources/line-items.test.js.map +1 -1
  82. package/dist/cjs/tests/api-resources/paper-items.test.js +1 -1
  83. package/dist/cjs/tests/api-resources/paper-items.test.js.map +1 -1
  84. package/dist/cjs/tests/api-resources/payment-orders/payment-orders.test.js +505 -10
  85. package/dist/cjs/tests/api-resources/payment-orders/payment-orders.test.js.map +1 -1
  86. package/dist/cjs/tests/api-resources/payment-orders/reversals.test.d.ts +1 -0
  87. package/dist/cjs/tests/api-resources/payment-orders/reversals.test.js +77 -0
  88. package/dist/cjs/tests/api-resources/payment-orders/reversals.test.js.map +1 -0
  89. package/dist/cjs/tests/api-resources/returns.test.js +1 -1
  90. package/dist/cjs/tests/api-resources/returns.test.js.map +1 -1
  91. package/dist/cjs/tests/api-resources/top-level.test.js +1 -1
  92. package/dist/cjs/tests/api-resources/top-level.test.js.map +1 -1
  93. package/dist/cjs/tests/api-resources/transactions.test.js +9 -5
  94. package/dist/cjs/tests/api-resources/transactions.test.js.map +1 -1
  95. package/dist/cjs/tests/api-resources/validations.test.js +1 -1
  96. package/dist/cjs/tests/api-resources/validations.test.js.map +1 -1
  97. package/dist/cjs/tests/api-resources/webhooks.test.js +1 -1
  98. package/dist/cjs/tests/api-resources/webhooks.test.js.map +1 -1
  99. package/dist/cjs/tests/index.test.js +6 -15
  100. package/dist/cjs/tests/index.test.js.map +1 -1
  101. package/dist/cjs/version.d.ts +1 -0
  102. package/dist/cjs/version.js +5 -0
  103. package/dist/cjs/version.js.map +1 -0
  104. package/index.ts +43 -2
  105. package/package.json +3 -3
  106. package/pagination.ts +1 -1
  107. package/resources/counterparties.ts +63 -63
  108. package/resources/documents.ts +10 -10
  109. package/resources/events.ts +10 -10
  110. package/resources/expected-payments.ts +46 -36
  111. package/resources/external-accounts.ts +66 -66
  112. package/resources/incoming-payment-details.ts +65 -65
  113. package/resources/index.ts +5 -0
  114. package/resources/internal-accounts.ts +77 -65
  115. package/resources/ledger-account-categories.ts +322 -0
  116. package/resources/ledger-accounts.ts +336 -0
  117. package/resources/ledger-entries.ts +140 -0
  118. package/resources/ledger-transactions.ts +381 -0
  119. package/resources/ledgers.ts +154 -0
  120. package/resources/line-items.ts +12 -12
  121. package/resources/paper-items.ts +17 -17
  122. package/resources/payment-orders/payment-orders.ts +166 -82
  123. package/resources/payment-orders/reversals.ts +9 -9
  124. package/resources/returns.ts +31 -28
  125. package/resources/transactions.ts +23 -22
  126. package/resources/validations.ts +7 -0
  127. package/tests/api-resources/counterparties.test.ts +9 -9
  128. package/tests/api-resources/documents.test.ts +1 -1
  129. package/tests/api-resources/events.test.ts +1 -1
  130. package/tests/api-resources/expected-payments.test.ts +56 -14
  131. package/tests/api-resources/external-accounts.test.ts +6 -6
  132. package/tests/api-resources/incoming-payment-details.test.ts +7 -5
  133. package/tests/api-resources/internal-accounts.test.ts +8 -3
  134. package/tests/api-resources/ledger-account-categories.test.ts +174 -0
  135. package/tests/api-resources/ledger-accounts.test.ts +151 -0
  136. package/tests/api-resources/ledger-entries.test.ts +68 -0
  137. package/tests/api-resources/ledger-transactions.test.ts +238 -0
  138. package/tests/api-resources/ledgers.test.ts +109 -0
  139. package/tests/api-resources/line-items.test.ts +3 -3
  140. package/tests/api-resources/paper-items.test.ts +1 -1
  141. package/tests/api-resources/payment-orders/payment-orders.test.ts +506 -10
  142. package/tests/api-resources/payment-orders/reversals.test.ts +39 -0
  143. package/tests/api-resources/returns.test.ts +1 -1
  144. package/tests/api-resources/top-level.test.ts +1 -1
  145. package/tests/api-resources/transactions.test.ts +9 -5
  146. package/tests/api-resources/validations.test.ts +1 -1
  147. package/tests/api-resources/webhooks.test.ts +1 -1
  148. package/tests/index.test.ts +6 -15
  149. package/tsconfig.json +2 -1
  150. package/typings/digest-fetch/index.d.ts +33 -0
  151. package/version.ts +1 -0
package/README.md CHANGED
@@ -24,18 +24,17 @@ import ModernTreasury from 'modern-treasury';
24
24
 
25
25
  const modernTreasury = new ModernTreasury({
26
26
  apiKey: 'my api key', // defaults to process.env["MODERN_TREASURY_API_KEY"]
27
- organizationId: 'my organization id',
27
+ organizationId: 'my-organization-ID',
28
28
  });
29
29
 
30
30
  async function main() {
31
- const externalAccount = await modernTreasury.externalAccounts.create({
32
- counterparty_id: '123',
33
- name: 'my bank',
31
+ const counterparty = await modernTreasury.counterparties.create({
32
+ name: 'my first counterparty',
34
33
  });
35
34
 
36
- console.log(externalAccount.id);
35
+ console.log(counterparty.id);
37
36
  }
38
- main();
37
+ main().catch(console.error);
39
38
  ```
40
39
 
41
40
  ### Usage with TypeScript
@@ -48,17 +47,15 @@ import ModernTreasury from 'modern-treasury';
48
47
 
49
48
  const modernTreasury = new ModernTreasury({
50
49
  apiKey: 'my api key', // defaults to process.env["MODERN_TREASURY_API_KEY"]
51
- organizationId: 'my organization id',
50
+ organizationId: 'my-organization-ID',
52
51
  });
53
52
 
54
53
  async function main() {
55
- const params: ModernTreasury.ExternalAccountCreateParams = { counterparty_id: '123', name: 'my bank' };
54
+ const params: ModernTreasury.CounterpartyCreateParams = { name: 'my first counterparty' };
56
55
 
57
- const externalAccount: ModernTreasury.ExternalAccount = await modernTreasury.externalAccounts.create(
58
- params,
59
- );
56
+ const counterparty: ModernTreasury.Counterparty = await modernTreasury.counterparties.create(params);
60
57
  }
61
- main();
58
+ main().catch(console.error);
62
59
  ```
63
60
 
64
61
  Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
@@ -82,7 +79,7 @@ async function main() {
82
79
  }
83
80
  });
84
81
  }
85
- main();
82
+ main().catch(console.error);
86
83
  ```
87
84
 
88
85
  Error codes are as followed:
@@ -111,7 +108,7 @@ You can use the `maxRetries` option to configure or disable this:
111
108
  // Configure the default for all requests:
112
109
  const modernTreasury = new ModernTreasury({
113
110
  maxRetries: 0, // default is 2
114
- organizationId: 'my organization id',
111
+ organizationId: 'my-organization-ID',
115
112
  });
116
113
 
117
114
  // Or, configure per-request:
@@ -129,7 +126,7 @@ Requests time out after 60 seconds by default. You can configure this with a `ti
129
126
  // Configure the default for all requests:
130
127
  const modernTreasury = new ModernTreasury({
131
128
  timeout: 20 * 1000, // 20 seconds (default is 60s)
132
- organizationId: 'my organization id',
129
+ organizationId: 'my-organization-ID',
133
130
  });
134
131
 
135
132
  // Override per-request:
@@ -172,7 +169,7 @@ import HttpsProxyAgent from 'https-proxy-agent';
172
169
  // Configure the default for all requests:
173
170
  const modernTreasury = new ModernTreasury({
174
171
  httpAgent: new HttpsProxyAgent(process.env.PROXY_URL),
175
- organizationId: 'my organization id',
172
+ organizationId: 'my-organization-ID',
176
173
  });
177
174
 
178
175
  // Override per-request:
@@ -188,7 +185,7 @@ This package is in beta. Its internals and interfaces are not stable
188
185
  and subject to change without a major semver bump;
189
186
  please reach out if you rely on any undocumented behavior.
190
187
 
191
- We are keen for your feedback; please email us at [dev-feedback@moderntreasury.com](mailto:dev-feedback@moderntreasury.com)
188
+ We are keen for your feedback; please email us at [sdk-feedback@moderntreasury.com](mailto:sdk-feedback@moderntreasury.com)
192
189
  or open an issue with questions, bugs, or suggestions.
193
190
 
194
191
  ## Requirements
package/build CHANGED
@@ -3,6 +3,8 @@ set -euo pipefail
3
3
 
4
4
  rm -rf dist/*
5
5
 
6
+ yarn tsn check-version.ts
7
+
6
8
  tsc -p tsconfig.cjs.json
7
9
 
8
10
  tsc-alias -p tsconfig.cjs.json
@@ -0,0 +1,22 @@
1
+ import fs from 'fs';
2
+ import { VERSION } from './version';
3
+
4
+ const main = () => {
5
+ const pkg = JSON.parse(fs.readFileSync('package.json').toString()) as Record<string, unknown>;
6
+ const version = pkg['version'];
7
+ if (!version) throw 'The version property is not set in the package.json file';
8
+ if (typeof version !== 'string') {
9
+ throw `Unexpected type for the package.json version field; got ${typeof version}, expected string`;
10
+ }
11
+ if (version !== VERSION) {
12
+ throw (
13
+ `Version mismatch; package.json = ${version}, version.ts = ${VERSION}; ` +
14
+ `Please update the package.json version property or modify the VERSION variable in version.ts to ensure they match`
15
+ );
16
+ }
17
+ console.log(`Versions ${version} (package.json) and ${VERSION} (version.ts) match`);
18
+ };
19
+
20
+ if (require.main === module) {
21
+ main();
22
+ }
package/core.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import qs from 'qs';
2
- import pkgUp from 'pkg-up';
3
2
 
4
3
  import type { Agent } from 'http';
5
4
  import type NodeFetch from 'node-fetch';
@@ -8,9 +7,10 @@ import type KeepAliveAgent from 'agentkeepalive';
8
7
  import { AbortController } from 'abort-controller';
9
8
  import { FormData, File, Blob } from 'formdata-node';
10
9
  import { FormDataEncoder } from 'form-data-encoder';
11
-
12
10
  import { Readable } from 'stream';
13
11
 
12
+ import { VERSION } from './version';
13
+
14
14
  const isNode = typeof process !== 'undefined';
15
15
  let nodeFetch: typeof NodeFetch | undefined = undefined;
16
16
  let getDefaultAgent = (_url: string): Agent | undefined => undefined;
@@ -29,6 +29,8 @@ if (isNode) {
29
29
  const DEFAULT_MAX_RETRIES = 2;
30
30
  const DEFAULT_TIMEOUT = 60 * 1000; // 60s
31
31
 
32
+ type Fetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
33
+
32
34
  export abstract class APIClient {
33
35
  apiKey: string | null;
34
36
  baseURL: string;
@@ -36,7 +38,7 @@ export abstract class APIClient {
36
38
  timeout: number;
37
39
  httpAgent: Agent | undefined;
38
40
 
39
- private fetch: typeof NodeFetch;
41
+ private fetch: Fetch;
40
42
  protected idempotencyHeader?: string;
41
43
 
42
44
  constructor({
@@ -68,7 +70,7 @@ export abstract class APIClient {
68
70
  );
69
71
  }
70
72
  // For now, we just pretend that Fetch is the same type as NodeFetch.
71
- this.fetch = fetch as unknown as typeof NodeFetch;
73
+ this.fetch = fetch as unknown as Fetch;
72
74
  }
73
75
  }
74
76
 
@@ -89,7 +91,7 @@ export abstract class APIClient {
89
91
  Accept: 'application/json',
90
92
  'Content-Type': 'application/json',
91
93
  'User-Agent': this.getUserAgent(),
92
- 'X-Stainless-Client-User-Agent': getPlatformPropertiesJSON(),
94
+ ...getPlatformHeaders(),
93
95
  ...this.authHeaders(),
94
96
  };
95
97
  }
@@ -241,9 +243,15 @@ export abstract class APIClient {
241
243
 
242
244
  const timeout = setTimeout(() => controller.abort(), ms);
243
245
 
244
- return this.fetch(url, { signal: controller.signal as any, ...options }).finally(() => {
245
- clearTimeout(timeout);
246
- });
246
+ return this.getRequestClient()
247
+ .fetch(url, { signal: controller.signal as any, ...options })
248
+ .finally(() => {
249
+ clearTimeout(timeout);
250
+ });
251
+ }
252
+
253
+ protected getRequestClient(): RequestClient {
254
+ return { fetch: this.fetch };
247
255
  }
248
256
 
249
257
  private shouldRetry(response: Response): boolean {
@@ -312,8 +320,7 @@ export abstract class APIClient {
312
320
  }
313
321
 
314
322
  private getUserAgent(): string {
315
- const packageVersion = getPackageVersion();
316
- return `${this.constructor.name}/JS ${packageVersion}`;
323
+ return `${this.constructor.name}/JS ${VERSION}`;
317
324
  }
318
325
 
319
326
  private debug(action: string, ...args: any[]) {
@@ -438,7 +445,7 @@ export class PagePromise<
438
445
  }
439
446
 
440
447
  export const createResponseHeaders = (
441
- headers: Awaited<ReturnType<typeof NodeFetch>>['headers'],
448
+ headers: Awaited<ReturnType<Fetch>>['headers'],
442
449
  ): Record<string, string> => {
443
450
  return new Proxy(Object.fromEntries(headers.entries()), {
444
451
  get(target, name) {
@@ -450,6 +457,7 @@ export const createResponseHeaders = (
450
457
 
451
458
  type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
452
459
 
460
+ export type RequestClient = { fetch: Fetch };
453
461
  export type Headers = Record<string, string | null | undefined>;
454
462
  export type KeysEnum<T> = { [P in keyof Required<T>]: true };
455
463
 
@@ -577,53 +585,98 @@ export class APIConnectionTimeoutError extends APIConnectionError {
577
585
  }
578
586
  }
579
587
 
580
- let _packageVersion: string;
581
- const getPackageVersion = (): string => {
582
- try {
583
- // eslint-disable-next-line @typescript-eslint/no-var-requires
584
- return (_packageVersion ??= require(pkgUp.sync()!).version);
585
- } catch (e) {
586
- console.debug(`Ignoring error while determing package version ${e}`);
587
- return (_packageVersion = 'unknown');
588
- }
589
- };
590
-
591
588
  declare const Deno: any;
589
+ type Arch = 'x32' | 'x64' | 'arm' | 'arm64' | `other:${string}` | 'unknown';
590
+ type PlatformName =
591
+ | 'MacOS'
592
+ | 'Linux'
593
+ | 'Windows'
594
+ | 'FreeBSD'
595
+ | 'OpenBSD'
596
+ | 'iOS'
597
+ | 'Android'
598
+ | `Other:${string}`
599
+ | 'Unknown';
592
600
  type PlatformProperties = {
593
- lang: 'js';
594
- packageVersion: string;
595
- os: string;
596
- arch: string;
597
- runtime: 'node' | 'deno';
598
- runtimeVersion: string;
601
+ 'X-Stainless-Lang': 'js';
602
+ 'X-Stainless-Package-Version': string;
603
+ 'X-Stainless-OS': PlatformName;
604
+ 'X-Stainless-Arch': Arch;
605
+ 'X-Stainless-Runtime': 'node' | 'deno' | 'unknown';
606
+ 'X-Stainless-Runtime-Version': string;
599
607
  };
600
- const getPlatformProperties = (): PlatformProperties | void => {
608
+ const getPlatformProperties = (): PlatformProperties => {
601
609
  if (typeof process !== 'undefined') {
602
610
  return {
603
- lang: 'js',
604
- packageVersion: getPackageVersion(),
605
- os: process.platform,
606
- arch: process.arch,
607
- runtime: 'node',
608
- runtimeVersion: process.version,
611
+ 'X-Stainless-Lang': 'js',
612
+ 'X-Stainless-Package-Version': VERSION,
613
+ 'X-Stainless-OS': normalizePlatform(process.platform),
614
+ 'X-Stainless-Arch': normalizeArch(process.arch),
615
+ 'X-Stainless-Runtime': 'node',
616
+ 'X-Stainless-Runtime-Version': process.version,
609
617
  };
610
618
  }
611
619
  if (typeof Deno !== 'undefined') {
612
620
  return {
613
- lang: 'js',
614
- packageVersion: getPackageVersion(),
615
- os: Deno.build.os,
616
- arch: Deno.build.arch,
617
- runtime: 'deno',
618
- runtimeVersion: Deno.version,
621
+ 'X-Stainless-Lang': 'js',
622
+ 'X-Stainless-Package-Version': VERSION,
623
+ 'X-Stainless-OS': normalizePlatform(Deno.build.os),
624
+ 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
625
+ 'X-Stainless-Runtime': 'deno',
626
+ 'X-Stainless-Runtime-Version': Deno.version,
619
627
  };
620
628
  }
621
629
  // TODO add support for Cloudflare workers, browsers, etc.
630
+ return {
631
+ 'X-Stainless-Lang': 'js',
632
+ 'X-Stainless-Package-Version': VERSION,
633
+ 'X-Stainless-OS': 'Unknown',
634
+ 'X-Stainless-Arch': 'unknown',
635
+ 'X-Stainless-Runtime': 'unknown',
636
+ 'X-Stainless-Runtime-Version': 'unknown',
637
+ };
638
+ };
639
+
640
+ const normalizeArch = (arch: string): Arch => {
641
+ // Node docs:
642
+ // - https://nodejs.org/api/process.html#processarch
643
+ // Deno docs:
644
+ // - https://doc.deno.land/deno/stable/~/Deno.build
645
+ if (arch === 'x32') return 'x32';
646
+ if (arch === 'x86_64' || arch === 'x64') return 'x64';
647
+ if (arch === 'arm') return 'arm';
648
+ if (arch === 'aarch64' || arch === 'arm64') return 'arm64';
649
+ if (arch) return `other:${arch}`;
650
+ return 'unknown';
651
+ };
652
+
653
+ const normalizePlatform = (platform: string): PlatformName => {
654
+ // Node platforms:
655
+ // - https://nodejs.org/api/process.html#processplatform
656
+ // Deno platforms:
657
+ // - https://doc.deno.land/deno/stable/~/Deno.build
658
+ // - https://github.com/denoland/deno/issues/14799
659
+
660
+ platform = platform.toLowerCase();
661
+
662
+ // NOTE: this iOS check is untested and may not work
663
+ // Node does not work natively on IOS, there is a fork at
664
+ // https://github.com/nodejs-mobile/nodejs-mobile
665
+ // however it is unknown at the time of writing how to detect if it is running
666
+ if (platform.includes('ios')) return 'iOS';
667
+ if (platform === 'android') return 'Android';
668
+ if (platform === 'darwin') return 'MacOS';
669
+ if (platform === 'win32') return 'Windows';
670
+ if (platform === 'freebsd') return 'FreeBSD';
671
+ if (platform === 'openbsd') return 'OpenBSD';
672
+ if (platform === 'linux') return 'Linux';
673
+ if (platform) return `Other:${platform}`;
674
+ return 'Unknown';
622
675
  };
623
676
 
624
- let _platformPropertiesJSON: string;
625
- const getPlatformPropertiesJSON = () => {
626
- return (_platformPropertiesJSON ??= JSON.stringify(getPlatformProperties())) || '';
677
+ let _platformHeaders: PlatformProperties;
678
+ const getPlatformHeaders = () => {
679
+ return (_platformHeaders ??= getPlatformProperties());
627
680
  };
628
681
 
629
682
  const safeJSON = (text: string) => {
@@ -657,35 +710,42 @@ const castToError = (err: any): Error => {
657
710
  return new Error(err);
658
711
  };
659
712
 
660
- const validateFormValue = (value: unknown): string | number | boolean | File | Blob => {
661
- if (
662
- typeof value === 'string' ||
663
- typeof value === 'number' ||
664
- typeof value === 'boolean' ||
665
- value instanceof File ||
666
- value instanceof Blob
667
- ) {
668
- return value;
669
- }
713
+ /**
714
+ * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value.
715
+ * Otherwise returns the request as is.
716
+ */
717
+ export const maybeMultipartFormRequestOptions = <T = Record<string, unknown>>(
718
+ opts: RequestOptions<T>,
719
+ ): RequestOptions<T | Readable> => {
720
+ // TODO: does this add unreasonable overhead in the case where we shouldn't use multipart/form-data?
721
+ const form = createForm(opts.body);
670
722
 
671
- if (value == null) {
672
- throw new TypeError(
673
- `null is not a valid form data value, if you want to pass null then you need to use the string 'null'`,
674
- );
723
+ for (const [_, entry] of form.entries()) {
724
+ const value = entry.valueOf();
725
+ if (value instanceof File || value instanceof Blob) {
726
+ return getMultipartRequestOptions(form, opts);
727
+ }
675
728
  }
676
729
 
677
- throw new TypeError(
678
- `Invalid value given to form, expected a string, number, boolean, File or Blob but got ${value} instead`,
679
- );
730
+ return opts;
680
731
  };
681
732
 
682
733
  export const multipartFormRequestOptions = <T = Record<string, unknown>>(
683
734
  opts: RequestOptions<T>,
684
735
  ): RequestOptions<T | Readable> => {
736
+ return getMultipartRequestOptions(createForm(opts.body), opts);
737
+ };
738
+
739
+ const createForm = <T = Record<string, unknown>>(body: T | undefined): FormData => {
685
740
  const form = new FormData();
686
- Object.entries(opts.body || {}).forEach(
687
- ([key, value]) => value !== undefined && form.set(key, validateFormValue(value)),
688
- );
741
+ Object.entries(body || {}).forEach(([key, value]) => addFormValue(form, key, value));
742
+ return form;
743
+ };
744
+
745
+ const getMultipartRequestOptions = <T = Record<string, unknown>>(
746
+ form: FormData,
747
+ opts: RequestOptions<T>,
748
+ ): RequestOptions<T | Readable> => {
689
749
  const encoder = new FormDataEncoder(form);
690
750
  return {
691
751
  ...opts,
@@ -694,6 +754,42 @@ export const multipartFormRequestOptions = <T = Record<string, unknown>>(
694
754
  };
695
755
  };
696
756
 
757
+ const addFormValue = (form: FormData, key: string, value: unknown) => {
758
+ if (value == null) {
759
+ throw new TypeError(
760
+ `null is not a valid form data value, if you want to pass null then you need to use the string 'null'`,
761
+ );
762
+ }
763
+
764
+ // TODO: make nested formats configurable
765
+ if (
766
+ typeof value === 'string' ||
767
+ typeof value === 'number' ||
768
+ typeof value === 'boolean' ||
769
+ value instanceof File ||
770
+ value instanceof Blob
771
+ ) {
772
+ if (form.has(key)) {
773
+ throw new Error(
774
+ `Received multiple values for FormData with the same key: ${key}; This behaviour is not supported.`,
775
+ );
776
+ }
777
+ form.append(key, value);
778
+ } else if (Array.isArray(value)) {
779
+ value.forEach((entry) => {
780
+ addFormValue(form, key + '[]', entry);
781
+ });
782
+ } else if (typeof value === 'object') {
783
+ Object.entries(value).forEach(([name, prop]) => {
784
+ addFormValue(form, `${key}[${name}]`, prop);
785
+ });
786
+ } else {
787
+ throw new TypeError(
788
+ `Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`,
789
+ );
790
+ }
791
+ };
792
+
697
793
  export const coerceInteger = (value: unknown): number => {
698
794
  if (typeof value === 'number') return Math.round(value);
699
795
  if (typeof value === 'string') return parseInt(value);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod };
6
+ };
7
+ Object.defineProperty(exports, '__esModule', { value: true });
8
+ const fs_1 = __importDefault(require('fs'));
9
+ const version_1 = require('./version');
10
+ const main = () => {
11
+ const pkg = JSON.parse(fs_1.default.readFileSync('package.json').toString());
12
+ const version = pkg['version'];
13
+ if (!version) throw 'The version property is not set in the package.json file';
14
+ if (typeof version !== 'string') {
15
+ throw `Unexpected type for the package.json version field; got ${typeof version}, expected string`;
16
+ }
17
+ if (version !== version_1.VERSION) {
18
+ throw (
19
+ `Version mismatch; package.json = ${version}, version.ts = ${version_1.VERSION}; ` +
20
+ `Please update the package.json version property or modify the VERSION variable in version.ts to ensure they match`
21
+ );
22
+ }
23
+ console.log(`Versions ${version} (package.json) and ${version_1.VERSION} (version.ts) match`);
24
+ };
25
+ if (require.main === module) {
26
+ main();
27
+ }
28
+ //# sourceMappingURL=check-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-version.js","sourceRoot":"","sources":["../../check-version.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,uCAAoC;AAEpC,MAAM,IAAI,GAAG,GAAG,EAAE;IAChB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAA4B,CAAC;IAC9F,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,MAAM,0DAA0D,CAAC;IAC/E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,MAAM,2DAA2D,OAAO,OAAO,mBAAmB,CAAC;KACpG;IACD,IAAI,OAAO,KAAK,iBAAO,EAAE;QACvB,MAAM,CACJ,oCAAoC,OAAO,kBAAkB,iBAAO,IAAI;YACxE,mHAAmH,CACpH,CAAC;KACH;IACD,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,uBAAuB,iBAAO,qBAAqB,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,IAAI,EAAE,CAAC;CACR"}
@@ -2,9 +2,9 @@
2
2
  /// <reference types="node" />
3
3
  import qs from 'qs';
4
4
  import type { Agent } from 'http';
5
- import type NodeFetch from 'node-fetch';
6
5
  import type { RequestInfo, RequestInit, Response } from 'node-fetch';
7
6
  import { Readable } from 'stream';
7
+ declare type Fetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
8
8
  export declare abstract class APIClient {
9
9
  apiKey: string | null;
10
10
  baseURL: string;
@@ -67,6 +67,7 @@ export declare abstract class APIClient {
67
67
  { signal, ...options }: RequestInit | undefined,
68
68
  ms: number,
69
69
  ): Promise<Response>;
70
+ protected getRequestClient(): RequestClient;
70
71
  private shouldRetry;
71
72
  private retryRequest;
72
73
  private calculateRetryTimeoutSeconds;
@@ -125,9 +126,12 @@ export declare class PagePromise<
125
126
  [Symbol.asyncIterator](): AsyncGenerator<Awaited<Item>, void, unknown>;
126
127
  }
127
128
  export declare const createResponseHeaders: (
128
- headers: Awaited<ReturnType<typeof NodeFetch>>['headers'],
129
+ headers: Awaited<ReturnType<Fetch>>['headers'],
129
130
  ) => Record<string, string>;
130
131
  declare type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
132
+ export declare type RequestClient = {
133
+ fetch: Fetch;
134
+ };
131
135
  export declare type Headers = Record<string, string | null | undefined>;
132
136
  export declare type KeysEnum<T> = {
133
137
  [P in keyof Required<T>]: true;
@@ -144,7 +148,7 @@ export declare type RequestOptions<Req extends {} = Record<string, unknown> | Re
144
148
  };
145
149
  export declare const isRequestOptions: (
146
150
  obj: unknown,
147
- ) => obj is RequestOptions<Readable | Record<string, unknown>>;
151
+ ) => obj is RequestOptions<Record<string, unknown> | Readable>;
148
152
  export declare type FinalRequestOptions<Req extends {} = Record<string, unknown> | Readable> =
149
153
  RequestOptions<Req> & {
150
154
  method: HTTPMethod;
@@ -200,6 +204,13 @@ export declare class APIConnectionError extends APIError {
200
204
  export declare class APIConnectionTimeoutError extends APIConnectionError {
201
205
  constructor();
202
206
  }
207
+ /**
208
+ * Returns a multipart/form-data request if any part of the given request body contains a File / Blob value.
209
+ * Otherwise returns the request as is.
210
+ */
211
+ export declare const maybeMultipartFormRequestOptions: <T = Record<string, unknown>>(
212
+ opts: RequestOptions<T>,
213
+ ) => RequestOptions<Readable | T>;
203
214
  export declare const multipartFormRequestOptions: <T = Record<string, unknown>>(
204
215
  opts: RequestOptions<T>,
205
216
  ) => RequestOptions<Readable | T>;