nxus-qbd 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +340 -252
- package/dist/client.d.ts +26 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -1
- package/dist/client.js.map +1 -1
- package/dist/generated/types.gen.d.ts +300 -288
- package/dist/generated/types.gen.d.ts.map +1 -1
- package/dist/generated/types.gen.js.map +1 -1
- package/dist/models/index.js +1 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/qbd/bill_payment_or_credit.js +0 -1
- package/dist/models/qbd/bill_payment_or_credit.js.map +1 -1
- package/dist/transport.d.ts +78 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +291 -20
- package/dist/transport.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,252 +1,340 @@
|
|
|
1
|
-
# nxus-qbd
|
|
2
|
-
|
|
3
|
-
Official TypeScript SDK for the [Nxus](https://nx-us.net/docs/) QuickBooks Desktop API.
|
|
4
|
-
|
|
5
|
-
## Runtime Support
|
|
6
|
-
|
|
7
|
-
Runs on **Node.js 18+** and **Bun 1.0+**. The SDK uses native `fetch` and `AbortController` with no Node-specific dependencies.
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install nxus-qbd
|
|
13
|
-
pnpm add nxus-qbd
|
|
14
|
-
bun add nxus-qbd
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Environments
|
|
18
|
-
|
|
19
|
-
The SDK targets `https://api.nx-us.net/` by default.
|
|
20
|
-
|
|
21
|
-
Use `environment: NxusEnvironment.DEVELOPMENT` to target `https://localhost:7242/`, or pass an explicit `baseUrl` override when you need a custom endpoint.
|
|
22
|
-
|
|
23
|
-
```ts
|
|
24
|
-
import { NxusClient, NxusEnvironment } from "nxus-qbd";
|
|
25
|
-
|
|
26
|
-
const nxus = new NxusClient({
|
|
27
|
-
apiKey: "sk_live_...",
|
|
28
|
-
environment: NxusEnvironment.DEVELOPMENT,
|
|
29
|
-
});
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Timeouts
|
|
33
|
-
|
|
34
|
-
The SDK defaults to a `100_000ms` client timeout so normal callers can still
|
|
35
|
-
receive the API's structured timeout responses for heavier QuickBooks
|
|
36
|
-
operations.
|
|
37
|
-
|
|
38
|
-
Advanced callers can override this globally or per request:
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { NxusClient } from "nxus-qbd";
|
|
42
|
-
|
|
43
|
-
const nxus = new NxusClient({
|
|
44
|
-
apiKey: "sk_live_...",
|
|
45
|
-
timeout: 120_000,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const page = await nxus.transactions.list({
|
|
49
|
-
connectionId: "your-connection-id",
|
|
50
|
-
limit: 100,
|
|
51
|
-
DetailLevel: "all",
|
|
52
|
-
timeout: 30_000,
|
|
53
|
-
});
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Paginated/list requests can also send a backend timeout hint without changing
|
|
57
|
-
the SDK's local abort timer:
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
const page = await nxus.transactions.list({
|
|
61
|
-
connectionId: "your-connection-id",
|
|
62
|
-
limit: 100,
|
|
63
|
-
DetailLevel: "all",
|
|
64
|
-
timeout: 30_000,
|
|
65
|
-
timeoutSeconds: 45,
|
|
66
|
-
});
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
When `timeoutSeconds` is provided on a `.list()` call, the SDK sends it as the
|
|
70
|
-
`X-Nxus-Timeout-Seconds` request header and keeps reusing that header for
|
|
71
|
-
manual `getNextPage()` calls and `for await` auto-pagination. It is not added
|
|
72
|
-
to the query string.
|
|
73
|
-
|
|
74
|
-
## Automatic Retries
|
|
75
|
-
|
|
76
|
-
The SDK automatically retries transient failures up to `2` additional times
|
|
77
|
-
(3 total attempts) with exponential backoff and jitter.
|
|
78
|
-
|
|
79
|
-
The `x-should-retry` response header from the API is the primary signal:
|
|
80
|
-
|
|
81
|
-
- `true` → retry, even for statuses that wouldn't normally retry.
|
|
82
|
-
- `false` → don't retry, even for statuses that normally would.
|
|
83
|
-
|
|
84
|
-
When the header is absent (older backend, infrastructure-level error), the SDK
|
|
85
|
-
falls back to retrying:
|
|
86
|
-
|
|
87
|
-
- Network errors (fetch threw before receiving a response)
|
|
88
|
-
- HTTP `408` (Request Timeout) and `429` (Too Many Requests)
|
|
89
|
-
- HTTP `5xx`
|
|
90
|
-
|
|
91
|
-
`409` is **not** in the fallback retry set: the API overloads `409` for both
|
|
92
|
-
retryable lock contention (`ObjectInUse`, `LockFailed`) and terminal
|
|
93
|
-
business-rule violations (`OutdatedEditSequence`, `NameNotUnique`). Without
|
|
94
|
-
`x-should-retry` to disambiguate, the safe default is to surface the error to
|
|
95
|
-
the caller. Servers that emit `x-should-retry: true` opt the retryable 409s
|
|
96
|
-
back in.
|
|
97
|
-
|
|
98
|
-
For backoff, the standard `Retry-After` response header (seconds or HTTP-date)
|
|
99
|
-
is honored when present, with `error.retryAfter` (seconds) in the JSON body
|
|
100
|
-
as a fallback. Local timeouts (the SDK's abort timer) are treated as
|
|
101
|
-
cancellations and are not retried.
|
|
102
|
-
|
|
103
|
-
Configure globally or per-request:
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
const nxus = new NxusClient({
|
|
107
|
-
apiKey: "sk_live_...",
|
|
108
|
-
maxRetries: 3, // default is 2; set to 0 to disable
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// Disable retries for one call
|
|
112
|
-
const created = await nxus.invoices.create({
|
|
113
|
-
customerRefListId: "...",
|
|
114
|
-
invoiceLineAdds: [{ itemRefListId: "...", amount: 100 }],
|
|
115
|
-
connectionId: "...",
|
|
116
|
-
maxRetries: 0,
|
|
117
|
-
});
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
##
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const nxus = new NxusClient({
|
|
172
|
-
apiKey: "sk_live_...",
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
>
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
1
|
+
# nxus-qbd
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for the [Nxus](https://nx-us.net/docs/) QuickBooks Desktop API.
|
|
4
|
+
|
|
5
|
+
## Runtime Support
|
|
6
|
+
|
|
7
|
+
Runs on **Node.js 18+** and **Bun 1.0+**. The SDK uses native `fetch` and `AbortController` with no Node-specific dependencies.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install nxus-qbd
|
|
13
|
+
pnpm add nxus-qbd
|
|
14
|
+
bun add nxus-qbd
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Environments
|
|
18
|
+
|
|
19
|
+
The SDK targets `https://api.nx-us.net/` by default.
|
|
20
|
+
|
|
21
|
+
Use `environment: NxusEnvironment.DEVELOPMENT` to target `https://localhost:7242/`, or pass an explicit `baseUrl` override when you need a custom endpoint.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { NxusClient, NxusEnvironment } from "nxus-qbd";
|
|
25
|
+
|
|
26
|
+
const nxus = new NxusClient({
|
|
27
|
+
apiKey: "sk_live_...",
|
|
28
|
+
environment: NxusEnvironment.DEVELOPMENT,
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Timeouts
|
|
33
|
+
|
|
34
|
+
The SDK defaults to a `100_000ms` client timeout so normal callers can still
|
|
35
|
+
receive the API's structured timeout responses for heavier QuickBooks
|
|
36
|
+
operations.
|
|
37
|
+
|
|
38
|
+
Advanced callers can override this globally or per request:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { NxusClient } from "nxus-qbd";
|
|
42
|
+
|
|
43
|
+
const nxus = new NxusClient({
|
|
44
|
+
apiKey: "sk_live_...",
|
|
45
|
+
timeout: 120_000,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const page = await nxus.transactions.list({
|
|
49
|
+
connectionId: "your-connection-id",
|
|
50
|
+
limit: 100,
|
|
51
|
+
DetailLevel: "all",
|
|
52
|
+
timeout: 30_000,
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Paginated/list requests can also send a backend timeout hint without changing
|
|
57
|
+
the SDK's local abort timer:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const page = await nxus.transactions.list({
|
|
61
|
+
connectionId: "your-connection-id",
|
|
62
|
+
limit: 100,
|
|
63
|
+
DetailLevel: "all",
|
|
64
|
+
timeout: 30_000,
|
|
65
|
+
timeoutSeconds: 45,
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
When `timeoutSeconds` is provided on a `.list()` call, the SDK sends it as the
|
|
70
|
+
`X-Nxus-Timeout-Seconds` request header and keeps reusing that header for
|
|
71
|
+
manual `getNextPage()` calls and `for await` auto-pagination. It is not added
|
|
72
|
+
to the query string.
|
|
73
|
+
|
|
74
|
+
## Automatic Retries
|
|
75
|
+
|
|
76
|
+
The SDK automatically retries transient failures up to `2` additional times
|
|
77
|
+
(3 total attempts) with exponential backoff and jitter.
|
|
78
|
+
|
|
79
|
+
The `x-should-retry` response header from the API is the primary signal:
|
|
80
|
+
|
|
81
|
+
- `true` → retry, even for statuses that wouldn't normally retry.
|
|
82
|
+
- `false` → don't retry, even for statuses that normally would.
|
|
83
|
+
|
|
84
|
+
When the header is absent (older backend, infrastructure-level error), the SDK
|
|
85
|
+
falls back to retrying:
|
|
86
|
+
|
|
87
|
+
- Network errors (fetch threw before receiving a response)
|
|
88
|
+
- HTTP `408` (Request Timeout) and `429` (Too Many Requests)
|
|
89
|
+
- HTTP `5xx`
|
|
90
|
+
|
|
91
|
+
`409` is **not** in the fallback retry set: the API overloads `409` for both
|
|
92
|
+
retryable lock contention (`ObjectInUse`, `LockFailed`) and terminal
|
|
93
|
+
business-rule violations (`OutdatedEditSequence`, `NameNotUnique`). Without
|
|
94
|
+
`x-should-retry` to disambiguate, the safe default is to surface the error to
|
|
95
|
+
the caller. Servers that emit `x-should-retry: true` opt the retryable 409s
|
|
96
|
+
back in.
|
|
97
|
+
|
|
98
|
+
For backoff, the standard `Retry-After` response header (seconds or HTTP-date)
|
|
99
|
+
is honored when present, with `error.retryAfter` (seconds) in the JSON body
|
|
100
|
+
as a fallback. Local timeouts (the SDK's abort timer) are treated as
|
|
101
|
+
cancellations and are not retried.
|
|
102
|
+
|
|
103
|
+
Configure globally or per-request:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const nxus = new NxusClient({
|
|
107
|
+
apiKey: "sk_live_...",
|
|
108
|
+
maxRetries: 3, // default is 2; set to 0 to disable
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Disable retries for one call
|
|
112
|
+
const created = await nxus.invoices.create({
|
|
113
|
+
customerRefListId: "...",
|
|
114
|
+
invoiceLineAdds: [{ itemRefListId: "...", amount: 100 }],
|
|
115
|
+
connectionId: "...",
|
|
116
|
+
maxRetries: 0,
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Verbose Logging
|
|
121
|
+
|
|
122
|
+
Set `verbose: true` to emit structured logs for every request, response, retry,
|
|
123
|
+
and error. Sensitive headers (`Authorization`, `Cookie`, `Set-Cookie`,
|
|
124
|
+
`X-Api-Key`, `Proxy-Authorization`) are automatically redacted.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
const nxus = new NxusClient({
|
|
128
|
+
apiKey: "sk_live_...",
|
|
129
|
+
verbose: true, // logs to console
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Plug in your own logger (winston, pino, etc.) by providing any object that
|
|
134
|
+
implements `{ debug, info, warn, error }`:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import type { NxusLogger } from "nxus-qbd";
|
|
138
|
+
|
|
139
|
+
const logger: NxusLogger = {
|
|
140
|
+
debug: (m, c) => myLogger.debug({ event: m, ...c }),
|
|
141
|
+
info: (m, c) => myLogger.info({ event: m, ...c }),
|
|
142
|
+
warn: (m, c) => myLogger.warn({ event: m, ...c }),
|
|
143
|
+
error: (m, c) => myLogger.error({ event: m, ...c }),
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const nxus = new NxusClient({ apiKey: "sk_live_...", logger });
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Providing a `logger` implies `verbose: true`. You can also opt-in on a single
|
|
150
|
+
call via `{ verbose: true }` in request options.
|
|
151
|
+
|
|
152
|
+
## Proxy Support
|
|
153
|
+
|
|
154
|
+
Route traffic through an outbound HTTP/HTTPS proxy by passing `proxy`:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
const nxus = new NxusClient({
|
|
158
|
+
apiKey: "sk_live_...",
|
|
159
|
+
proxy: "http://proxy.corp:8080",
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
On Node, the SDK lazily loads `undici.ProxyAgent` (shipped with Node 18+) and
|
|
164
|
+
wires it via `fetchOptions.dispatcher`. On Bun, the URL is passed through as
|
|
165
|
+
the native `proxy` fetch option. For advanced cases — custom TLS, mTLS,
|
|
166
|
+
per-request dispatchers — use the `fetchOptions` escape hatch:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { ProxyAgent } from "undici";
|
|
170
|
+
|
|
171
|
+
const nxus = new NxusClient({
|
|
172
|
+
apiKey: "sk_live_...",
|
|
173
|
+
fetchOptions: {
|
|
174
|
+
dispatcher: new ProxyAgent({
|
|
175
|
+
uri: "http://proxy.corp:8080",
|
|
176
|
+
token: `Basic ${Buffer.from("user:pass").toString("base64")}`,
|
|
177
|
+
}),
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`fetchOptions` may also be supplied per request to override the client default.
|
|
183
|
+
|
|
184
|
+
## Raw HTTP Access
|
|
185
|
+
|
|
186
|
+
When you need direct access to the underlying `Response` — headers, streaming
|
|
187
|
+
bodies, custom status handling — use `transport.raw()`. Authentication, default
|
|
188
|
+
headers, the timeout, and retries are still applied; only JSON parsing and the
|
|
189
|
+
typed error mapping are bypassed.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { NxusClient } from "nxus-qbd";
|
|
193
|
+
|
|
194
|
+
const nxus = new NxusClient({ apiKey: "sk_live_..." });
|
|
195
|
+
|
|
196
|
+
const res = await (nxus as unknown as { transport: { raw: (path: string, init?: RequestInit) => Promise<Response> } })
|
|
197
|
+
.transport.raw("/api/v1/vendors", { method: "GET" });
|
|
198
|
+
|
|
199
|
+
console.log(res.status, res.headers.get("x-request-id"));
|
|
200
|
+
const stream = res.body; // ReadableStream for large downloads
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Non-2xx responses are returned, not thrown — the caller is responsible for
|
|
204
|
+
checking `response.ok`. Use this only for cases the typed resource methods
|
|
205
|
+
can't model (binary downloads, response-header inspection, custom error
|
|
206
|
+
semantics).
|
|
207
|
+
|
|
208
|
+
## Quick Start
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { NxusClient } from "nxus-qbd";
|
|
212
|
+
|
|
213
|
+
const nxus = new NxusClient({ apiKey: "sk_live_..." });
|
|
214
|
+
|
|
215
|
+
// List vendors
|
|
216
|
+
const page = await nxus.vendors.list({ limit: 50, connectionId: "your-connection-id" });
|
|
217
|
+
|
|
218
|
+
for (const vendor of page.data) {
|
|
219
|
+
console.log(vendor.name);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Retrieve a single customer by QuickBooks ListID
|
|
223
|
+
const customer = await nxus.customers.retrieve("80000001-1234567890", {
|
|
224
|
+
connectionId: "your-connection-id",
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Create an invoice (flat params)
|
|
228
|
+
const invoice = await nxus.invoices.create({
|
|
229
|
+
customerRefListId: "80000001-1234567890",
|
|
230
|
+
invoiceLineAdds: [
|
|
231
|
+
{ itemRefListId: "80000002-1234567890", amount: 150.0 },
|
|
232
|
+
],
|
|
233
|
+
connectionId: "your-connection-id",
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Update a vendor (ID first, flat fields)
|
|
237
|
+
const updated = await nxus.vendors.update("80000001-1234567890", {
|
|
238
|
+
name: "Acme (Updated)",
|
|
239
|
+
revisionNumber: vendor.revisionNumber,
|
|
240
|
+
connectionId: "your-connection-id",
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// Delete
|
|
244
|
+
await nxus.vendors.delete("80000001-1234567890", {
|
|
245
|
+
connectionId: "your-connection-id",
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Connection Scoping
|
|
250
|
+
|
|
251
|
+
Every request requires a `connectionId` to identify which QuickBooks Desktop company file to target. You can set it per-request or globally via the constructor:
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
// Per-request
|
|
255
|
+
const page = await nxus.vendors.list({ limit: 10, connectionId: "your-connection-id" });
|
|
256
|
+
const vendor = await nxus.vendors.retrieve("id", { connectionId: "your-connection-id" });
|
|
257
|
+
|
|
258
|
+
// Global default
|
|
259
|
+
const nxus = new NxusClient({
|
|
260
|
+
apiKey: "sk_live_...",
|
|
261
|
+
headers: { "X-Connection-Id": "your-connection-id" },
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Auto-Pagination
|
|
266
|
+
|
|
267
|
+
List methods return an `AutoPaginationPromise` that supports both manual page navigation and `for await` iteration:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
// Auto-paginate through all records
|
|
271
|
+
for await (const vendor of nxus.vendors.list({ limit: 100, timeoutSeconds: 45 })) {
|
|
272
|
+
console.log(vendor.name);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Manual page-by-page navigation
|
|
276
|
+
let page = await nxus.vendors.list({ limit: 50, timeoutSeconds: 45 });
|
|
277
|
+
while (page.hasNextPage()) {
|
|
278
|
+
page = await page.getNextPage();
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
> [!IMPORTANT]
|
|
283
|
+
> **Processing Constraints**: Each paginated request must either complete or be cancelled before the subsequent request can be processed by the backend.
|
|
284
|
+
>
|
|
285
|
+
> - **Async API (Primary)**: The Async API is the recommended way to handle these requests as it allows for better lifecycle management.
|
|
286
|
+
> - **Sync Wrappers**: While sync wrappers are provided for convenience, you may need to increase your client-side timeouts to ensure large paginated sets complete successfully.
|
|
287
|
+
|
|
288
|
+
## Examples
|
|
289
|
+
|
|
290
|
+
Runnable examples live in [`examples/`](examples/):
|
|
291
|
+
|
|
292
|
+
| Example | Description |
|
|
293
|
+
|---|---|
|
|
294
|
+
| [`basic-crud.ts`](examples/basic-crud.ts) | Create, retrieve, update, list, and delete a vendor |
|
|
295
|
+
| [`authSetup.ts`](examples/authSetup.ts) | Create a connection, generate a hosted QWC auth flow URL, and check auth status |
|
|
296
|
+
| [`auto-pagination.ts`](examples/auto-pagination.ts) | Auto-iteration across pages plus manual page navigation |
|
|
297
|
+
| [`connection-scoped.ts`](examples/connection-scoped.ts) | Multi-company isolation with `connectionId` |
|
|
298
|
+
| [`error-handling.ts`](examples/error-handling.ts) | Error categorization and typed SDK errors |
|
|
299
|
+
| [`pagination-walkthrough.ts`](examples/pagination-walkthrough.ts) | Cursor handling walkthrough |
|
|
300
|
+
| [`reports.ts`](examples/reports.ts) | Aging, general detail, and general summary reports |
|
|
301
|
+
| [`timeout-tuning.ts`](examples/timeout-tuning.ts) | Default timeout behavior, client-wide overrides, and per-request timeout tuning |
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
## Error Handling
|
|
305
|
+
|
|
306
|
+
All methods throw `NxusApiError` on non-2xx responses:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { NxusClient, NxusApiError } from "nxus-qbd";
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
await nxus.vendors.retrieve("non-existent-id");
|
|
313
|
+
} catch (err) {
|
|
314
|
+
if (err instanceof NxusApiError) {
|
|
315
|
+
console.log(err.status); // 404
|
|
316
|
+
console.log(err.userMessage); // User-safe message
|
|
317
|
+
console.log(err.isNotFound); // true
|
|
318
|
+
console.log(err.isAuthError); // false
|
|
319
|
+
console.log(err.isRateLimited); // false
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Resources
|
|
325
|
+
|
|
326
|
+
All QuickBooks Desktop resources are available as namespaced properties:
|
|
327
|
+
|
|
328
|
+
| Category | Resources |
|
|
329
|
+
|---|---|
|
|
330
|
+
| **Transactions** | `invoices`, `bills`, `checks`, `deposits`, `estimates`, `creditMemos`, `purchaseOrders`, `salesReceipts`, `journalEntries`, `receivePayments`, `vendorCredits`, `creditCardCharges`, `creditCardBills`, `creditCardCredits`, `charges`, `buildAssemblies`, `arRefundCreditCards`, `salesTaxPaymentChecks`, `itemReceipts`, `checkBills`, `timeTrackings`, `transactions` |
|
|
331
|
+
| **Lists** | `accounts`, `customers`, `vendors`, `employees`, `otherNames`, `currencies`, `terms`, `dateDrivenTerms`, `paymentMethods`, `shipMethods`, `salesTaxCodes`, `priceLevels`, `qbdClasses`, `customerTypes`, `vendorTypes`, `billingRates`, `inventorySites`, `barCodes`, `accountTaxLineInfos`, `unitOfMeasureSets`, `specialItems` |
|
|
332
|
+
| **Read-only** | `billToPay` |
|
|
333
|
+
| **Items** | `items`, `inventoryItems`, `itemDiscounts`, `itemFixedAssets`, `itemGroups`, `itemInventoryAssemblies`, `itemNonInventory`, `itemOtherCharges`, `itemPayments`, `itemSalesTax`, `itemSalesTaxGroups`, `serviceItems`, `itemSubtotals` |
|
|
334
|
+
| **Payroll** | `payrollItemNonWages`, `payrollItemWages`, `workersCompCodes` |
|
|
335
|
+
| **Reports** | `reports.retrieveAging()`, `reports.retrieveGeneralDetail()`, `reports.retrieveGeneralSummary()`, `reports.retrieveBudgetSummary()`, `reports.retrieveJob()`, `reports.retrieveTime()`, `reports.retrieveCustomDetail()`, `reports.retrieveCustomSummary()`, `reports.retrievePayrollDetail()` |
|
|
336
|
+
| **Platform** | `authSessions`, `connections` |
|
|
337
|
+
|
|
338
|
+
## License
|
|
339
|
+
|
|
340
|
+
MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* await nxus.vendors.delete('80000001-1234567890', { connectionId: '...' });
|
|
21
21
|
* ```
|
|
22
22
|
*/
|
|
23
|
+
import { type NxusLogger } from "./transport";
|
|
23
24
|
import type { RequestOptions } from "./transport";
|
|
24
25
|
import { type NxusEnvironment } from "./config";
|
|
25
26
|
import { Resource, ReadOnlyResource, ListDeleteResource, ListRetrieveDeleteResource, ListRetrieveCreateResource, CrudNoUpdateResource, NoDeleteResource, CreateOnlyResource } from "./resources/base";
|
|
@@ -67,8 +68,32 @@ export interface NxusClientOptions {
|
|
|
67
68
|
* `maxRetries` on the request options.
|
|
68
69
|
*/
|
|
69
70
|
maxRetries?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Emit debug logs for every request, response, retry, and error. Sensitive
|
|
73
|
+
* headers (Authorization, cookies, x-api-key) are redacted in the logs.
|
|
74
|
+
* Defaults to `false`. Providing `logger` implies `verbose: true`.
|
|
75
|
+
*/
|
|
76
|
+
verbose?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Custom structured logger. Plug in winston, pino, or any object that
|
|
79
|
+
* implements `{ debug, info, warn, error }`. When omitted and `verbose` is
|
|
80
|
+
* `true`, the SDK logs to `console`.
|
|
81
|
+
*/
|
|
82
|
+
logger?: NxusLogger;
|
|
83
|
+
/**
|
|
84
|
+
* Outbound HTTP/HTTPS proxy URL (e.g. `"http://proxy.corp:8080"`). On Node,
|
|
85
|
+
* the SDK lazily loads `undici.ProxyAgent`. On Bun, the URL is passed
|
|
86
|
+
* through as the native `proxy` fetch option. No-op in browsers and Deno.
|
|
87
|
+
*/
|
|
88
|
+
proxy?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Extra options merged into every `fetch()` call. Escape hatch for
|
|
91
|
+
* runtime-specific features (e.g. custom `dispatcher` on Node/undici, `tls`
|
|
92
|
+
* on Bun).
|
|
93
|
+
*/
|
|
94
|
+
fetchOptions?: Record<string, unknown>;
|
|
70
95
|
}
|
|
71
|
-
export type { RequestOptions };
|
|
96
|
+
export type { RequestOptions, NxusLogger };
|
|
72
97
|
export declare class NxusClient {
|
|
73
98
|
private readonly transport;
|
|
74
99
|
/**
|