nxus-qbd 0.7.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +269 -91
- package/dist/client.d.ts +81 -77
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +77 -71
- package/dist/client.js.map +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/generated/count-capabilities.d.ts +64 -0
- package/dist/generated/count-capabilities.d.ts.map +1 -0
- package/dist/generated/count-capabilities.js +64 -0
- package/dist/generated/count-capabilities.js.map +1 -0
- package/dist/generated/index.d.ts +1 -1
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/resource-capabilities.d.ts +506 -0
- package/dist/generated/resource-capabilities.d.ts.map +1 -0
- package/dist/generated/resource-capabilities.js +506 -0
- package/dist/generated/resource-capabilities.js.map +1 -0
- package/dist/generated/types.gen.d.ts +29531 -20897
- package/dist/generated/types.gen.d.ts.map +1 -1
- package/dist/generated/types.gen.js +80 -0
- package/dist/generated/types.gen.js.map +1 -1
- package/dist/helpers/enums.d.ts +29 -0
- package/dist/helpers/enums.d.ts.map +1 -0
- package/dist/helpers/enums.js +38 -0
- package/dist/helpers/enums.js.map +1 -0
- package/dist/helpers/errors.d.ts +14 -3
- package/dist/helpers/errors.d.ts.map +1 -1
- package/dist/helpers/errors.js +274 -23
- package/dist/helpers/errors.js.map +1 -1
- package/dist/helpers/index.d.ts +4 -2
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +4 -2
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/pagination.d.ts +11 -1
- package/dist/helpers/pagination.d.ts.map +1 -1
- package/dist/helpers/pagination.js.map +1 -1
- package/dist/helpers/response.d.ts +93 -0
- package/dist/helpers/response.d.ts.map +1 -0
- package/dist/helpers/response.js +84 -0
- package/dist/helpers/response.js.map +1 -0
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -8
- package/dist/index.js.map +1 -1
- package/dist/models/core/auth_session.d.ts +1 -1
- package/dist/models/core/auth_session.d.ts.map +1 -1
- package/dist/models/core/connections.d.ts +1 -1
- package/dist/models/core/connections.d.ts.map +1 -1
- package/dist/models/core/index.d.ts +3 -3
- package/dist/models/core/index.d.ts.map +1 -1
- package/dist/models/core/index.js +3 -3
- package/dist/models/core/index.js.map +1 -1
- package/dist/models/core/qwc_auth_setup.d.ts +1 -1
- package/dist/models/core/qwc_auth_setup.d.ts.map +1 -1
- package/dist/models/index.d.ts +6 -6
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +5 -5
- package/dist/models/index.js.map +1 -1
- package/dist/models/qbd/account.d.ts +2 -2
- package/dist/models/qbd/account.d.ts.map +1 -1
- package/dist/models/qbd/account.js +1 -1
- package/dist/models/qbd/account.js.map +1 -1
- package/dist/models/qbd/account_tax_line_info.d.ts +1 -1
- package/dist/models/qbd/account_tax_line_info.d.ts.map +1 -1
- package/dist/models/qbd/ar_refund_credit_card.d.ts +1 -1
- package/dist/models/qbd/ar_refund_credit_card.d.ts.map +1 -1
- package/dist/models/qbd/bar_code.d.ts +1 -1
- package/dist/models/qbd/bar_code.d.ts.map +1 -1
- package/dist/models/qbd/bill.d.ts +1 -1
- package/dist/models/qbd/bill.d.ts.map +1 -1
- package/dist/models/qbd/bill_payment_or_credit.d.ts +1 -1
- package/dist/models/qbd/bill_payment_or_credit.d.ts.map +1 -1
- package/dist/models/qbd/billing_rate.d.ts +1 -1
- package/dist/models/qbd/billing_rate.d.ts.map +1 -1
- package/dist/models/qbd/build_assembly.d.ts +1 -1
- package/dist/models/qbd/build_assembly.d.ts.map +1 -1
- package/dist/models/qbd/charge.d.ts +1 -1
- package/dist/models/qbd/charge.d.ts.map +1 -1
- package/dist/models/qbd/check.d.ts +1 -1
- package/dist/models/qbd/check.d.ts.map +1 -1
- package/dist/models/qbd/check_bill_payment.d.ts +1 -1
- package/dist/models/qbd/check_bill_payment.d.ts.map +1 -1
- package/dist/models/qbd/class_.d.ts +1 -1
- package/dist/models/qbd/class_.d.ts.map +1 -1
- package/dist/models/qbd/credit_card_bill_payment.d.ts +1 -1
- package/dist/models/qbd/credit_card_bill_payment.d.ts.map +1 -1
- package/dist/models/qbd/credit_card_charge.d.ts +1 -1
- package/dist/models/qbd/credit_card_charge.d.ts.map +1 -1
- package/dist/models/qbd/credit_card_credit.d.ts +1 -1
- package/dist/models/qbd/credit_card_credit.d.ts.map +1 -1
- package/dist/models/qbd/credit_memo.d.ts +1 -1
- package/dist/models/qbd/credit_memo.d.ts.map +1 -1
- package/dist/models/qbd/currency.d.ts +2 -1
- package/dist/models/qbd/currency.d.ts.map +1 -1
- package/dist/models/qbd/currency.js +2 -1
- package/dist/models/qbd/currency.js.map +1 -1
- package/dist/models/qbd/custom_field_definitions.d.ts +1 -1
- package/dist/models/qbd/custom_field_definitions.d.ts.map +1 -1
- package/dist/models/qbd/custom_fields.d.ts +2 -2
- package/dist/models/qbd/custom_fields.d.ts.map +1 -1
- package/dist/models/qbd/custom_fields.js +1 -1
- package/dist/models/qbd/custom_fields.js.map +1 -1
- package/dist/models/qbd/customer.d.ts +2 -2
- package/dist/models/qbd/customer.d.ts.map +1 -1
- package/dist/models/qbd/customer.js +1 -1
- package/dist/models/qbd/customer.js.map +1 -1
- package/dist/models/qbd/customer_type.d.ts +1 -1
- package/dist/models/qbd/customer_type.d.ts.map +1 -1
- package/dist/models/qbd/date_driven_term.d.ts +1 -1
- package/dist/models/qbd/date_driven_term.d.ts.map +1 -1
- package/dist/models/qbd/deposit.d.ts +1 -1
- package/dist/models/qbd/deposit.d.ts.map +1 -1
- package/dist/models/qbd/employee.d.ts +2 -2
- package/dist/models/qbd/employee.d.ts.map +1 -1
- package/dist/models/qbd/employee.js +1 -1
- package/dist/models/qbd/employee.js.map +1 -1
- package/dist/models/qbd/estimate.d.ts +1 -1
- package/dist/models/qbd/estimate.d.ts.map +1 -1
- package/dist/models/qbd/index.d.ts +66 -66
- package/dist/models/qbd/index.d.ts.map +1 -1
- package/dist/models/qbd/index.js +66 -66
- package/dist/models/qbd/index.js.map +1 -1
- package/dist/models/qbd/inventory_adjustment.d.ts +1 -1
- package/dist/models/qbd/inventory_adjustment.d.ts.map +1 -1
- package/dist/models/qbd/inventory_site.d.ts +1 -1
- package/dist/models/qbd/inventory_site.d.ts.map +1 -1
- package/dist/models/qbd/invoice.d.ts +2 -1
- package/dist/models/qbd/invoice.d.ts.map +1 -1
- package/dist/models/qbd/invoice.js +2 -1
- package/dist/models/qbd/invoice.js.map +1 -1
- package/dist/models/qbd/item.d.ts +2 -2
- package/dist/models/qbd/item.d.ts.map +1 -1
- package/dist/models/qbd/item.js +1 -1
- package/dist/models/qbd/item.js.map +1 -1
- package/dist/models/qbd/item_discount.d.ts +1 -1
- package/dist/models/qbd/item_discount.d.ts.map +1 -1
- package/dist/models/qbd/item_fixed_asset.d.ts +1 -1
- package/dist/models/qbd/item_fixed_asset.d.ts.map +1 -1
- package/dist/models/qbd/item_group.d.ts +1 -1
- package/dist/models/qbd/item_group.d.ts.map +1 -1
- package/dist/models/qbd/item_inventory.d.ts +1 -1
- package/dist/models/qbd/item_inventory.d.ts.map +1 -1
- package/dist/models/qbd/item_inventory_assembly.d.ts +1 -1
- package/dist/models/qbd/item_inventory_assembly.d.ts.map +1 -1
- package/dist/models/qbd/item_non_inventory.d.ts +1 -1
- package/dist/models/qbd/item_non_inventory.d.ts.map +1 -1
- package/dist/models/qbd/item_other_charge.d.ts +1 -1
- package/dist/models/qbd/item_other_charge.d.ts.map +1 -1
- package/dist/models/qbd/item_payment.d.ts +1 -1
- package/dist/models/qbd/item_payment.d.ts.map +1 -1
- package/dist/models/qbd/item_receipt.d.ts +1 -1
- package/dist/models/qbd/item_receipt.d.ts.map +1 -1
- package/dist/models/qbd/item_sales_tax.d.ts +1 -1
- package/dist/models/qbd/item_sales_tax.d.ts.map +1 -1
- package/dist/models/qbd/item_sales_tax_group.d.ts +1 -1
- package/dist/models/qbd/item_sales_tax_group.d.ts.map +1 -1
- package/dist/models/qbd/item_service.d.ts +1 -1
- package/dist/models/qbd/item_service.d.ts.map +1 -1
- package/dist/models/qbd/item_subtotal.d.ts +1 -1
- package/dist/models/qbd/item_subtotal.d.ts.map +1 -1
- package/dist/models/qbd/journal_entry.d.ts +1 -1
- package/dist/models/qbd/journal_entry.d.ts.map +1 -1
- package/dist/models/qbd/other_name.d.ts +1 -1
- package/dist/models/qbd/other_name.d.ts.map +1 -1
- package/dist/models/qbd/payment_method.d.ts +1 -1
- package/dist/models/qbd/payment_method.d.ts.map +1 -1
- package/dist/models/qbd/payroll_item_non_wage.d.ts +1 -1
- package/dist/models/qbd/payroll_item_non_wage.d.ts.map +1 -1
- package/dist/models/qbd/payroll_item_wage.d.ts +1 -1
- package/dist/models/qbd/payroll_item_wage.d.ts.map +1 -1
- package/dist/models/qbd/price_level.d.ts +1 -1
- package/dist/models/qbd/price_level.d.ts.map +1 -1
- package/dist/models/qbd/purchase_order.d.ts +1 -1
- package/dist/models/qbd/purchase_order.d.ts.map +1 -1
- package/dist/models/qbd/receive_payment.d.ts +1 -1
- package/dist/models/qbd/receive_payment.d.ts.map +1 -1
- package/dist/models/qbd/report.d.ts +1 -1
- package/dist/models/qbd/report.d.ts.map +1 -1
- package/dist/models/qbd/sales_order.d.ts +1 -1
- package/dist/models/qbd/sales_order.d.ts.map +1 -1
- package/dist/models/qbd/sales_receipt.d.ts +1 -1
- package/dist/models/qbd/sales_receipt.d.ts.map +1 -1
- package/dist/models/qbd/sales_tax_code.d.ts +1 -1
- package/dist/models/qbd/sales_tax_code.d.ts.map +1 -1
- package/dist/models/qbd/sales_tax_payment_check.d.ts +1 -1
- package/dist/models/qbd/sales_tax_payment_check.d.ts.map +1 -1
- package/dist/models/qbd/ship_method.d.ts +1 -1
- package/dist/models/qbd/ship_method.d.ts.map +1 -1
- package/dist/models/qbd/special_item.d.ts +1 -1
- package/dist/models/qbd/special_item.d.ts.map +1 -1
- package/dist/models/qbd/tenant_me.d.ts +1 -1
- package/dist/models/qbd/tenant_me.d.ts.map +1 -1
- package/dist/models/qbd/term.d.ts +1 -1
- package/dist/models/qbd/term.d.ts.map +1 -1
- package/dist/models/qbd/time_tracking_activity.d.ts +1 -1
- package/dist/models/qbd/time_tracking_activity.d.ts.map +1 -1
- package/dist/models/qbd/transaction.d.ts +1 -1
- package/dist/models/qbd/transaction.d.ts.map +1 -1
- package/dist/models/qbd/unit_of_measure_set.d.ts +1 -1
- package/dist/models/qbd/unit_of_measure_set.d.ts.map +1 -1
- package/dist/models/qbd/vendor.d.ts +1 -1
- package/dist/models/qbd/vendor.d.ts.map +1 -1
- package/dist/models/qbd/vendor_credit.d.ts +1 -1
- package/dist/models/qbd/vendor_credit.d.ts.map +1 -1
- package/dist/models/qbd/vendor_type.d.ts +1 -1
- package/dist/models/qbd/vendor_type.d.ts.map +1 -1
- package/dist/models/qbd/workers_comp_code.d.ts +1 -1
- package/dist/models/qbd/workers_comp_code.d.ts.map +1 -1
- package/dist/resources/base.d.ts +159 -29
- package/dist/resources/base.d.ts.map +1 -1
- package/dist/resources/base.js +417 -151
- package/dist/resources/base.js.map +1 -1
- package/dist/resources/connections.d.ts +17 -4
- package/dist/resources/connections.d.ts.map +1 -1
- package/dist/resources/connections.js +39 -13
- package/dist/resources/connections.js.map +1 -1
- package/dist/resources/custom-fields.d.ts +35 -32
- package/dist/resources/custom-fields.d.ts.map +1 -1
- package/dist/resources/custom-fields.js +121 -119
- package/dist/resources/custom-fields.js.map +1 -1
- package/dist/resources/reports.d.ts +23 -10
- package/dist/resources/reports.d.ts.map +1 -1
- package/dist/resources/reports.js +40 -29
- package/dist/resources/reports.js.map +1 -1
- package/dist/transport.d.ts +61 -10
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +522 -113
- package/dist/transport.js.map +1 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# nxus-qbd
|
|
1
|
+
# nxus-qbd v1.0.0
|
|
2
2
|
|
|
3
3
|
Official TypeScript SDK for the [Nxus](https://nx-us.net/docs/) QuickBooks Desktop API.
|
|
4
4
|
|
|
@@ -45,25 +45,33 @@ const nxus = new NxusClient({
|
|
|
45
45
|
timeout: 120_000,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
const page = await nxus.transactions.list(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
const page = await nxus.transactions.list(
|
|
49
|
+
{
|
|
50
|
+
limit: 100,
|
|
51
|
+
DetailLevel: "all",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
connectionId: "your-connection-id",
|
|
55
|
+
timeout: 30_000,
|
|
56
|
+
},
|
|
57
|
+
);
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
Paginated/list requests can also send a backend timeout hint without changing
|
|
57
61
|
the SDK's local abort timer:
|
|
58
62
|
|
|
59
63
|
```ts
|
|
60
|
-
const page = await nxus.transactions.list(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
const page = await nxus.transactions.list(
|
|
65
|
+
{
|
|
66
|
+
limit: 100,
|
|
67
|
+
DetailLevel: "all",
|
|
68
|
+
timeoutSeconds: 45,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
connectionId: "your-connection-id",
|
|
72
|
+
timeout: 30_000,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
67
75
|
```
|
|
68
76
|
|
|
69
77
|
When `timeoutSeconds` is provided on a `.list()` call, the SDK sends it as the
|
|
@@ -98,7 +106,28 @@ back in.
|
|
|
98
106
|
For backoff, the standard `Retry-After` response header (seconds or HTTP-date)
|
|
99
107
|
is honored when present, with `error.retryAfter` (seconds) in the JSON body
|
|
100
108
|
as a fallback. Local timeouts (the SDK's abort timer) are treated as
|
|
101
|
-
cancellations and
|
|
109
|
+
cancellations for reads, updates, deletes, and other non-idempotent calls.
|
|
110
|
+
Generic Creates are the exception: their idempotency key makes timeout retries
|
|
111
|
+
safe, so they reuse the same key on the next attempt.
|
|
112
|
+
|
|
113
|
+
## Safe Create Retries
|
|
114
|
+
|
|
115
|
+
Every generic resource `.create()` call automatically sends a cryptographically
|
|
116
|
+
random `Idempotency-Key`. The SDK generates it once before retries begin and
|
|
117
|
+
uses the same key for every attempt, including `.withResponse.create()`.
|
|
118
|
+
|
|
119
|
+
For a workflow that can resume after the current process exits, supply and
|
|
120
|
+
persist your own key:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
await nxus.bills.create(request, {
|
|
124
|
+
idempotencyKey: `billing-import-${importJobId}`,
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The key is sent only as the `Idempotency-Key` HTTP header, never in the JSON
|
|
129
|
+
body. QuickBooks recovery identifiers and recovery status remain server-owned;
|
|
130
|
+
on a timeout, retry the same logical Create key and follow `x-should-retry`.
|
|
102
131
|
|
|
103
132
|
Configure globally or per-request:
|
|
104
133
|
|
|
@@ -109,12 +138,16 @@ const nxus = new NxusClient({
|
|
|
109
138
|
});
|
|
110
139
|
|
|
111
140
|
// Disable retries for one call
|
|
112
|
-
const created = await nxus.invoices.create(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
141
|
+
const created = await nxus.invoices.create(
|
|
142
|
+
{
|
|
143
|
+
customerRefListId: "...",
|
|
144
|
+
invoiceLineAdds: [{ itemRefListId: "...", amount: 100 }],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
connectionId: "...",
|
|
148
|
+
maxRetries: 0,
|
|
149
|
+
},
|
|
150
|
+
);
|
|
118
151
|
```
|
|
119
152
|
|
|
120
153
|
## Verbose Logging
|
|
@@ -126,7 +159,7 @@ and error. Sensitive headers (`Authorization`, `Cookie`, `Set-Cookie`,
|
|
|
126
159
|
```ts
|
|
127
160
|
const nxus = new NxusClient({
|
|
128
161
|
apiKey: "sk_live_...",
|
|
129
|
-
verbose: true,
|
|
162
|
+
verbose: true, // logs to console
|
|
130
163
|
});
|
|
131
164
|
```
|
|
132
165
|
|
|
@@ -138,8 +171,8 @@ import type { NxusLogger } from "nxus-qbd";
|
|
|
138
171
|
|
|
139
172
|
const logger: NxusLogger = {
|
|
140
173
|
debug: (m, c) => myLogger.debug({ event: m, ...c }),
|
|
141
|
-
info:
|
|
142
|
-
warn:
|
|
174
|
+
info: (m, c) => myLogger.info({ event: m, ...c }),
|
|
175
|
+
warn: (m, c) => myLogger.warn({ event: m, ...c }),
|
|
143
176
|
error: (m, c) => myLogger.error({ event: m, ...c }),
|
|
144
177
|
};
|
|
145
178
|
|
|
@@ -181,29 +214,50 @@ const nxus = new NxusClient({
|
|
|
181
214
|
|
|
182
215
|
`fetchOptions` may also be supplied per request to override the client default.
|
|
183
216
|
|
|
184
|
-
##
|
|
217
|
+
## Response Metadata
|
|
185
218
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
headers, the timeout, and retries are still applied; only JSON parsing and the
|
|
189
|
-
typed error mapping are bypassed.
|
|
219
|
+
Every resource method has a `withResponse` twin that returns the parsed model
|
|
220
|
+
_and_ the response metadata that came with it:
|
|
190
221
|
|
|
191
222
|
```ts
|
|
192
|
-
|
|
223
|
+
const check = await nxus.checks.create({ payeeId });
|
|
224
|
+
// -> Check
|
|
193
225
|
|
|
194
|
-
const
|
|
226
|
+
const wrapped = await nxus.checks.withResponse.create({ payeeId });
|
|
227
|
+
// -> NxusResponse<Check>
|
|
228
|
+
|
|
229
|
+
wrapped.data; // the same Check
|
|
230
|
+
wrapped.statusCode; // 200
|
|
231
|
+
wrapped.requestId; // 'req_abc123' — quote this in support requests
|
|
232
|
+
wrapped.headers; // frozen, lower-cased names
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Both forms are the same call. The plain method is a wrapper that discards the
|
|
236
|
+
metadata, so parsing, retries and error translation are identical — only the
|
|
237
|
+
return value differs. Errors throw `NxusApiError` in both.
|
|
195
238
|
|
|
196
|
-
|
|
197
|
-
.transport.raw("/api/v1/vendors", { method: "GET" });
|
|
239
|
+
`NxusResponse` is frozen, as is its `headers` object.
|
|
198
240
|
|
|
199
|
-
|
|
200
|
-
|
|
241
|
+
The undecoded body is not retained unless you ask for it, since keeping it for
|
|
242
|
+
every call would hold a second full copy of every payload alive:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
const wrapped = await nxus.vendors.withResponse.retrieve(id, {
|
|
246
|
+
includeRawBody: true,
|
|
247
|
+
});
|
|
248
|
+
wrapped.rawBody; // the exact text the server sent
|
|
201
249
|
```
|
|
202
250
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
251
|
+
The SDK never hands back a `fetch` `Response`. A `Response` body can only be
|
|
252
|
+
read once, so exposing one would mean handing consumers an object that is
|
|
253
|
+
already consumed — and would put the runtime's stream semantics into this
|
|
254
|
+
SDK's contract. Everything useful is copied out while the response is still
|
|
255
|
+
readable, so a `NxusResponse` is safe to keep, log, or pass around.
|
|
256
|
+
|
|
257
|
+
`withResponse.list` returns the **first page** only and does not auto-paginate:
|
|
258
|
+
later pages are separate requests with their own status and headers, which one
|
|
259
|
+
wrapper could not honestly describe. Use `wrapped.data.hasMore` and
|
|
260
|
+
`wrapped.data.cursor` to continue, or the plain `list` for the async iterator.
|
|
207
261
|
|
|
208
262
|
## Quick Start
|
|
209
263
|
|
|
@@ -213,7 +267,10 @@ import { NxusClient } from "nxus-qbd";
|
|
|
213
267
|
const nxus = new NxusClient({ apiKey: "sk_live_..." });
|
|
214
268
|
|
|
215
269
|
// List vendors
|
|
216
|
-
const page = await nxus.vendors.list(
|
|
270
|
+
const page = await nxus.vendors.list(
|
|
271
|
+
{ limit: 50 },
|
|
272
|
+
{ connectionId: "your-connection-id" },
|
|
273
|
+
);
|
|
217
274
|
|
|
218
275
|
for (const vendor of page.data) {
|
|
219
276
|
console.log(vendor.name);
|
|
@@ -224,21 +281,28 @@ const customer = await nxus.customers.retrieve("80000001-1234567890", {
|
|
|
224
281
|
connectionId: "your-connection-id",
|
|
225
282
|
});
|
|
226
283
|
|
|
227
|
-
// Create an invoice (
|
|
228
|
-
const invoice = await nxus.invoices.create(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
{ itemRefListId: "80000002-1234567890", amount: 150.0 },
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
284
|
+
// Create an invoice (payload first, transport options second)
|
|
285
|
+
const invoice = await nxus.invoices.create(
|
|
286
|
+
{
|
|
287
|
+
customerRefListId: "80000001-1234567890",
|
|
288
|
+
invoiceLineAdds: [{ itemRefListId: "80000002-1234567890", amount: 150.0 }],
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
connectionId: "your-connection-id",
|
|
292
|
+
},
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
// Update a vendor (ID first, payload second, transport options third)
|
|
296
|
+
const updated = await nxus.vendors.update(
|
|
297
|
+
"80000001-1234567890",
|
|
298
|
+
{
|
|
299
|
+
name: "Acme (Updated)",
|
|
300
|
+
revisionNumber: vendor.revisionNumber,
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
connectionId: "your-connection-id",
|
|
304
|
+
},
|
|
305
|
+
);
|
|
242
306
|
|
|
243
307
|
// Delete
|
|
244
308
|
await nxus.vendors.delete("80000001-1234567890", {
|
|
@@ -252,14 +316,113 @@ Every request requires a `connectionId` to identify which QuickBooks Desktop com
|
|
|
252
316
|
|
|
253
317
|
```ts
|
|
254
318
|
// Per-request
|
|
255
|
-
const page = await nxus.vendors.list(
|
|
256
|
-
|
|
319
|
+
const page = await nxus.vendors.list(
|
|
320
|
+
{ limit: 10 },
|
|
321
|
+
{ connectionId: "your-connection-id" },
|
|
322
|
+
);
|
|
323
|
+
const vendor = await nxus.vendors.retrieve("id", {
|
|
324
|
+
connectionId: "your-connection-id",
|
|
325
|
+
});
|
|
257
326
|
|
|
258
327
|
// Global default
|
|
259
328
|
const nxus = new NxusClient({
|
|
260
329
|
apiKey: "sk_live_...",
|
|
261
|
-
|
|
330
|
+
connectionId: "your-connection-id",
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Request Options
|
|
335
|
+
|
|
336
|
+
Resource methods that accept a request body or query now prefer a split call shape:
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
await nxus.vendors.create(
|
|
340
|
+
{ name: "Acme" },
|
|
341
|
+
{ connectionId: "your-connection-id", timeout: 30_000 },
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
await nxus.vendors.list(
|
|
345
|
+
{ limit: 50, timeoutSeconds: 45 },
|
|
346
|
+
{ connectionId: "your-connection-id" },
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
await nxus.reports.retrieveAging(
|
|
350
|
+
{ reportType: "summary" },
|
|
351
|
+
{ connectionId: "your-connection-id" },
|
|
352
|
+
);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
This keeps transport options out of serialized request bodies and query strings.
|
|
356
|
+
|
|
357
|
+
`authSessions.create()` is the main special case because `connectionId` is a real
|
|
358
|
+
payload field on that endpoint. When you need both the auth-session payload
|
|
359
|
+
connection and a transport-level connection header, pass them separately:
|
|
360
|
+
|
|
361
|
+
```ts
|
|
362
|
+
await nxus.authSessions.create(
|
|
363
|
+
{
|
|
364
|
+
connectionId: "payload-connection-id",
|
|
365
|
+
redirectUrl: "https://example.com/after-qwc",
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
connectionId: "transport-connection-id",
|
|
369
|
+
},
|
|
370
|
+
);
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Filtering By Active Status
|
|
374
|
+
|
|
375
|
+
QuickBooks returns only active records unless a list request says otherwise.
|
|
376
|
+
`activeStatus` is typed, so the value comes from `QbdActiveStatus` rather than
|
|
377
|
+
a hand-written string:
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
import { NxusClient, QbdActiveStatus } from "nxus-qbd";
|
|
381
|
+
|
|
382
|
+
// Active and inactive records
|
|
383
|
+
const all = await nxus.vendors.list({
|
|
384
|
+
limit: 50,
|
|
385
|
+
activeStatus: QbdActiveStatus.ALL,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// Only the records QuickBooks has marked inactive
|
|
389
|
+
const inactive = await nxus.vendors.list({
|
|
390
|
+
limit: 50,
|
|
391
|
+
activeStatus: QbdActiveStatus.INACTIVE_ONLY,
|
|
262
392
|
});
|
|
393
|
+
|
|
394
|
+
// Omit it entirely for QuickBooks' ActiveOnly default
|
|
395
|
+
const active = await nxus.vendors.list({ limit: 50 });
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
The wire values are `ActiveOnly`, `InactiveOnly` and `All`, and QuickBooks
|
|
399
|
+
matches them exactly. A near miss such as `"all"` is not rejected as a bad
|
|
400
|
+
request — it travels all the way into qbXML and comes back as QBD error 3110,
|
|
401
|
+
`The enumerated value "all" in the field "ActiveStatus" is unknown or invalid`.
|
|
402
|
+
That is what the enum is for.
|
|
403
|
+
|
|
404
|
+
The enum and its wire string are interchangeable, so both of these compile and
|
|
405
|
+
send the same request, while a typo does not compile at all:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
await nxus.vendors.list({ activeStatus: QbdActiveStatus.ALL });
|
|
409
|
+
await nxus.vendors.list({ activeStatus: "All" });
|
|
410
|
+
|
|
411
|
+
// @ts-expect-error — "all" is not one of the three literals
|
|
412
|
+
await nxus.vendors.list({ activeStatus: "all" });
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
A value the compiler only knows as `string` — an environment variable, a CLI
|
|
416
|
+
flag, a database column — cannot be checked that way. `toActiveStatus` closes
|
|
417
|
+
that gap by validating locally instead of letting QuickBooks fail the request:
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
import { toActiveStatus } from "nxus-qbd";
|
|
421
|
+
|
|
422
|
+
const activeStatus = toActiveStatus(process.env.NXUS_ACTIVE_STATUS ?? "All");
|
|
423
|
+
await nxus.vendors.list({ limit: 50, activeStatus });
|
|
424
|
+
|
|
425
|
+
// `isActiveStatus(value)` narrows without throwing.
|
|
263
426
|
```
|
|
264
427
|
|
|
265
428
|
## Auto-Pagination
|
|
@@ -268,7 +431,10 @@ List methods return an `AutoPaginationPromise` that supports both manual page na
|
|
|
268
431
|
|
|
269
432
|
```ts
|
|
270
433
|
// Auto-paginate through all records
|
|
271
|
-
for await (const vendor of nxus.vendors.list({
|
|
434
|
+
for await (const vendor of nxus.vendors.list({
|
|
435
|
+
limit: 100,
|
|
436
|
+
timeoutSeconds: 45,
|
|
437
|
+
})) {
|
|
272
438
|
console.log(vendor.name);
|
|
273
439
|
}
|
|
274
440
|
|
|
@@ -289,17 +455,16 @@ while (page.hasNextPage()) {
|
|
|
289
455
|
|
|
290
456
|
Runnable examples live in [`examples/`](examples/):
|
|
291
457
|
|
|
292
|
-
| Example
|
|
293
|
-
|
|
294
|
-
| [`basic-crud.ts`](examples/basic-crud.ts)
|
|
295
|
-
| [`authSetup.ts`](examples/authSetup.ts)
|
|
296
|
-
| [`auto-pagination.ts`](examples/auto-pagination.ts)
|
|
297
|
-
| [`connection-scoped.ts`](examples/connection-scoped.ts)
|
|
298
|
-
| [`error-handling.ts`](examples/error-handling.ts)
|
|
299
|
-
| [`pagination-walkthrough.ts`](examples/pagination-walkthrough.ts) | Cursor handling walkthrough
|
|
300
|
-
| [`reports.ts`](examples/reports.ts)
|
|
301
|
-
| [`timeout-tuning.ts`](examples/timeout-tuning.ts)
|
|
302
|
-
|
|
458
|
+
| Example | Description |
|
|
459
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
460
|
+
| [`basic-crud.ts`](examples/basic-crud.ts) | Create, retrieve, update, list, and delete a vendor |
|
|
461
|
+
| [`authSetup.ts`](examples/authSetup.ts) | Create a connection, generate a hosted QWC auth flow URL, and check auth status |
|
|
462
|
+
| [`auto-pagination.ts`](examples/auto-pagination.ts) | Auto-iteration across pages plus manual page navigation |
|
|
463
|
+
| [`connection-scoped.ts`](examples/connection-scoped.ts) | Multi-company isolation with `connectionId` |
|
|
464
|
+
| [`error-handling.ts`](examples/error-handling.ts) | Error categorization and typed SDK errors |
|
|
465
|
+
| [`pagination-walkthrough.ts`](examples/pagination-walkthrough.ts) | Cursor handling walkthrough |
|
|
466
|
+
| [`reports.ts`](examples/reports.ts) | Aging, general detail, and general summary reports |
|
|
467
|
+
| [`timeout-tuning.ts`](examples/timeout-tuning.ts) | Default timeout behavior, client-wide overrides, and per-request timeout tuning |
|
|
303
468
|
|
|
304
469
|
## Error Handling
|
|
305
470
|
|
|
@@ -312,40 +477,54 @@ try {
|
|
|
312
477
|
await nxus.vendors.retrieve("non-existent-id");
|
|
313
478
|
} catch (err) {
|
|
314
479
|
if (err instanceof NxusApiError) {
|
|
315
|
-
console.log(err.status);
|
|
316
|
-
console.log(err.userMessage);
|
|
317
|
-
console.log(err.
|
|
318
|
-
console.log(err.
|
|
319
|
-
console.log(err.
|
|
480
|
+
console.log(err.status); // 404
|
|
481
|
+
console.log(err.userMessage); // User-safe message
|
|
482
|
+
console.log(err.retryAfter); // Requested retry delay in seconds, if present
|
|
483
|
+
console.log(err.isNotFound); // true
|
|
484
|
+
console.log(err.isAuthError); // false
|
|
485
|
+
console.log(err.isRateLimited); // false
|
|
486
|
+
console.log(err.isRestrictionError); // lifecycle or billing restriction
|
|
487
|
+
console.log(err.isArchivedConnection); // lifecycleState === "archived"
|
|
488
|
+
console.log(err.isConnectorOffline); // QuickBooks Web Connector is not polling
|
|
320
489
|
}
|
|
321
490
|
}
|
|
322
491
|
```
|
|
323
492
|
|
|
493
|
+
Restriction responses also expose `lifecycleState`, `restrictionReason`,
|
|
494
|
+
`restrictionCode`, `requiresPayment`, and `checkoutUrl`. `throwIfError(value)`
|
|
495
|
+
converts an arbitrary generated-client error value into `NxusApiError`.
|
|
496
|
+
|
|
497
|
+
`isConnectorOffline` is worth handling on its own: it means the QuickBooks Web
|
|
498
|
+
Connector is not polling, so the API answered 503 without queuing anything and
|
|
499
|
+
retrying cannot succeed until someone starts the connector. Read `code` to tell
|
|
500
|
+
`QWC_NEVER_CONNECTED` (the `.qwc` file was never installed) from
|
|
501
|
+
`QWC_NOT_CONNECTED` (it authenticated once and has since stopped) — the two want
|
|
502
|
+
different operator instructions.
|
|
503
|
+
|
|
324
504
|
## Resources
|
|
325
505
|
|
|
326
506
|
All QuickBooks Desktop resources are available as namespaced properties:
|
|
327
507
|
|
|
328
|
-
| Category
|
|
329
|
-
|
|
508
|
+
| Category | Resources |
|
|
509
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
330
510
|
| **Transactions** | `invoices`, `bills`, `checks`, `deposits`, `estimates`, `creditMemos`, `purchaseOrders`, `salesReceipts`, `journalEntries`, `receivePayments`, `vendorCredits`, `creditCardCharges`, `creditCardBills`, `creditCardCredits`, `charges`, `buildAssemblies`, `arRefundCreditCards`, `salesTaxPaymentChecks`, `itemReceipts`, `CheckBillPayments`, `timeTrackings`, `transactions` |
|
|
331
|
-
| **Lists**
|
|
332
|
-
| **Read-only**
|
|
333
|
-
| **Items**
|
|
334
|
-
| **Payroll**
|
|
335
|
-
| **Reports**
|
|
336
|
-
| **Core**
|
|
337
|
-
|
|
511
|
+
| **Lists** | `accounts`, `customers`, `vendors`, `employees`, `otherNames`, `currencies`, `terms`, `dateDrivenTerms`, `paymentMethods`, `shipMethods`, `salesTaxCodes`, `priceLevels`, `qbdClasses`, `customerTypes`, `vendorTypes`, `billingRates`, `inventorySites`, `barCodes`, `accountTaxLineInfos`, `unitOfMeasureSets`, `specialItems` |
|
|
512
|
+
| **Read-only** | `billToPay` |
|
|
513
|
+
| **Items** | `items`, `inventoryItems`, `itemDiscounts`, `itemFixedAssets`, `itemGroups`, `itemInventoryAssemblies`, `itemNonInventory`, `itemOtherCharges`, `itemPayments`, `itemSalesTax`, `itemSalesTaxGroups`, `serviceItems`, `itemSubtotals` |
|
|
514
|
+
| **Payroll** | `payrollItemNonWages`, `payrollItemWages`, `workersCompCodes` |
|
|
515
|
+
| **Reports** | `reports.retrieveAging()`, `reports.retrieveGeneralDetail()`, `reports.retrieveGeneralSummary()`, `reports.retrieveBudgetSummary()`, `reports.retrieveJob()`, `reports.retrieveTime()`, `reports.retrieveCustomDetail()`, `reports.retrieveCustomSummary()`, `reports.retrievePayrollDetail()` |
|
|
516
|
+
| **Core** | `authSessions`, `connections` |
|
|
338
517
|
|
|
339
518
|
## Custom fields and data extensions
|
|
340
519
|
|
|
341
520
|
QuickBooks Desktop uses the same underlying mechanism for both UI-visible custom fields and application-only integration data:
|
|
342
521
|
|
|
343
|
-
| QuickBooks concept
|
|
344
|
-
|
|
345
|
-
| Data extension definition | `
|
|
346
|
-
| Data extension value
|
|
522
|
+
| QuickBooks concept | SDK/API name | Purpose |
|
|
523
|
+
| ------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
524
|
+
| Data extension definition | `DataExtDefinition` / custom field definition | Describes a field's owner, name, data type, and supported object types. |
|
|
525
|
+
| Data extension value | `DataExt` / custom field value | Stores the field's value on one specific QuickBooks list object, transaction, or transaction line. |
|
|
347
526
|
|
|
348
|
-
A definition must exist before a value can be written. Definitions are identified by `ownerId + name`; values add the specific QuickBooks target to that composite identity. QuickBooks may omit `DataExtID` for private definitions, so SDK consumers must allow `
|
|
527
|
+
A definition must exist before a value can be written. Definitions are identified by `ownerId + name`; values add the specific QuickBooks target to that composite identity. QuickBooks may omit `DataExtID` for private definitions, so SDK consumers must allow `DataExtDefinition.id` to be `null`.
|
|
349
528
|
|
|
350
529
|
The `ownerId` determines how a definition is used:
|
|
351
530
|
|
|
@@ -356,14 +535,13 @@ The `assignToObjects` property is therefore optional in the SDK request type, bu
|
|
|
356
535
|
|
|
357
536
|
The normal workflow is:
|
|
358
537
|
|
|
359
|
-
1. Create the `
|
|
538
|
+
1. Create the `DataExtDefinition`.
|
|
360
539
|
2. Create a `DataExt` value using the same `ownerId` and field name, plus a target such as a Customer `ListID`, an Invoice `TxnID`, or a transaction-line `TxnLineID`.
|
|
361
540
|
3. Update or delete the value using that same composite identity.
|
|
362
541
|
4. Delete a private definition only after its values are no longer needed. Public definitions must be managed in the QuickBooks UI because QuickBooks does not support deleting them through `DataExtDefDel`.
|
|
363
542
|
|
|
364
543
|
Public fields are typically used for information users should see or edit in QuickBooks. Private extensions are commonly used for external-system identifiers, synchronization or verification markers, workflow state, migration metadata, and other integration data that should not appear in the QuickBooks UI.
|
|
365
544
|
|
|
366
|
-
|
|
367
545
|
## License
|
|
368
546
|
|
|
369
547
|
MIT
|