@panoptic-it-solutions/quickbooks-client 0.1.1 → 0.1.3
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/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +44 -1
- package/dist/index.mjs +44 -1
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -257,6 +257,12 @@ declare class QuickBooksClient {
|
|
|
257
257
|
* Execute a query using QuickBooks Query Language
|
|
258
258
|
*/
|
|
259
259
|
query<T>(sql: string): Promise<T[]>;
|
|
260
|
+
/**
|
|
261
|
+
* Execute a query with automatic pagination to fetch all results
|
|
262
|
+
* @param sql - Base SQL query (without STARTPOSITION/MAXRESULTS)
|
|
263
|
+
* @param pageSize - Number of results per page (default 1000, max 1000)
|
|
264
|
+
*/
|
|
265
|
+
queryAll<T>(sql: string, pageSize?: number): Promise<T[]>;
|
|
260
266
|
getInvoice(id: string): Promise<Invoice>;
|
|
261
267
|
getInvoices(where?: string): Promise<Invoice[]>;
|
|
262
268
|
createInvoice(invoice: Partial<Invoice>): Promise<Invoice>;
|
package/dist/index.d.ts
CHANGED
|
@@ -257,6 +257,12 @@ declare class QuickBooksClient {
|
|
|
257
257
|
* Execute a query using QuickBooks Query Language
|
|
258
258
|
*/
|
|
259
259
|
query<T>(sql: string): Promise<T[]>;
|
|
260
|
+
/**
|
|
261
|
+
* Execute a query with automatic pagination to fetch all results
|
|
262
|
+
* @param sql - Base SQL query (without STARTPOSITION/MAXRESULTS)
|
|
263
|
+
* @param pageSize - Number of results per page (default 1000, max 1000)
|
|
264
|
+
*/
|
|
265
|
+
queryAll<T>(sql: string, pageSize?: number): Promise<T[]>;
|
|
260
266
|
getInvoice(id: string): Promise<Invoice>;
|
|
261
267
|
getInvoices(where?: string): Promise<Invoice[]>;
|
|
262
268
|
createInvoice(invoice: Partial<Invoice>): Promise<Invoice>;
|
package/dist/index.js
CHANGED
|
@@ -384,7 +384,6 @@ var QuickBooksClient = class {
|
|
|
384
384
|
* Execute a query using QuickBooks Query Language
|
|
385
385
|
*/
|
|
386
386
|
async query(sql) {
|
|
387
|
-
const response = await this.request("POST", "/query", void 0);
|
|
388
387
|
const tokens = await this.getValidTokens();
|
|
389
388
|
const env = this.config.environment || "production";
|
|
390
389
|
const baseUrl = API_BASE[env];
|
|
@@ -410,6 +409,50 @@ var QuickBooksClient = class {
|
|
|
410
409
|
const entityKey = keys[0];
|
|
411
410
|
return entityKey ? data.QueryResponse[entityKey] : [];
|
|
412
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Execute a query with automatic pagination to fetch all results
|
|
414
|
+
* @param sql - Base SQL query (without STARTPOSITION/MAXRESULTS)
|
|
415
|
+
* @param pageSize - Number of results per page (default 1000, max 1000)
|
|
416
|
+
*/
|
|
417
|
+
async queryAll(sql, pageSize = 1e3) {
|
|
418
|
+
const allResults = [];
|
|
419
|
+
let startPosition = 1;
|
|
420
|
+
const maxResults = Math.min(pageSize, 1e3);
|
|
421
|
+
while (true) {
|
|
422
|
+
const paginatedSql = `${sql} STARTPOSITION ${startPosition} MAXRESULTS ${maxResults}`;
|
|
423
|
+
const tokens = await this.getValidTokens();
|
|
424
|
+
const env = this.config.environment || "production";
|
|
425
|
+
const baseUrl = API_BASE[env];
|
|
426
|
+
const url = `${baseUrl}/v3/company/${tokens.realm_id}/query`;
|
|
427
|
+
await this.checkRateLimit();
|
|
428
|
+
const fetchResponse = await fetch(url, {
|
|
429
|
+
method: "POST",
|
|
430
|
+
headers: {
|
|
431
|
+
Authorization: `Bearer ${tokens.access_token}`,
|
|
432
|
+
Accept: "application/json",
|
|
433
|
+
"Content-Type": "application/text"
|
|
434
|
+
},
|
|
435
|
+
body: paginatedSql
|
|
436
|
+
});
|
|
437
|
+
if (!fetchResponse.ok) {
|
|
438
|
+
const errorData = await fetchResponse.json().catch(() => ({}));
|
|
439
|
+
throw handleQuickBooksError({ status: fetchResponse.status, ...errorData });
|
|
440
|
+
}
|
|
441
|
+
const data = await fetchResponse.json();
|
|
442
|
+
const keys = Object.keys(data.QueryResponse).filter(
|
|
443
|
+
(k) => !["startPosition", "maxResults", "totalCount"].includes(k)
|
|
444
|
+
);
|
|
445
|
+
const entityKey = keys[0];
|
|
446
|
+
const pageResults = entityKey ? data.QueryResponse[entityKey] : [];
|
|
447
|
+
allResults.push(...pageResults);
|
|
448
|
+
this.log("debug", `Fetched page at position ${startPosition}, got ${pageResults.length} results (total: ${allResults.length})`);
|
|
449
|
+
if (pageResults.length < maxResults) {
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
startPosition += maxResults;
|
|
453
|
+
}
|
|
454
|
+
return allResults;
|
|
455
|
+
}
|
|
413
456
|
// ============================================
|
|
414
457
|
// Invoice Methods
|
|
415
458
|
// ============================================
|
package/dist/index.mjs
CHANGED
|
@@ -348,7 +348,6 @@ var QuickBooksClient = class {
|
|
|
348
348
|
* Execute a query using QuickBooks Query Language
|
|
349
349
|
*/
|
|
350
350
|
async query(sql) {
|
|
351
|
-
const response = await this.request("POST", "/query", void 0);
|
|
352
351
|
const tokens = await this.getValidTokens();
|
|
353
352
|
const env = this.config.environment || "production";
|
|
354
353
|
const baseUrl = API_BASE[env];
|
|
@@ -374,6 +373,50 @@ var QuickBooksClient = class {
|
|
|
374
373
|
const entityKey = keys[0];
|
|
375
374
|
return entityKey ? data.QueryResponse[entityKey] : [];
|
|
376
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Execute a query with automatic pagination to fetch all results
|
|
378
|
+
* @param sql - Base SQL query (without STARTPOSITION/MAXRESULTS)
|
|
379
|
+
* @param pageSize - Number of results per page (default 1000, max 1000)
|
|
380
|
+
*/
|
|
381
|
+
async queryAll(sql, pageSize = 1e3) {
|
|
382
|
+
const allResults = [];
|
|
383
|
+
let startPosition = 1;
|
|
384
|
+
const maxResults = Math.min(pageSize, 1e3);
|
|
385
|
+
while (true) {
|
|
386
|
+
const paginatedSql = `${sql} STARTPOSITION ${startPosition} MAXRESULTS ${maxResults}`;
|
|
387
|
+
const tokens = await this.getValidTokens();
|
|
388
|
+
const env = this.config.environment || "production";
|
|
389
|
+
const baseUrl = API_BASE[env];
|
|
390
|
+
const url = `${baseUrl}/v3/company/${tokens.realm_id}/query`;
|
|
391
|
+
await this.checkRateLimit();
|
|
392
|
+
const fetchResponse = await fetch(url, {
|
|
393
|
+
method: "POST",
|
|
394
|
+
headers: {
|
|
395
|
+
Authorization: `Bearer ${tokens.access_token}`,
|
|
396
|
+
Accept: "application/json",
|
|
397
|
+
"Content-Type": "application/text"
|
|
398
|
+
},
|
|
399
|
+
body: paginatedSql
|
|
400
|
+
});
|
|
401
|
+
if (!fetchResponse.ok) {
|
|
402
|
+
const errorData = await fetchResponse.json().catch(() => ({}));
|
|
403
|
+
throw handleQuickBooksError({ status: fetchResponse.status, ...errorData });
|
|
404
|
+
}
|
|
405
|
+
const data = await fetchResponse.json();
|
|
406
|
+
const keys = Object.keys(data.QueryResponse).filter(
|
|
407
|
+
(k) => !["startPosition", "maxResults", "totalCount"].includes(k)
|
|
408
|
+
);
|
|
409
|
+
const entityKey = keys[0];
|
|
410
|
+
const pageResults = entityKey ? data.QueryResponse[entityKey] : [];
|
|
411
|
+
allResults.push(...pageResults);
|
|
412
|
+
this.log("debug", `Fetched page at position ${startPosition}, got ${pageResults.length} results (total: ${allResults.length})`);
|
|
413
|
+
if (pageResults.length < maxResults) {
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
startPosition += maxResults;
|
|
417
|
+
}
|
|
418
|
+
return allResults;
|
|
419
|
+
}
|
|
377
420
|
// ============================================
|
|
378
421
|
// Invoice Methods
|
|
379
422
|
// ============================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@panoptic-it-solutions/quickbooks-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "QuickBooks Online API client with OAuth 2.0, rate limiting, and typed entities",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
21
|
"test": "vitest",
|
|
22
22
|
"test:run": "vitest run",
|
|
23
|
+
"test:integration": "tsx test/integration.ts",
|
|
23
24
|
"lint": "biome check src",
|
|
24
25
|
"format": "biome format --write src",
|
|
25
26
|
"prepublishOnly": "npm run build"
|
|
@@ -41,11 +42,11 @@
|
|
|
41
42
|
"engines": {
|
|
42
43
|
"node": ">=18"
|
|
43
44
|
},
|
|
44
|
-
"dependencies": {},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@biomejs/biome": "^2.3.11",
|
|
47
47
|
"@types/node": "^20",
|
|
48
48
|
"tsup": "^8.0.0",
|
|
49
|
+
"tsx": "^4.21.0",
|
|
49
50
|
"typescript": "^5",
|
|
50
51
|
"vitest": "^2.0.0"
|
|
51
52
|
}
|