axusage 3.7.0 → 3.8.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.
@@ -1,5 +1,5 @@
1
- import type { ServiceUsageData } from "../types/domain.js";
2
- import type { CodexUsageResponse, CodexRateLimitWindow } from "../types/codex.js";
1
+ import type { UsageWindow, ServiceUsageData } from "../types/domain.js";
2
+ import type { CodexUsageResponse, CodexRateLimitWindow, CodexAdditionalRateLimit } from "../types/codex.js";
3
3
  /**
4
4
  * Converts a ChatGPT rate limit window to common usage window
5
5
  */
@@ -9,6 +9,10 @@ export declare function toUsageWindow(name: string, window: CodexRateLimitWindow
9
9
  resetsAt: Date;
10
10
  periodDurationMs: number;
11
11
  };
12
+ /**
13
+ * Converts an additional rate limit entry to usage windows
14
+ */
15
+ export declare function toAdditionalWindows(limit: CodexAdditionalRateLimit): readonly UsageWindow[];
12
16
  /**
13
17
  * Converts ChatGPT response to common domain model
14
18
  */
@@ -9,18 +9,47 @@ export function toUsageWindow(name, window) {
9
9
  periodDurationMs: window.limit_window_seconds * 1000,
10
10
  };
11
11
  }
12
+ /**
13
+ * Formats a human-readable label from the limit_name or metered_feature
14
+ */
15
+ function formatAdditionalLimitLabel(limit) {
16
+ return limit.limit_name || limit.metered_feature;
17
+ }
18
+ /**
19
+ * Converts an additional rate limit entry to usage windows
20
+ */
21
+ export function toAdditionalWindows(limit) {
22
+ const label = formatAdditionalLimitLabel(limit);
23
+ const rateLimit = limit.rate_limit;
24
+ if (!rateLimit)
25
+ return [];
26
+ const windows = [];
27
+ if (rateLimit.primary_window) {
28
+ windows.push(toUsageWindow(`${label} (primary)`, rateLimit.primary_window));
29
+ }
30
+ if (rateLimit.secondary_window) {
31
+ windows.push(toUsageWindow(`${label} (secondary)`, rateLimit.secondary_window));
32
+ }
33
+ return windows;
34
+ }
12
35
  /**
13
36
  * Converts ChatGPT response to common domain model
14
37
  */
15
38
  export function toServiceUsageData(response) {
39
+ const windows = [
40
+ toUsageWindow("Primary Window (~5 hours)", response.rate_limit.primary_window),
41
+ toUsageWindow("Secondary Window (~7 days)", response.rate_limit.secondary_window),
42
+ ];
43
+ if (response.additional_rate_limits) {
44
+ for (const limit of response.additional_rate_limits) {
45
+ windows.push(...toAdditionalWindows(limit));
46
+ }
47
+ }
16
48
  return {
17
49
  service: "ChatGPT",
18
50
  serviceType: "codex",
19
51
  planType: response.plan_type,
20
- windows: [
21
- toUsageWindow("Primary Window (~5 hours)", response.rate_limit.primary_window),
22
- toUsageWindow("Secondary Window (~7 days)", response.rate_limit.secondary_window),
23
- ],
52
+ windows,
24
53
  metadata: {
25
54
  allowed: response.rate_limit.allowed,
26
55
  limitReached: response.rate_limit.limit_reached,
@@ -104,7 +104,7 @@ export function groupByQuotaPool(modelQuotas) {
104
104
  }
105
105
  // Sort model IDs within each pool for consistent ordering
106
106
  for (const pool of poolMap.values()) {
107
- pool.modelIds.sort();
107
+ pool.modelIds = pool.modelIds.toSorted();
108
108
  }
109
109
  return [...poolMap.values()];
110
110
  }
@@ -9,6 +9,27 @@ export declare const CodexRateLimitWindow: z.ZodObject<{
9
9
  reset_at: z.ZodNumber;
10
10
  }, z.core.$strip>;
11
11
  export type CodexRateLimitWindow = z.infer<typeof CodexRateLimitWindow>;
12
+ declare const CodexAdditionalRateLimit: z.ZodObject<{
13
+ limit_name: z.ZodString;
14
+ metered_feature: z.ZodString;
15
+ rate_limit: z.ZodOptional<z.ZodNullable<z.ZodObject<{
16
+ allowed: z.ZodBoolean;
17
+ limit_reached: z.ZodBoolean;
18
+ primary_window: z.ZodOptional<z.ZodObject<{
19
+ used_percent: z.ZodNumber;
20
+ limit_window_seconds: z.ZodNumber;
21
+ reset_after_seconds: z.ZodNumber;
22
+ reset_at: z.ZodNumber;
23
+ }, z.core.$strip>>;
24
+ secondary_window: z.ZodOptional<z.ZodObject<{
25
+ used_percent: z.ZodNumber;
26
+ limit_window_seconds: z.ZodNumber;
27
+ reset_after_seconds: z.ZodNumber;
28
+ reset_at: z.ZodNumber;
29
+ }, z.core.$strip>>;
30
+ }, z.core.$strip>>>;
31
+ }, z.core.$strip>;
32
+ export type CodexAdditionalRateLimit = z.infer<typeof CodexAdditionalRateLimit>;
12
33
  export declare const CodexUsageResponse: z.ZodObject<{
13
34
  plan_type: z.ZodString;
14
35
  rate_limit: z.ZodObject<{
@@ -28,5 +49,26 @@ export declare const CodexUsageResponse: z.ZodObject<{
28
49
  }, z.core.$strip>;
29
50
  }, z.core.$strip>;
30
51
  credits: z.ZodNullable<z.ZodUnknown>;
52
+ additional_rate_limits: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
53
+ limit_name: z.ZodString;
54
+ metered_feature: z.ZodString;
55
+ rate_limit: z.ZodOptional<z.ZodNullable<z.ZodObject<{
56
+ allowed: z.ZodBoolean;
57
+ limit_reached: z.ZodBoolean;
58
+ primary_window: z.ZodOptional<z.ZodObject<{
59
+ used_percent: z.ZodNumber;
60
+ limit_window_seconds: z.ZodNumber;
61
+ reset_after_seconds: z.ZodNumber;
62
+ reset_at: z.ZodNumber;
63
+ }, z.core.$strip>>;
64
+ secondary_window: z.ZodOptional<z.ZodObject<{
65
+ used_percent: z.ZodNumber;
66
+ limit_window_seconds: z.ZodNumber;
67
+ reset_after_seconds: z.ZodNumber;
68
+ reset_at: z.ZodNumber;
69
+ }, z.core.$strip>>;
70
+ }, z.core.$strip>>>;
71
+ }, z.core.$strip>>>>;
31
72
  }, z.core.$strip>;
32
73
  export type CodexUsageResponse = z.infer<typeof CodexUsageResponse>;
74
+ export {};
@@ -14,8 +14,25 @@ const CodexRateLimit = z.object({
14
14
  primary_window: CodexRateLimitWindow,
15
15
  secondary_window: CodexRateLimitWindow,
16
16
  });
17
+ const CodexAdditionalRateLimit = z.object({
18
+ limit_name: z.string(),
19
+ metered_feature: z.string(),
20
+ rate_limit: z
21
+ .object({
22
+ allowed: z.boolean(),
23
+ limit_reached: z.boolean(),
24
+ primary_window: CodexRateLimitWindow.optional(),
25
+ secondary_window: CodexRateLimitWindow.optional(),
26
+ })
27
+ .nullable()
28
+ .optional(),
29
+ });
17
30
  export const CodexUsageResponse = z.object({
18
31
  plan_type: z.string(),
19
32
  rate_limit: CodexRateLimit,
20
33
  credits: z.unknown().nullable(),
34
+ additional_rate_limits: z
35
+ .array(CodexAdditionalRateLimit)
36
+ .nullable()
37
+ .optional(),
21
38
  });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "axusage",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "3.7.0",
5
+ "version": "3.8.0",
6
6
  "description": "Monitor API usage across Claude, ChatGPT, GitHub Copilot, and Gemini from a single CLI",
7
7
  "repository": {
8
8
  "type": "git",