@panoptic-it-solutions/quickbooks-client 0.1.3 → 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.
package/dist/index.d.mts CHANGED
@@ -20,6 +20,8 @@ interface QuickBooksConfig {
20
20
  /** Options for initializing the client */
21
21
  interface QuickBooksClientOptions extends QuickBooksConfig {
22
22
  tokenStore: TokenStore;
23
+ /** QBO API minor version (e.g. 75). Appended to all API URLs. */
24
+ minorVersion?: number;
23
25
  /** Optional logging hook */
24
26
  onLog?: (level: "debug" | "info" | "warn" | "error", message: string, data?: unknown) => void;
25
27
  }
@@ -60,6 +62,11 @@ interface QueryResponse<T> {
60
62
  };
61
63
  time?: string;
62
64
  }
65
+ /** Ref type used throughout QBO entities */
66
+ interface Ref {
67
+ value: string;
68
+ name?: string;
69
+ }
63
70
  /** Base entity with common fields */
64
71
  interface BaseEntity {
65
72
  Id?: string;
@@ -69,42 +76,44 @@ interface BaseEntity {
69
76
  LastUpdatedTime?: string;
70
77
  };
71
78
  }
72
- /** Invoice entity */
79
+ /** Address */
80
+ interface Address {
81
+ Id?: string;
82
+ Line1?: string;
83
+ Line2?: string;
84
+ City?: string;
85
+ CountrySubDivisionCode?: string;
86
+ PostalCode?: string;
87
+ Country?: string;
88
+ }
73
89
  interface Invoice extends BaseEntity {
74
90
  DocNumber?: string;
75
91
  TxnDate?: string;
76
92
  DueDate?: string;
77
93
  TotalAmt?: number;
78
94
  Balance?: number;
79
- CustomerRef?: {
80
- value: string;
81
- name?: string;
82
- };
95
+ CustomerRef?: Ref;
83
96
  Line?: InvoiceLine[];
84
97
  BillEmail?: {
85
98
  Address?: string;
86
99
  };
87
- CurrencyRef?: {
88
- value: string;
89
- name?: string;
90
- };
100
+ CurrencyRef?: Ref;
101
+ TxnTaxDetail?: TxnTaxDetail;
102
+ PrivateNote?: string;
91
103
  }
92
104
  interface InvoiceLine {
93
105
  Id?: string;
94
106
  LineNum?: number;
95
107
  Description?: string;
96
108
  Amount?: number;
97
- DetailType?: string;
109
+ DetailType?: "SalesItemLineDetail" | "SubTotalLineDetail" | "DiscountLineDetail" | "GroupLineDetail" | string;
98
110
  SalesItemLineDetail?: {
99
- ItemRef?: {
100
- value: string;
101
- name?: string;
102
- };
111
+ ItemRef?: Ref;
112
+ TaxCodeRef?: Ref;
103
113
  Qty?: number;
104
114
  UnitPrice?: number;
105
115
  };
106
116
  }
107
- /** Customer entity */
108
117
  interface Customer extends BaseEntity {
109
118
  DisplayName?: string;
110
119
  CompanyName?: string;
@@ -121,31 +130,12 @@ interface Customer extends BaseEntity {
121
130
  Balance?: number;
122
131
  Active?: boolean;
123
132
  }
124
- interface Address {
125
- Id?: string;
126
- Line1?: string;
127
- Line2?: string;
128
- City?: string;
129
- CountrySubDivisionCode?: string;
130
- PostalCode?: string;
131
- Country?: string;
132
- }
133
- /** Payment entity */
134
133
  interface Payment extends BaseEntity {
135
134
  TxnDate?: string;
136
135
  TotalAmt?: number;
137
- CustomerRef?: {
138
- value: string;
139
- name?: string;
140
- };
141
- DepositToAccountRef?: {
142
- value: string;
143
- name?: string;
144
- };
145
- PaymentMethodRef?: {
146
- value: string;
147
- name?: string;
148
- };
136
+ CustomerRef?: Ref;
137
+ DepositToAccountRef?: Ref;
138
+ PaymentMethodRef?: Ref;
149
139
  Line?: PaymentLine[];
150
140
  }
151
141
  interface PaymentLine {
@@ -155,7 +145,6 @@ interface PaymentLine {
155
145
  TxnType: string;
156
146
  }>;
157
147
  }
158
- /** Account entity */
159
148
  interface Account extends BaseEntity {
160
149
  Name?: string;
161
150
  AccountType?: string;
@@ -164,8 +153,8 @@ interface Account extends BaseEntity {
164
153
  Active?: boolean;
165
154
  Classification?: string;
166
155
  FullyQualifiedName?: string;
156
+ CurrencyRef?: Ref;
167
157
  }
168
- /** Vendor entity */
169
158
  interface Vendor extends BaseEntity {
170
159
  DisplayName?: string;
171
160
  CompanyName?: string;
@@ -180,34 +169,227 @@ interface Vendor extends BaseEntity {
180
169
  BillAddr?: Address;
181
170
  Balance?: number;
182
171
  Active?: boolean;
172
+ TaxIdentifier?: string;
173
+ CurrencyRef?: Ref;
183
174
  }
184
- /** Bill entity */
185
175
  interface Bill extends BaseEntity {
186
176
  DocNumber?: string;
187
177
  TxnDate?: string;
188
178
  DueDate?: string;
189
179
  TotalAmt?: number;
190
180
  Balance?: number;
191
- VendorRef?: {
192
- value: string;
193
- name?: string;
194
- };
181
+ VendorRef?: Ref;
182
+ APAccountRef?: Ref;
195
183
  Line?: BillLine[];
184
+ TxnTaxDetail?: TxnTaxDetail;
185
+ PrivateNote?: string;
186
+ CurrencyRef?: Ref;
187
+ DepartmentRef?: Ref;
196
188
  }
197
189
  interface BillLine {
198
190
  Id?: string;
199
191
  LineNum?: number;
200
192
  Description?: string;
201
193
  Amount?: number;
202
- DetailType?: string;
194
+ DetailType?: "AccountBasedExpenseLineDetail" | "ItemBasedExpenseLineDetail" | string;
195
+ AccountBasedExpenseLineDetail?: {
196
+ AccountRef?: Ref;
197
+ TaxCodeRef?: Ref;
198
+ BillableStatus?: "Billable" | "NotBillable" | "HasBeenBilled";
199
+ CustomerRef?: Ref;
200
+ TaxAmount?: number;
201
+ };
202
+ ItemBasedExpenseLineDetail?: {
203
+ ItemRef?: Ref;
204
+ TaxCodeRef?: Ref;
205
+ BillableStatus?: "Billable" | "NotBillable" | "HasBeenBilled";
206
+ CustomerRef?: Ref;
207
+ Qty?: number;
208
+ UnitPrice?: number;
209
+ };
210
+ }
211
+ interface BillPayment extends BaseEntity {
212
+ VendorRef?: Ref;
213
+ TotalAmt?: number;
214
+ PayType?: "Check" | "CreditCard";
215
+ DocNumber?: string;
216
+ TxnDate?: string;
217
+ APAccountRef?: Ref;
218
+ DepartmentRef?: Ref;
219
+ CurrencyRef?: Ref;
220
+ PrivateNote?: string;
221
+ Line?: BillPaymentLine[];
222
+ CheckPayment?: {
223
+ BankAccountRef?: Ref;
224
+ PrintStatus?: "NeedToPrint" | "NotSet";
225
+ };
226
+ CreditCardPayment?: {
227
+ CCAccountRef?: Ref;
228
+ };
229
+ }
230
+ interface BillPaymentLine {
231
+ Amount?: number;
232
+ LinkedTxn?: Array<{
233
+ TxnId: string;
234
+ TxnType: "Bill" | string;
235
+ }>;
236
+ }
237
+ interface CreditMemo extends BaseEntity {
238
+ DocNumber?: string;
239
+ TxnDate?: string;
240
+ TotalAmt?: number;
241
+ Balance?: number;
242
+ RemainingCredit?: number;
243
+ CustomerRef?: Ref;
244
+ Line?: CreditMemoLine[];
245
+ BillEmail?: {
246
+ Address?: string;
247
+ };
248
+ CurrencyRef?: Ref;
249
+ TxnTaxDetail?: TxnTaxDetail;
250
+ PrivateNote?: string;
251
+ DepartmentRef?: Ref;
252
+ }
253
+ interface CreditMemoLine {
254
+ Id?: string;
255
+ LineNum?: number;
256
+ Description?: string;
257
+ Amount?: number;
258
+ DetailType?: "SalesItemLineDetail" | "SubTotalLineDetail" | string;
259
+ SalesItemLineDetail?: {
260
+ ItemRef?: Ref;
261
+ TaxCodeRef?: Ref;
262
+ Qty?: number;
263
+ UnitPrice?: number;
264
+ };
265
+ }
266
+ interface VendorCredit extends BaseEntity {
267
+ DocNumber?: string;
268
+ TxnDate?: string;
269
+ TotalAmt?: number;
270
+ Balance?: number;
271
+ VendorRef?: Ref;
272
+ APAccountRef?: Ref;
273
+ Line?: VendorCreditLine[];
274
+ CurrencyRef?: Ref;
275
+ PrivateNote?: string;
276
+ DepartmentRef?: Ref;
277
+ }
278
+ interface VendorCreditLine {
279
+ Id?: string;
280
+ LineNum?: number;
281
+ Description?: string;
282
+ Amount?: number;
283
+ DetailType?: "AccountBasedExpenseLineDetail" | "ItemBasedExpenseLineDetail" | string;
203
284
  AccountBasedExpenseLineDetail?: {
204
- AccountRef?: {
205
- value: string;
206
- name?: string;
207
- };
285
+ AccountRef?: Ref;
286
+ TaxCodeRef?: Ref;
287
+ BillableStatus?: "Billable" | "NotBillable" | "HasBeenBilled";
288
+ CustomerRef?: Ref;
289
+ };
290
+ ItemBasedExpenseLineDetail?: {
291
+ ItemRef?: Ref;
292
+ TaxCodeRef?: Ref;
293
+ BillableStatus?: "Billable" | "NotBillable" | "HasBeenBilled";
294
+ CustomerRef?: Ref;
295
+ Qty?: number;
296
+ UnitPrice?: number;
297
+ };
298
+ }
299
+ interface TaxCode extends BaseEntity {
300
+ Name?: string;
301
+ Description?: string;
302
+ Active?: boolean;
303
+ Taxable?: boolean;
304
+ TaxGroup?: boolean;
305
+ SalesTaxRateList?: {
306
+ TaxRateDetail?: TaxRateDetail[];
307
+ };
308
+ PurchaseTaxRateList?: {
309
+ TaxRateDetail?: TaxRateDetail[];
310
+ };
311
+ }
312
+ interface TaxRateDetail {
313
+ TaxRateRef?: Ref;
314
+ TaxTypeApplicable?: "TaxOnAmount" | "TaxOnAmountPlusTax" | "TaxOnTax";
315
+ TaxOrder?: number;
316
+ }
317
+ interface TaxRate extends BaseEntity {
318
+ Name?: string;
319
+ Description?: string;
320
+ RateValue?: number;
321
+ Active?: boolean;
322
+ AgencyRef?: Ref;
323
+ TaxReturnLineRef?: Ref;
324
+ SpecialTaxType?: string;
325
+ DisplayType?: string;
326
+ }
327
+ /** Tax detail block used on transactions (Invoice, Bill, CreditMemo, etc.) */
328
+ interface TxnTaxDetail {
329
+ TxnTaxCodeRef?: Ref;
330
+ TotalTax?: number;
331
+ TaxLine?: TaxLine[];
332
+ }
333
+ interface TaxLine {
334
+ Amount?: number;
335
+ DetailType?: "TaxLineDetail";
336
+ TaxLineDetail?: {
337
+ TaxRateRef?: Ref;
338
+ PercentBased?: boolean;
339
+ TaxPercent?: number;
340
+ NetAmountTaxable?: number;
341
+ TaxInclusiveAmount?: number;
342
+ OverrideDeltaAmount?: number;
208
343
  };
209
344
  }
210
- /** Item entity */
345
+ interface Attachable extends BaseEntity {
346
+ FileName?: string;
347
+ FileAccessUri?: string;
348
+ TempDownloadUri?: string;
349
+ Size?: number;
350
+ ContentType?: string;
351
+ Category?: string;
352
+ Lat?: string;
353
+ Long?: string;
354
+ PlaceName?: string;
355
+ Note?: string;
356
+ Tag?: string;
357
+ ThumbnailFileAccessUri?: string;
358
+ ThumbnailTempDownloadUri?: string;
359
+ AttachableRef?: AttachableRef[];
360
+ }
361
+ interface AttachableRef {
362
+ EntityRef?: Ref;
363
+ IncludeOnSend?: boolean;
364
+ LineInfo?: string;
365
+ NoRefOnly?: boolean;
366
+ /** e.g. "Bill", "Invoice", "VendorCredit" */
367
+ Inactive?: boolean;
368
+ }
369
+ interface CompanyInfo extends BaseEntity {
370
+ CompanyName?: string;
371
+ LegalName?: string;
372
+ CompanyAddr?: Address;
373
+ CustomerCommunicationAddr?: Address;
374
+ LegalAddr?: Address;
375
+ PrimaryPhone?: {
376
+ FreeFormNumber?: string;
377
+ };
378
+ CompanyStartDate?: string;
379
+ FiscalYearStartMonth?: string;
380
+ Country?: string;
381
+ Email?: {
382
+ Address?: string;
383
+ };
384
+ WebAddr?: {
385
+ URI?: string;
386
+ };
387
+ SupportedLanguages?: string;
388
+ NameValue?: Array<{
389
+ Name: string;
390
+ Value: string;
391
+ }>;
392
+ }
211
393
  interface Item extends BaseEntity {
212
394
  Name?: string;
213
395
  Description?: string;
@@ -217,15 +399,41 @@ interface Item extends BaseEntity {
217
399
  UnitPrice?: number;
218
400
  PurchaseCost?: number;
219
401
  QtyOnHand?: number;
220
- IncomeAccountRef?: {
221
- value: string;
222
- name?: string;
223
- };
224
- ExpenseAccountRef?: {
225
- value: string;
226
- name?: string;
402
+ IncomeAccountRef?: Ref;
403
+ ExpenseAccountRef?: Ref;
404
+ AssetAccountRef?: Ref;
405
+ Taxable?: boolean;
406
+ SalesTaxIncluded?: boolean;
407
+ PurchaseTaxIncluded?: boolean;
408
+ SalesTaxCodeRef?: Ref;
409
+ PurchaseTaxCodeRef?: Ref;
410
+ }
411
+ interface BatchItemRequest {
412
+ /** Unique ID for this batch item (you choose) */
413
+ bId: string;
414
+ /** Operation to perform */
415
+ operation: "create" | "update" | "delete" | "query";
416
+ /** Only for non-query operations: entity name e.g. "Bill", "Invoice" */
417
+ optionsData?: string;
418
+ /** The entity payload (for create/update/delete) */
419
+ [entityName: string]: unknown;
420
+ }
421
+ interface BatchItemResponse {
422
+ bId: string;
423
+ [key: string]: unknown;
424
+ Fault?: {
425
+ Error?: Array<{
426
+ Message?: string;
427
+ Detail?: string;
428
+ code?: string;
429
+ }>;
430
+ type?: string;
227
431
  };
228
432
  }
433
+ interface BatchResponse {
434
+ BatchItemResponse: BatchItemResponse[];
435
+ time?: string;
436
+ }
229
437
 
230
438
  /**
231
439
  * QuickBooks Online API Client
@@ -238,9 +446,14 @@ declare class QuickBooksClient {
238
446
  private tokenStore;
239
447
  private requestTimestamps;
240
448
  private onLog;
449
+ private minorVersion;
241
450
  constructor(options: QuickBooksClientOptions);
242
451
  private validateConfig;
243
452
  private log;
453
+ /**
454
+ * Append minorversion query param to a URL if configured
455
+ */
456
+ private appendMinorVersion;
244
457
  /**
245
458
  * Rate limiting - ensures we don't exceed 500 requests/minute
246
459
  */
@@ -285,14 +498,59 @@ declare class QuickBooksClient {
285
498
  getBills(where?: string): Promise<Bill[]>;
286
499
  createBill(bill: Partial<Bill>): Promise<Bill>;
287
500
  updateBill(bill: Bill): Promise<Bill>;
501
+ deleteBill(id: string, syncToken: string): Promise<void>;
502
+ getBillPayment(id: string): Promise<BillPayment>;
503
+ getBillPayments(where?: string): Promise<BillPayment[]>;
504
+ createBillPayment(billPayment: Partial<BillPayment>): Promise<BillPayment>;
505
+ updateBillPayment(billPayment: BillPayment): Promise<BillPayment>;
506
+ deleteBillPayment(id: string, syncToken: string): Promise<void>;
507
+ getCreditMemo(id: string): Promise<CreditMemo>;
508
+ getCreditMemos(where?: string): Promise<CreditMemo[]>;
509
+ createCreditMemo(creditMemo: Partial<CreditMemo>): Promise<CreditMemo>;
510
+ updateCreditMemo(creditMemo: CreditMemo): Promise<CreditMemo>;
511
+ deleteCreditMemo(id: string, syncToken: string): Promise<void>;
512
+ getVendorCredit(id: string): Promise<VendorCredit>;
513
+ getVendorCredits(where?: string): Promise<VendorCredit[]>;
514
+ createVendorCredit(vendorCredit: Partial<VendorCredit>): Promise<VendorCredit>;
515
+ updateVendorCredit(vendorCredit: VendorCredit): Promise<VendorCredit>;
516
+ deleteVendorCredit(id: string, syncToken: string): Promise<void>;
517
+ getTaxCode(id: string): Promise<TaxCode>;
518
+ getTaxCodes(where?: string): Promise<TaxCode[]>;
519
+ getTaxRate(id: string): Promise<TaxRate>;
520
+ getTaxRates(where?: string): Promise<TaxRate[]>;
288
521
  getItem(id: string): Promise<Item>;
289
522
  getItems(where?: string): Promise<Item[]>;
290
523
  createItem(item: Partial<Item>): Promise<Item>;
291
524
  updateItem(item: Item): Promise<Item>;
525
+ getAttachable(id: string): Promise<Attachable>;
526
+ getAttachables(where?: string): Promise<Attachable[]>;
527
+ /**
528
+ * Upload a file and attach it to an entity.
529
+ * Uses multipart/form-data — the QBO upload endpoint differs from standard CRUD.
530
+ */
531
+ uploadAttachable(file: Blob | Buffer, fileName: string, contentType: string, attachTo?: {
532
+ entityType: string;
533
+ entityId: string;
534
+ }): Promise<Attachable>;
535
+ updateAttachable(attachable: Attachable): Promise<Attachable>;
536
+ deleteAttachable(id: string, syncToken: string): Promise<void>;
537
+ /**
538
+ * Execute a batch of up to 30 operations in a single API call.
539
+ * Each item needs a unique bId and the entity payload.
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * const results = await client.batch([
544
+ * { bId: "1", operation: "create", Bill: { VendorRef: { value: "1" }, Line: [...] } },
545
+ * { bId: "2", operation: "query", optionsData: "SELECT * FROM Vendor WHERE Id = '1'" },
546
+ * ]);
547
+ * ```
548
+ */
549
+ batch(items: BatchItemRequest[]): Promise<BatchResponse>;
292
550
  /**
293
551
  * Get company info
294
552
  */
295
- getCompanyInfo(): Promise<unknown>;
553
+ getCompanyInfo(): Promise<CompanyInfo>;
296
554
  /**
297
555
  * Check if connected to QuickBooks
298
556
  */
@@ -308,6 +566,32 @@ declare class QuickBooksClient {
308
566
  }>;
309
567
  }
310
568
 
569
+ /**
570
+ * QuickBooks Error Handling
571
+ */
572
+ /** Error codes for QuickBooks API errors */
573
+ declare const QB_ERROR_CODES: {
574
+ readonly TOKEN_EXPIRED: "QB_TOKEN_EXPIRED";
575
+ readonly REFRESH_FAILED: "QB_REFRESH_FAILED";
576
+ readonly UNAUTHORIZED: "QB_UNAUTHORIZED";
577
+ readonly INVALID_REALM: "QB_INVALID_REALM";
578
+ readonly API_ERROR: "QB_API_ERROR";
579
+ readonly RATE_LIMIT: "QB_RATE_LIMIT";
580
+ readonly NETWORK_ERROR: "QB_NETWORK_ERROR";
581
+ readonly INVALID_CONFIG: "QB_INVALID_CONFIG";
582
+ readonly TOKEN_STORE_ERROR: "QB_TOKEN_STORE_ERROR";
583
+ };
584
+ type QuickBooksErrorCode = (typeof QB_ERROR_CODES)[keyof typeof QB_ERROR_CODES];
585
+ /** Custom error class for QuickBooks-related errors */
586
+ declare class QuickBooksError extends Error {
587
+ code: QuickBooksErrorCode;
588
+ status?: number | undefined;
589
+ details?: unknown | undefined;
590
+ constructor(message: string, code: QuickBooksErrorCode, status?: number | undefined, details?: unknown | undefined);
591
+ }
592
+ /** Handle and normalize errors from QuickBooks API */
593
+ declare function handleQuickBooksError(error: unknown): QuickBooksError;
594
+
311
595
  /**
312
596
  * OAuth 2.0 implementation for QuickBooks Online
313
597
  *
@@ -343,30 +627,4 @@ declare function isTokenExpired(expiresAt: number, bufferSeconds?: number): bool
343
627
  */
344
628
  declare function generateState(): string;
345
629
 
346
- /**
347
- * QuickBooks Error Handling
348
- */
349
- /** Error codes for QuickBooks API errors */
350
- declare const QB_ERROR_CODES: {
351
- readonly TOKEN_EXPIRED: "QB_TOKEN_EXPIRED";
352
- readonly REFRESH_FAILED: "QB_REFRESH_FAILED";
353
- readonly UNAUTHORIZED: "QB_UNAUTHORIZED";
354
- readonly INVALID_REALM: "QB_INVALID_REALM";
355
- readonly API_ERROR: "QB_API_ERROR";
356
- readonly RATE_LIMIT: "QB_RATE_LIMIT";
357
- readonly NETWORK_ERROR: "QB_NETWORK_ERROR";
358
- readonly INVALID_CONFIG: "QB_INVALID_CONFIG";
359
- readonly TOKEN_STORE_ERROR: "QB_TOKEN_STORE_ERROR";
360
- };
361
- type QuickBooksErrorCode = (typeof QB_ERROR_CODES)[keyof typeof QB_ERROR_CODES];
362
- /** Custom error class for QuickBooks-related errors */
363
- declare class QuickBooksError extends Error {
364
- code: QuickBooksErrorCode;
365
- status?: number | undefined;
366
- details?: unknown | undefined;
367
- constructor(message: string, code: QuickBooksErrorCode, status?: number | undefined, details?: unknown | undefined);
368
- }
369
- /** Handle and normalize errors from QuickBooks API */
370
- declare function handleQuickBooksError(error: unknown): QuickBooksError;
371
-
372
- export { type Account, type Address, type BaseEntity, type Bill, type BillLine, type Customer, type Invoice, type InvoiceLine, type Item, type OAuthTokenResponse, type Payment, type PaymentLine, QB_ERROR_CODES, type QueryResponse, type QuickBooksApiError, QuickBooksClient, type QuickBooksClientOptions, type QuickBooksConfig, QuickBooksError, type QuickBooksErrorCode, type QuickBooksTokens, type TokenStore, type Vendor, calculateTokenExpiry, exchangeCodeForTokens, generateAuthUrl, generateState, handleQuickBooksError, isTokenExpired, refreshTokens, revokeTokens };
630
+ export { type Account, type Address, type Attachable, type AttachableRef, type BaseEntity, type BatchItemRequest, type BatchItemResponse, type BatchResponse, type Bill, type BillLine, type BillPayment, type BillPaymentLine, type CompanyInfo, type CreditMemo, type CreditMemoLine, type Customer, type Invoice, type InvoiceLine, type Item, type OAuthTokenResponse, type Payment, type PaymentLine, QB_ERROR_CODES, type QueryResponse, type QuickBooksApiError, QuickBooksClient, type QuickBooksClientOptions, type QuickBooksConfig, QuickBooksError, type QuickBooksErrorCode, type QuickBooksTokens, type Ref, type TaxCode, type TaxLine, type TaxRate, type TaxRateDetail, type TokenStore, type TxnTaxDetail, type Vendor, type VendorCredit, type VendorCreditLine, calculateTokenExpiry, exchangeCodeForTokens, generateAuthUrl, generateState, handleQuickBooksError, isTokenExpired, refreshTokens, revokeTokens };