colacloud 1.2.0 → 1.3.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,10 +20,14 @@ interface Pagination {
20
20
  page: number;
21
21
  /** Number of items per page */
22
22
  per_page: number;
23
- /** Total number of items across all pages */
24
- total: number;
25
- /** Total number of pages */
26
- pages: number;
23
+ /** Total number of items across all pages (null when using offset pagination without count) */
24
+ total: number | null;
25
+ /** Total number of pages (null when using offset pagination without count) */
26
+ pages: number | null;
27
+ /** Whether there are more results available */
28
+ has_more?: boolean;
29
+ /** Pagination mode: "cursor" or "offset" */
30
+ mode?: string;
27
31
  }
28
32
  /**
29
33
  * Response wrapper for paginated list endpoints
@@ -42,24 +46,26 @@ interface SingleResponse<T> {
42
46
  data: T;
43
47
  }
44
48
  /**
45
- * Rate limit information from response headers
49
+ * Quota information parsed from response headers
46
50
  */
47
- interface RateLimitInfo {
48
- /** Maximum requests allowed per minute */
51
+ interface QuotaInfo {
52
+ /** Which meter this quota applies to */
53
+ meter: 'detail_views' | 'list_records';
54
+ /** Quota limit for the current billing period */
49
55
  limit: number;
50
- /** Remaining requests in the current window */
56
+ /** Remaining quota in the current billing period */
51
57
  remaining: number;
52
- /** Unix timestamp when the rate limit resets */
58
+ /** Unix timestamp when quotas reset (first of next month) */
53
59
  reset: number;
54
60
  }
55
61
  /**
56
- * Extended response that includes rate limit information
62
+ * Extended response that includes quota information
57
63
  */
58
- interface ResponseWithRateLimit<T> {
64
+ interface ResponseWithQuota<T> {
59
65
  /** The response data */
60
66
  data: T;
61
- /** Rate limit information from headers */
62
- rateLimit: RateLimitInfo | null;
67
+ /** Quota information from headers */
68
+ quota: QuotaInfo | null;
63
69
  }
64
70
  /**
65
71
  * Summary information about a COLA (Certificate of Label Approval)
@@ -382,7 +388,7 @@ declare class ColaCloud {
382
388
  * Make an authenticated request to the API
383
389
  * @internal
384
390
  */
385
- request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, params?: Record<string, unknown>): Promise<ResponseWithRateLimit<T>>;
391
+ request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, params?: Record<string, unknown>): Promise<ResponseWithQuota<T>>;
386
392
  /**
387
393
  * Handle error responses from the API
388
394
  */
@@ -401,11 +407,11 @@ declare class ColasResource {
401
407
  */
402
408
  list(params?: ColaListParams): Promise<PaginatedResponse<ColaSummary>>;
403
409
  /**
404
- * List COLAs with rate limit information
410
+ * List COLAs with quota information
405
411
  * @param params Search and filter parameters
406
- * @returns Paginated list with rate limit info
412
+ * @returns Paginated list with quota info
407
413
  */
408
- listWithRateLimit(params?: ColaListParams): Promise<ResponseWithRateLimit<PaginatedResponse<ColaSummary>>>;
414
+ listWithQuota(params?: ColaListParams): Promise<ResponseWithQuota<PaginatedResponse<ColaSummary>>>;
409
415
  /**
410
416
  * Get a single COLA by TTB ID
411
417
  * @param ttbId The unique TTB identifier
@@ -413,11 +419,11 @@ declare class ColasResource {
413
419
  */
414
420
  get(ttbId: string): Promise<ColaDetail>;
415
421
  /**
416
- * Get a single COLA with rate limit information
422
+ * Get a single COLA with quota information
417
423
  * @param ttbId The unique TTB identifier
418
- * @returns COLA details with rate limit info
424
+ * @returns COLA details with quota info
419
425
  */
420
- getWithRateLimit(ttbId: string): Promise<ResponseWithRateLimit<ColaDetail>>;
426
+ getWithQuota(ttbId: string): Promise<ResponseWithQuota<ColaDetail>>;
421
427
  /**
422
428
  * Create an async iterator that automatically pages through all results
423
429
  * @param params Search and filter parameters (page is ignored)
@@ -445,11 +451,11 @@ declare class PermitteesResource {
445
451
  */
446
452
  list(params?: PermitteeListParams): Promise<PaginatedResponse<PermitteeSummary>>;
447
453
  /**
448
- * List permittees with rate limit information
454
+ * List permittees with quota information
449
455
  * @param params Search and filter parameters
450
- * @returns Paginated list with rate limit info
456
+ * @returns Paginated list with quota info
451
457
  */
452
- listWithRateLimit(params?: PermitteeListParams): Promise<ResponseWithRateLimit<PaginatedResponse<PermitteeSummary>>>;
458
+ listWithQuota(params?: PermitteeListParams): Promise<ResponseWithQuota<PaginatedResponse<PermitteeSummary>>>;
453
459
  /**
454
460
  * Get a single permittee by permit number
455
461
  * @param permitNumber The unique permit number
@@ -457,11 +463,11 @@ declare class PermitteesResource {
457
463
  */
458
464
  get(permitNumber: string): Promise<PermitteeDetail>;
459
465
  /**
460
- * Get a single permittee with rate limit information
466
+ * Get a single permittee with quota information
461
467
  * @param permitNumber The unique permit number
462
- * @returns Permittee details with rate limit info
468
+ * @returns Permittee details with quota info
463
469
  */
464
- getWithRateLimit(permitNumber: string): Promise<ResponseWithRateLimit<PermitteeDetail>>;
470
+ getWithQuota(permitNumber: string): Promise<ResponseWithQuota<PermitteeDetail>>;
465
471
  /**
466
472
  * Create an async iterator that automatically pages through all results
467
473
  * @param params Search and filter parameters (page is ignored)
@@ -489,11 +495,11 @@ declare class BarcodesResource {
489
495
  */
490
496
  lookup(barcodeValue: string): Promise<BarcodeLookupResult>;
491
497
  /**
492
- * Look up barcode with rate limit information
498
+ * Look up barcode with quota information
493
499
  * @param barcodeValue The barcode to search for
494
- * @returns Barcode lookup result with rate limit info
500
+ * @returns Barcode lookup result with quota info
495
501
  */
496
- lookupWithRateLimit(barcodeValue: string): Promise<ResponseWithRateLimit<BarcodeLookupResult>>;
502
+ lookupWithQuota(barcodeValue: string): Promise<ResponseWithQuota<BarcodeLookupResult>>;
497
503
  }
498
504
  /**
499
505
  * Usage statistics resource handler
@@ -507,10 +513,10 @@ declare class UsageResource {
507
513
  */
508
514
  get(): Promise<UsageStats>;
509
515
  /**
510
- * Get usage statistics with rate limit information
511
- * @returns Usage statistics with rate limit info
516
+ * Get usage statistics with quota information
517
+ * @returns Usage statistics with quota info
512
518
  */
513
- getWithRateLimit(): Promise<ResponseWithRateLimit<UsageStats>>;
519
+ getWithQuota(): Promise<ResponseWithQuota<UsageStats>>;
514
520
  }
515
521
 
516
522
  /**
@@ -543,11 +549,11 @@ declare class AuthenticationError extends ColaCloudError {
543
549
  * Error thrown when rate limit is exceeded (429 Too Many Requests)
544
550
  */
545
551
  declare class RateLimitError extends ColaCloudError {
546
- /** Rate limit information from headers */
547
- readonly rateLimit: RateLimitInfo | null;
552
+ /** Quota information from headers */
553
+ readonly quota: QuotaInfo | null;
548
554
  /** Seconds until the rate limit resets */
549
555
  readonly retryAfter: number | null;
550
- constructor(message?: string, rateLimit?: RateLimitInfo | null, retryAfter?: number | null);
556
+ constructor(message?: string, quota?: QuotaInfo | null, retryAfter?: number | null);
551
557
  }
552
558
  /**
553
559
  * Error thrown when a requested resource is not found (404 Not Found)
@@ -605,7 +611,7 @@ interface PaginatedIteratorOptions<TParams> {
605
611
  page: number;
606
612
  }) => Promise<{
607
613
  response: PaginatedResponse<unknown>;
608
- rateLimit: RateLimitInfo | null;
614
+ quota: QuotaInfo | null;
609
615
  }>;
610
616
  /** Starting page number (defaults to 1) */
611
617
  startPage?: number;
@@ -624,8 +630,8 @@ interface PaginatedIteratorResult<T> {
624
630
  indexInPage: number;
625
631
  /** Total items across all pages */
626
632
  total: number;
627
- /** Rate limit info from the last request */
628
- rateLimit: RateLimitInfo | null;
633
+ /** Quota info from the last request */
634
+ quota: QuotaInfo | null;
629
635
  }
630
636
  /**
631
637
  * Creates an async iterator that automatically handles pagination
@@ -655,4 +661,4 @@ declare function collectAll<T>(iterator: AsyncIterable<T>, maxItems?: number): P
655
661
  */
656
662
  declare function take<T>(iterator: AsyncIterable<T>, count: number): Promise<T[]>;
657
663
 
658
- export { type ApiErrorResponse, AuthenticationError, type BarcodeLookupResult, type ColaBarcode, ColaCloud, type ColaCloudConfig, ColaCloudError, type ColaDetail, type ColaImage, type ColaListParams, type ColaSummary, NetworkError, NotFoundError, type PaginatedIteratorOptions, type PaginatedIteratorResult, type PaginatedResponse, type Pagination, type PermitteeDetail, type PermitteeListParams, type PermitteeSummary, RateLimitError, type RateLimitInfo, type ResponseWithRateLimit, ServerError, type SingleResponse, TimeoutError, type UsageStats, ValidationError, collectAll, createPaginatedIterator, createPaginatedIteratorWithMetadata, take };
664
+ export { type ApiErrorResponse, AuthenticationError, type BarcodeLookupResult, type ColaBarcode, ColaCloud, type ColaCloudConfig, ColaCloudError, type ColaDetail, type ColaImage, type ColaListParams, type ColaSummary, NetworkError, NotFoundError, type PaginatedIteratorOptions, type PaginatedIteratorResult, type PaginatedResponse, type Pagination, type PermitteeDetail, type PermitteeListParams, type PermitteeSummary, type QuotaInfo, RateLimitError, type ResponseWithQuota, ServerError, type SingleResponse, TimeoutError, type UsageStats, ValidationError, collectAll, createPaginatedIterator, createPaginatedIteratorWithMetadata, take };
package/dist/index.d.ts CHANGED
@@ -20,10 +20,14 @@ interface Pagination {
20
20
  page: number;
21
21
  /** Number of items per page */
22
22
  per_page: number;
23
- /** Total number of items across all pages */
24
- total: number;
25
- /** Total number of pages */
26
- pages: number;
23
+ /** Total number of items across all pages (null when using offset pagination without count) */
24
+ total: number | null;
25
+ /** Total number of pages (null when using offset pagination without count) */
26
+ pages: number | null;
27
+ /** Whether there are more results available */
28
+ has_more?: boolean;
29
+ /** Pagination mode: "cursor" or "offset" */
30
+ mode?: string;
27
31
  }
28
32
  /**
29
33
  * Response wrapper for paginated list endpoints
@@ -42,24 +46,26 @@ interface SingleResponse<T> {
42
46
  data: T;
43
47
  }
44
48
  /**
45
- * Rate limit information from response headers
49
+ * Quota information parsed from response headers
46
50
  */
47
- interface RateLimitInfo {
48
- /** Maximum requests allowed per minute */
51
+ interface QuotaInfo {
52
+ /** Which meter this quota applies to */
53
+ meter: 'detail_views' | 'list_records';
54
+ /** Quota limit for the current billing period */
49
55
  limit: number;
50
- /** Remaining requests in the current window */
56
+ /** Remaining quota in the current billing period */
51
57
  remaining: number;
52
- /** Unix timestamp when the rate limit resets */
58
+ /** Unix timestamp when quotas reset (first of next month) */
53
59
  reset: number;
54
60
  }
55
61
  /**
56
- * Extended response that includes rate limit information
62
+ * Extended response that includes quota information
57
63
  */
58
- interface ResponseWithRateLimit<T> {
64
+ interface ResponseWithQuota<T> {
59
65
  /** The response data */
60
66
  data: T;
61
- /** Rate limit information from headers */
62
- rateLimit: RateLimitInfo | null;
67
+ /** Quota information from headers */
68
+ quota: QuotaInfo | null;
63
69
  }
64
70
  /**
65
71
  * Summary information about a COLA (Certificate of Label Approval)
@@ -382,7 +388,7 @@ declare class ColaCloud {
382
388
  * Make an authenticated request to the API
383
389
  * @internal
384
390
  */
385
- request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, params?: Record<string, unknown>): Promise<ResponseWithRateLimit<T>>;
391
+ request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, params?: Record<string, unknown>): Promise<ResponseWithQuota<T>>;
386
392
  /**
387
393
  * Handle error responses from the API
388
394
  */
@@ -401,11 +407,11 @@ declare class ColasResource {
401
407
  */
402
408
  list(params?: ColaListParams): Promise<PaginatedResponse<ColaSummary>>;
403
409
  /**
404
- * List COLAs with rate limit information
410
+ * List COLAs with quota information
405
411
  * @param params Search and filter parameters
406
- * @returns Paginated list with rate limit info
412
+ * @returns Paginated list with quota info
407
413
  */
408
- listWithRateLimit(params?: ColaListParams): Promise<ResponseWithRateLimit<PaginatedResponse<ColaSummary>>>;
414
+ listWithQuota(params?: ColaListParams): Promise<ResponseWithQuota<PaginatedResponse<ColaSummary>>>;
409
415
  /**
410
416
  * Get a single COLA by TTB ID
411
417
  * @param ttbId The unique TTB identifier
@@ -413,11 +419,11 @@ declare class ColasResource {
413
419
  */
414
420
  get(ttbId: string): Promise<ColaDetail>;
415
421
  /**
416
- * Get a single COLA with rate limit information
422
+ * Get a single COLA with quota information
417
423
  * @param ttbId The unique TTB identifier
418
- * @returns COLA details with rate limit info
424
+ * @returns COLA details with quota info
419
425
  */
420
- getWithRateLimit(ttbId: string): Promise<ResponseWithRateLimit<ColaDetail>>;
426
+ getWithQuota(ttbId: string): Promise<ResponseWithQuota<ColaDetail>>;
421
427
  /**
422
428
  * Create an async iterator that automatically pages through all results
423
429
  * @param params Search and filter parameters (page is ignored)
@@ -445,11 +451,11 @@ declare class PermitteesResource {
445
451
  */
446
452
  list(params?: PermitteeListParams): Promise<PaginatedResponse<PermitteeSummary>>;
447
453
  /**
448
- * List permittees with rate limit information
454
+ * List permittees with quota information
449
455
  * @param params Search and filter parameters
450
- * @returns Paginated list with rate limit info
456
+ * @returns Paginated list with quota info
451
457
  */
452
- listWithRateLimit(params?: PermitteeListParams): Promise<ResponseWithRateLimit<PaginatedResponse<PermitteeSummary>>>;
458
+ listWithQuota(params?: PermitteeListParams): Promise<ResponseWithQuota<PaginatedResponse<PermitteeSummary>>>;
453
459
  /**
454
460
  * Get a single permittee by permit number
455
461
  * @param permitNumber The unique permit number
@@ -457,11 +463,11 @@ declare class PermitteesResource {
457
463
  */
458
464
  get(permitNumber: string): Promise<PermitteeDetail>;
459
465
  /**
460
- * Get a single permittee with rate limit information
466
+ * Get a single permittee with quota information
461
467
  * @param permitNumber The unique permit number
462
- * @returns Permittee details with rate limit info
468
+ * @returns Permittee details with quota info
463
469
  */
464
- getWithRateLimit(permitNumber: string): Promise<ResponseWithRateLimit<PermitteeDetail>>;
470
+ getWithQuota(permitNumber: string): Promise<ResponseWithQuota<PermitteeDetail>>;
465
471
  /**
466
472
  * Create an async iterator that automatically pages through all results
467
473
  * @param params Search and filter parameters (page is ignored)
@@ -489,11 +495,11 @@ declare class BarcodesResource {
489
495
  */
490
496
  lookup(barcodeValue: string): Promise<BarcodeLookupResult>;
491
497
  /**
492
- * Look up barcode with rate limit information
498
+ * Look up barcode with quota information
493
499
  * @param barcodeValue The barcode to search for
494
- * @returns Barcode lookup result with rate limit info
500
+ * @returns Barcode lookup result with quota info
495
501
  */
496
- lookupWithRateLimit(barcodeValue: string): Promise<ResponseWithRateLimit<BarcodeLookupResult>>;
502
+ lookupWithQuota(barcodeValue: string): Promise<ResponseWithQuota<BarcodeLookupResult>>;
497
503
  }
498
504
  /**
499
505
  * Usage statistics resource handler
@@ -507,10 +513,10 @@ declare class UsageResource {
507
513
  */
508
514
  get(): Promise<UsageStats>;
509
515
  /**
510
- * Get usage statistics with rate limit information
511
- * @returns Usage statistics with rate limit info
516
+ * Get usage statistics with quota information
517
+ * @returns Usage statistics with quota info
512
518
  */
513
- getWithRateLimit(): Promise<ResponseWithRateLimit<UsageStats>>;
519
+ getWithQuota(): Promise<ResponseWithQuota<UsageStats>>;
514
520
  }
515
521
 
516
522
  /**
@@ -543,11 +549,11 @@ declare class AuthenticationError extends ColaCloudError {
543
549
  * Error thrown when rate limit is exceeded (429 Too Many Requests)
544
550
  */
545
551
  declare class RateLimitError extends ColaCloudError {
546
- /** Rate limit information from headers */
547
- readonly rateLimit: RateLimitInfo | null;
552
+ /** Quota information from headers */
553
+ readonly quota: QuotaInfo | null;
548
554
  /** Seconds until the rate limit resets */
549
555
  readonly retryAfter: number | null;
550
- constructor(message?: string, rateLimit?: RateLimitInfo | null, retryAfter?: number | null);
556
+ constructor(message?: string, quota?: QuotaInfo | null, retryAfter?: number | null);
551
557
  }
552
558
  /**
553
559
  * Error thrown when a requested resource is not found (404 Not Found)
@@ -605,7 +611,7 @@ interface PaginatedIteratorOptions<TParams> {
605
611
  page: number;
606
612
  }) => Promise<{
607
613
  response: PaginatedResponse<unknown>;
608
- rateLimit: RateLimitInfo | null;
614
+ quota: QuotaInfo | null;
609
615
  }>;
610
616
  /** Starting page number (defaults to 1) */
611
617
  startPage?: number;
@@ -624,8 +630,8 @@ interface PaginatedIteratorResult<T> {
624
630
  indexInPage: number;
625
631
  /** Total items across all pages */
626
632
  total: number;
627
- /** Rate limit info from the last request */
628
- rateLimit: RateLimitInfo | null;
633
+ /** Quota info from the last request */
634
+ quota: QuotaInfo | null;
629
635
  }
630
636
  /**
631
637
  * Creates an async iterator that automatically handles pagination
@@ -655,4 +661,4 @@ declare function collectAll<T>(iterator: AsyncIterable<T>, maxItems?: number): P
655
661
  */
656
662
  declare function take<T>(iterator: AsyncIterable<T>, count: number): Promise<T[]>;
657
663
 
658
- export { type ApiErrorResponse, AuthenticationError, type BarcodeLookupResult, type ColaBarcode, ColaCloud, type ColaCloudConfig, ColaCloudError, type ColaDetail, type ColaImage, type ColaListParams, type ColaSummary, NetworkError, NotFoundError, type PaginatedIteratorOptions, type PaginatedIteratorResult, type PaginatedResponse, type Pagination, type PermitteeDetail, type PermitteeListParams, type PermitteeSummary, RateLimitError, type RateLimitInfo, type ResponseWithRateLimit, ServerError, type SingleResponse, TimeoutError, type UsageStats, ValidationError, collectAll, createPaginatedIterator, createPaginatedIteratorWithMetadata, take };
664
+ export { type ApiErrorResponse, AuthenticationError, type BarcodeLookupResult, type ColaBarcode, ColaCloud, type ColaCloudConfig, ColaCloudError, type ColaDetail, type ColaImage, type ColaListParams, type ColaSummary, NetworkError, NotFoundError, type PaginatedIteratorOptions, type PaginatedIteratorResult, type PaginatedResponse, type Pagination, type PermitteeDetail, type PermitteeListParams, type PermitteeSummary, type QuotaInfo, RateLimitError, type ResponseWithQuota, ServerError, type SingleResponse, TimeoutError, type UsageStats, ValidationError, collectAll, createPaginatedIterator, createPaginatedIteratorWithMetadata, take };
package/dist/index.js CHANGED
@@ -76,14 +76,14 @@ var AuthenticationError = class _AuthenticationError extends ColaCloudError {
76
76
  }
77
77
  };
78
78
  var RateLimitError = class _RateLimitError extends ColaCloudError {
79
- /** Rate limit information from headers */
80
- rateLimit;
79
+ /** Quota information from headers */
80
+ quota;
81
81
  /** Seconds until the rate limit resets */
82
82
  retryAfter;
83
- constructor(message = "Rate limit exceeded", rateLimit = null, retryAfter = null) {
83
+ constructor(message = "Rate limit exceeded", quota = null, retryAfter = null) {
84
84
  super(message, 429, "rate_limit_exceeded");
85
85
  this.name = "RateLimitError";
86
- this.rateLimit = rateLimit;
86
+ this.quota = quota;
87
87
  this.retryAfter = retryAfter;
88
88
  if (Error.captureStackTrace) {
89
89
  Error.captureStackTrace(this, _RateLimitError);
@@ -169,9 +169,15 @@ function createPaginatedIterator(options) {
169
169
  done = true;
170
170
  break;
171
171
  }
172
- if (pagination !== null && currentPage > pagination.pages) {
173
- done = true;
174
- break;
172
+ if (pagination !== null) {
173
+ if (pagination.has_more === false) {
174
+ done = true;
175
+ break;
176
+ }
177
+ if (pagination.pages !== null && currentPage > pagination.pages) {
178
+ done = true;
179
+ break;
180
+ }
175
181
  }
176
182
  const result = await fetchPage({
177
183
  ...params,
@@ -209,7 +215,7 @@ function createPaginatedIteratorWithMetadata(options) {
209
215
  let currentItems = [];
210
216
  let currentIndex = 0;
211
217
  let pagination = null;
212
- let rateLimit = null;
218
+ let quota = null;
213
219
  let pagesFetched = 0;
214
220
  let done = false;
215
221
  return {
@@ -219,16 +225,22 @@ function createPaginatedIteratorWithMetadata(options) {
219
225
  done = true;
220
226
  break;
221
227
  }
222
- if (pagination !== null && currentPage > pagination.pages) {
223
- done = true;
224
- break;
228
+ if (pagination !== null) {
229
+ if (pagination.has_more === false) {
230
+ done = true;
231
+ break;
232
+ }
233
+ if (pagination.pages !== null && currentPage > pagination.pages) {
234
+ done = true;
235
+ break;
236
+ }
225
237
  }
226
238
  const result = await fetchPage({
227
239
  ...params,
228
240
  page: currentPage
229
241
  });
230
242
  pagination = result.response.pagination;
231
- rateLimit = result.rateLimit;
243
+ quota = result.quota;
232
244
  currentItems = result.response.data;
233
245
  currentIndex = 0;
234
246
  currentPage++;
@@ -249,7 +261,7 @@ function createPaginatedIteratorWithMetadata(options) {
249
261
  // We already incremented after fetch
250
262
  indexInPage: currentIndex,
251
263
  total: pagination?.total ?? 0,
252
- rateLimit
264
+ quota
253
265
  };
254
266
  currentIndex++;
255
267
  return { done: false, value: result };
@@ -286,14 +298,20 @@ function toSnakeCase(params) {
286
298
  }
287
299
  return result;
288
300
  }
289
- function parseRateLimitHeaders(headers) {
290
- const limit = headers.get("X-RateLimit-Limit");
291
- const remaining = headers.get("X-RateLimit-Remaining");
292
- const reset = headers.get("X-RateLimit-Reset");
293
- if (limit === null || remaining === null || reset === null) {
294
- return null;
295
- }
301
+ function parseQuotaHeaders(headers) {
302
+ const reset = headers.get("X-Quota-Reset");
303
+ if (reset === null) return null;
304
+ let limit = headers.get("X-Detail-Views-Limit");
305
+ let remaining = headers.get("X-Detail-Views-Remaining");
306
+ let meter = "detail_views";
307
+ if (limit === null) {
308
+ limit = headers.get("X-List-Records-Limit");
309
+ remaining = headers.get("X-List-Records-Remaining");
310
+ meter = "list_records";
311
+ }
312
+ if (limit === null || remaining === null) return null;
296
313
  return {
314
+ meter,
297
315
  limit: parseInt(limit, 10),
298
316
  remaining: parseInt(remaining, 10),
299
317
  reset: parseInt(reset, 10)
@@ -350,12 +368,12 @@ var ColaCloud = class {
350
368
  signal: controller.signal
351
369
  });
352
370
  clearTimeout(timeoutId);
353
- const rateLimit = parseRateLimitHeaders(response.headers);
371
+ const quota = parseQuotaHeaders(response.headers);
354
372
  if (!response.ok) {
355
- await this.handleErrorResponse(response, rateLimit);
373
+ await this.handleErrorResponse(response, quota);
356
374
  }
357
375
  const data = await response.json();
358
- return { data, rateLimit };
376
+ return { data, quota };
359
377
  } catch (error) {
360
378
  clearTimeout(timeoutId);
361
379
  if (error instanceof Error && error.name === "AbortError") {
@@ -373,7 +391,7 @@ var ColaCloud = class {
373
391
  /**
374
392
  * Handle error responses from the API
375
393
  */
376
- async handleErrorResponse(response, rateLimit) {
394
+ async handleErrorResponse(response, quota) {
377
395
  let errorData;
378
396
  try {
379
397
  errorData = await response.json();
@@ -390,7 +408,7 @@ var ColaCloud = class {
390
408
  const retryAfter = response.headers.get("Retry-After");
391
409
  throw new RateLimitError(
392
410
  message,
393
- rateLimit,
411
+ quota,
394
412
  retryAfter ? parseInt(retryAfter, 10) : null
395
413
  );
396
414
  }
@@ -425,11 +443,11 @@ var ColasResource = class {
425
443
  return result.data;
426
444
  }
427
445
  /**
428
- * List COLAs with rate limit information
446
+ * List COLAs with quota information
429
447
  * @param params Search and filter parameters
430
- * @returns Paginated list with rate limit info
448
+ * @returns Paginated list with quota info
431
449
  */
432
- async listWithRateLimit(params = {}) {
450
+ async listWithQuota(params = {}) {
433
451
  return this.client.request(
434
452
  "GET",
435
453
  "/colas",
@@ -456,17 +474,17 @@ var ColasResource = class {
456
474
  }
457
475
  }
458
476
  /**
459
- * Get a single COLA with rate limit information
477
+ * Get a single COLA with quota information
460
478
  * @param ttbId The unique TTB identifier
461
- * @returns COLA details with rate limit info
479
+ * @returns COLA details with quota info
462
480
  */
463
- async getWithRateLimit(ttbId) {
481
+ async getWithQuota(ttbId) {
464
482
  try {
465
483
  const result = await this.client.request(
466
484
  "GET",
467
485
  `/colas/${encodeURIComponent(ttbId)}`
468
486
  );
469
- return { data: result.data.data, rateLimit: result.rateLimit };
487
+ return { data: result.data.data, quota: result.quota };
470
488
  } catch (error) {
471
489
  if (error instanceof NotFoundError) {
472
490
  throw new NotFoundError("COLA", ttbId);
@@ -495,7 +513,7 @@ var ColasResource = class {
495
513
  "/colas",
496
514
  p
497
515
  );
498
- return { response: result.data, rateLimit: result.rateLimit };
516
+ return { response: result.data, quota: result.quota };
499
517
  }
500
518
  });
501
519
  }
@@ -518,11 +536,11 @@ var PermitteesResource = class {
518
536
  return result.data;
519
537
  }
520
538
  /**
521
- * List permittees with rate limit information
539
+ * List permittees with quota information
522
540
  * @param params Search and filter parameters
523
- * @returns Paginated list with rate limit info
541
+ * @returns Paginated list with quota info
524
542
  */
525
- async listWithRateLimit(params = {}) {
543
+ async listWithQuota(params = {}) {
526
544
  return this.client.request(
527
545
  "GET",
528
546
  "/permittees",
@@ -549,17 +567,17 @@ var PermitteesResource = class {
549
567
  }
550
568
  }
551
569
  /**
552
- * Get a single permittee with rate limit information
570
+ * Get a single permittee with quota information
553
571
  * @param permitNumber The unique permit number
554
- * @returns Permittee details with rate limit info
572
+ * @returns Permittee details with quota info
555
573
  */
556
- async getWithRateLimit(permitNumber) {
574
+ async getWithQuota(permitNumber) {
557
575
  try {
558
576
  const result = await this.client.request(
559
577
  "GET",
560
578
  `/permittees/${encodeURIComponent(permitNumber)}`
561
579
  );
562
- return { data: result.data.data, rateLimit: result.rateLimit };
580
+ return { data: result.data.data, quota: result.quota };
563
581
  } catch (error) {
564
582
  if (error instanceof NotFoundError) {
565
583
  throw new NotFoundError("Permittee", permitNumber);
@@ -584,7 +602,7 @@ var PermitteesResource = class {
584
602
  params,
585
603
  fetchPage: async (p) => {
586
604
  const result = await this.client.request("GET", "/permittees", p);
587
- return { response: result.data, rateLimit: result.rateLimit };
605
+ return { response: result.data, quota: result.quota };
588
606
  }
589
607
  });
590
608
  }
@@ -610,14 +628,14 @@ var BarcodesResource = class {
610
628
  }
611
629
  }
612
630
  /**
613
- * Look up barcode with rate limit information
631
+ * Look up barcode with quota information
614
632
  * @param barcodeValue The barcode to search for
615
- * @returns Barcode lookup result with rate limit info
633
+ * @returns Barcode lookup result with quota info
616
634
  */
617
- async lookupWithRateLimit(barcodeValue) {
635
+ async lookupWithQuota(barcodeValue) {
618
636
  try {
619
637
  const result = await this.client.request("GET", `/barcode/${encodeURIComponent(barcodeValue)}`);
620
- return { data: result.data.data, rateLimit: result.rateLimit };
638
+ return { data: result.data.data, quota: result.quota };
621
639
  } catch (error) {
622
640
  if (error instanceof NotFoundError) {
623
641
  throw new NotFoundError("Barcode", barcodeValue);
@@ -642,15 +660,15 @@ var UsageResource = class {
642
660
  return result.data.data;
643
661
  }
644
662
  /**
645
- * Get usage statistics with rate limit information
646
- * @returns Usage statistics with rate limit info
663
+ * Get usage statistics with quota information
664
+ * @returns Usage statistics with quota info
647
665
  */
648
- async getWithRateLimit() {
666
+ async getWithQuota() {
649
667
  const result = await this.client.request(
650
668
  "GET",
651
669
  "/usage"
652
670
  );
653
- return { data: result.data.data, rateLimit: result.rateLimit };
671
+ return { data: result.data.data, quota: result.quota };
654
672
  }
655
673
  };
656
674
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -38,14 +38,14 @@ var AuthenticationError = class _AuthenticationError extends ColaCloudError {
38
38
  }
39
39
  };
40
40
  var RateLimitError = class _RateLimitError extends ColaCloudError {
41
- /** Rate limit information from headers */
42
- rateLimit;
41
+ /** Quota information from headers */
42
+ quota;
43
43
  /** Seconds until the rate limit resets */
44
44
  retryAfter;
45
- constructor(message = "Rate limit exceeded", rateLimit = null, retryAfter = null) {
45
+ constructor(message = "Rate limit exceeded", quota = null, retryAfter = null) {
46
46
  super(message, 429, "rate_limit_exceeded");
47
47
  this.name = "RateLimitError";
48
- this.rateLimit = rateLimit;
48
+ this.quota = quota;
49
49
  this.retryAfter = retryAfter;
50
50
  if (Error.captureStackTrace) {
51
51
  Error.captureStackTrace(this, _RateLimitError);
@@ -131,9 +131,15 @@ function createPaginatedIterator(options) {
131
131
  done = true;
132
132
  break;
133
133
  }
134
- if (pagination !== null && currentPage > pagination.pages) {
135
- done = true;
136
- break;
134
+ if (pagination !== null) {
135
+ if (pagination.has_more === false) {
136
+ done = true;
137
+ break;
138
+ }
139
+ if (pagination.pages !== null && currentPage > pagination.pages) {
140
+ done = true;
141
+ break;
142
+ }
137
143
  }
138
144
  const result = await fetchPage({
139
145
  ...params,
@@ -171,7 +177,7 @@ function createPaginatedIteratorWithMetadata(options) {
171
177
  let currentItems = [];
172
178
  let currentIndex = 0;
173
179
  let pagination = null;
174
- let rateLimit = null;
180
+ let quota = null;
175
181
  let pagesFetched = 0;
176
182
  let done = false;
177
183
  return {
@@ -181,16 +187,22 @@ function createPaginatedIteratorWithMetadata(options) {
181
187
  done = true;
182
188
  break;
183
189
  }
184
- if (pagination !== null && currentPage > pagination.pages) {
185
- done = true;
186
- break;
190
+ if (pagination !== null) {
191
+ if (pagination.has_more === false) {
192
+ done = true;
193
+ break;
194
+ }
195
+ if (pagination.pages !== null && currentPage > pagination.pages) {
196
+ done = true;
197
+ break;
198
+ }
187
199
  }
188
200
  const result = await fetchPage({
189
201
  ...params,
190
202
  page: currentPage
191
203
  });
192
204
  pagination = result.response.pagination;
193
- rateLimit = result.rateLimit;
205
+ quota = result.quota;
194
206
  currentItems = result.response.data;
195
207
  currentIndex = 0;
196
208
  currentPage++;
@@ -211,7 +223,7 @@ function createPaginatedIteratorWithMetadata(options) {
211
223
  // We already incremented after fetch
212
224
  indexInPage: currentIndex,
213
225
  total: pagination?.total ?? 0,
214
- rateLimit
226
+ quota
215
227
  };
216
228
  currentIndex++;
217
229
  return { done: false, value: result };
@@ -248,14 +260,20 @@ function toSnakeCase(params) {
248
260
  }
249
261
  return result;
250
262
  }
251
- function parseRateLimitHeaders(headers) {
252
- const limit = headers.get("X-RateLimit-Limit");
253
- const remaining = headers.get("X-RateLimit-Remaining");
254
- const reset = headers.get("X-RateLimit-Reset");
255
- if (limit === null || remaining === null || reset === null) {
256
- return null;
257
- }
263
+ function parseQuotaHeaders(headers) {
264
+ const reset = headers.get("X-Quota-Reset");
265
+ if (reset === null) return null;
266
+ let limit = headers.get("X-Detail-Views-Limit");
267
+ let remaining = headers.get("X-Detail-Views-Remaining");
268
+ let meter = "detail_views";
269
+ if (limit === null) {
270
+ limit = headers.get("X-List-Records-Limit");
271
+ remaining = headers.get("X-List-Records-Remaining");
272
+ meter = "list_records";
273
+ }
274
+ if (limit === null || remaining === null) return null;
258
275
  return {
276
+ meter,
259
277
  limit: parseInt(limit, 10),
260
278
  remaining: parseInt(remaining, 10),
261
279
  reset: parseInt(reset, 10)
@@ -312,12 +330,12 @@ var ColaCloud = class {
312
330
  signal: controller.signal
313
331
  });
314
332
  clearTimeout(timeoutId);
315
- const rateLimit = parseRateLimitHeaders(response.headers);
333
+ const quota = parseQuotaHeaders(response.headers);
316
334
  if (!response.ok) {
317
- await this.handleErrorResponse(response, rateLimit);
335
+ await this.handleErrorResponse(response, quota);
318
336
  }
319
337
  const data = await response.json();
320
- return { data, rateLimit };
338
+ return { data, quota };
321
339
  } catch (error) {
322
340
  clearTimeout(timeoutId);
323
341
  if (error instanceof Error && error.name === "AbortError") {
@@ -335,7 +353,7 @@ var ColaCloud = class {
335
353
  /**
336
354
  * Handle error responses from the API
337
355
  */
338
- async handleErrorResponse(response, rateLimit) {
356
+ async handleErrorResponse(response, quota) {
339
357
  let errorData;
340
358
  try {
341
359
  errorData = await response.json();
@@ -352,7 +370,7 @@ var ColaCloud = class {
352
370
  const retryAfter = response.headers.get("Retry-After");
353
371
  throw new RateLimitError(
354
372
  message,
355
- rateLimit,
373
+ quota,
356
374
  retryAfter ? parseInt(retryAfter, 10) : null
357
375
  );
358
376
  }
@@ -387,11 +405,11 @@ var ColasResource = class {
387
405
  return result.data;
388
406
  }
389
407
  /**
390
- * List COLAs with rate limit information
408
+ * List COLAs with quota information
391
409
  * @param params Search and filter parameters
392
- * @returns Paginated list with rate limit info
410
+ * @returns Paginated list with quota info
393
411
  */
394
- async listWithRateLimit(params = {}) {
412
+ async listWithQuota(params = {}) {
395
413
  return this.client.request(
396
414
  "GET",
397
415
  "/colas",
@@ -418,17 +436,17 @@ var ColasResource = class {
418
436
  }
419
437
  }
420
438
  /**
421
- * Get a single COLA with rate limit information
439
+ * Get a single COLA with quota information
422
440
  * @param ttbId The unique TTB identifier
423
- * @returns COLA details with rate limit info
441
+ * @returns COLA details with quota info
424
442
  */
425
- async getWithRateLimit(ttbId) {
443
+ async getWithQuota(ttbId) {
426
444
  try {
427
445
  const result = await this.client.request(
428
446
  "GET",
429
447
  `/colas/${encodeURIComponent(ttbId)}`
430
448
  );
431
- return { data: result.data.data, rateLimit: result.rateLimit };
449
+ return { data: result.data.data, quota: result.quota };
432
450
  } catch (error) {
433
451
  if (error instanceof NotFoundError) {
434
452
  throw new NotFoundError("COLA", ttbId);
@@ -457,7 +475,7 @@ var ColasResource = class {
457
475
  "/colas",
458
476
  p
459
477
  );
460
- return { response: result.data, rateLimit: result.rateLimit };
478
+ return { response: result.data, quota: result.quota };
461
479
  }
462
480
  });
463
481
  }
@@ -480,11 +498,11 @@ var PermitteesResource = class {
480
498
  return result.data;
481
499
  }
482
500
  /**
483
- * List permittees with rate limit information
501
+ * List permittees with quota information
484
502
  * @param params Search and filter parameters
485
- * @returns Paginated list with rate limit info
503
+ * @returns Paginated list with quota info
486
504
  */
487
- async listWithRateLimit(params = {}) {
505
+ async listWithQuota(params = {}) {
488
506
  return this.client.request(
489
507
  "GET",
490
508
  "/permittees",
@@ -511,17 +529,17 @@ var PermitteesResource = class {
511
529
  }
512
530
  }
513
531
  /**
514
- * Get a single permittee with rate limit information
532
+ * Get a single permittee with quota information
515
533
  * @param permitNumber The unique permit number
516
- * @returns Permittee details with rate limit info
534
+ * @returns Permittee details with quota info
517
535
  */
518
- async getWithRateLimit(permitNumber) {
536
+ async getWithQuota(permitNumber) {
519
537
  try {
520
538
  const result = await this.client.request(
521
539
  "GET",
522
540
  `/permittees/${encodeURIComponent(permitNumber)}`
523
541
  );
524
- return { data: result.data.data, rateLimit: result.rateLimit };
542
+ return { data: result.data.data, quota: result.quota };
525
543
  } catch (error) {
526
544
  if (error instanceof NotFoundError) {
527
545
  throw new NotFoundError("Permittee", permitNumber);
@@ -546,7 +564,7 @@ var PermitteesResource = class {
546
564
  params,
547
565
  fetchPage: async (p) => {
548
566
  const result = await this.client.request("GET", "/permittees", p);
549
- return { response: result.data, rateLimit: result.rateLimit };
567
+ return { response: result.data, quota: result.quota };
550
568
  }
551
569
  });
552
570
  }
@@ -572,14 +590,14 @@ var BarcodesResource = class {
572
590
  }
573
591
  }
574
592
  /**
575
- * Look up barcode with rate limit information
593
+ * Look up barcode with quota information
576
594
  * @param barcodeValue The barcode to search for
577
- * @returns Barcode lookup result with rate limit info
595
+ * @returns Barcode lookup result with quota info
578
596
  */
579
- async lookupWithRateLimit(barcodeValue) {
597
+ async lookupWithQuota(barcodeValue) {
580
598
  try {
581
599
  const result = await this.client.request("GET", `/barcode/${encodeURIComponent(barcodeValue)}`);
582
- return { data: result.data.data, rateLimit: result.rateLimit };
600
+ return { data: result.data.data, quota: result.quota };
583
601
  } catch (error) {
584
602
  if (error instanceof NotFoundError) {
585
603
  throw new NotFoundError("Barcode", barcodeValue);
@@ -604,15 +622,15 @@ var UsageResource = class {
604
622
  return result.data.data;
605
623
  }
606
624
  /**
607
- * Get usage statistics with rate limit information
608
- * @returns Usage statistics with rate limit info
625
+ * Get usage statistics with quota information
626
+ * @returns Usage statistics with quota info
609
627
  */
610
- async getWithRateLimit() {
628
+ async getWithQuota() {
611
629
  const result = await this.client.request(
612
630
  "GET",
613
631
  "/usage"
614
632
  );
615
- return { data: result.data.data, rateLimit: result.rateLimit };
633
+ return { data: result.data.data, quota: result.quota };
616
634
  }
617
635
  };
618
636
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colacloud",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Official JavaScript/TypeScript SDK for the COLA Cloud API - access the TTB COLA Registry of alcohol product label approvals",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",