axusage 3.8.1 → 3.8.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.
Files changed (174) hide show
  1. package/README.md +19 -8
  2. package/dist/adapters/claude.d.ts +1 -0
  3. package/dist/adapters/claude.d.ts.map +1 -0
  4. package/dist/adapters/claude.js +1 -0
  5. package/dist/adapters/claude.js.map +1 -0
  6. package/dist/adapters/coalesce-claude-usage-response.d.ts +1 -0
  7. package/dist/adapters/coalesce-claude-usage-response.d.ts.map +1 -0
  8. package/dist/adapters/coalesce-claude-usage-response.js +1 -0
  9. package/dist/adapters/coalesce-claude-usage-response.js.map +1 -0
  10. package/dist/adapters/codex.d.ts +1 -0
  11. package/dist/adapters/codex.d.ts.map +1 -0
  12. package/dist/adapters/codex.js +1 -0
  13. package/dist/adapters/codex.js.map +1 -0
  14. package/dist/adapters/copilot.d.ts +1 -0
  15. package/dist/adapters/copilot.d.ts.map +1 -0
  16. package/dist/adapters/copilot.js +1 -0
  17. package/dist/adapters/copilot.js.map +1 -0
  18. package/dist/adapters/gemini.d.ts +1 -0
  19. package/dist/adapters/gemini.d.ts.map +1 -0
  20. package/dist/adapters/gemini.js +1 -0
  21. package/dist/adapters/gemini.js.map +1 -0
  22. package/dist/adapters/parse-claude-usage.d.ts +1 -0
  23. package/dist/adapters/parse-claude-usage.d.ts.map +1 -0
  24. package/dist/adapters/parse-claude-usage.js +1 -0
  25. package/dist/adapters/parse-claude-usage.js.map +1 -0
  26. package/dist/adapters/parse-codex-usage.d.ts +1 -0
  27. package/dist/adapters/parse-codex-usage.d.ts.map +1 -0
  28. package/dist/adapters/parse-codex-usage.js +1 -0
  29. package/dist/adapters/parse-codex-usage.js.map +1 -0
  30. package/dist/adapters/parse-copilot-usage.d.ts +1 -0
  31. package/dist/adapters/parse-copilot-usage.d.ts.map +1 -0
  32. package/dist/adapters/parse-copilot-usage.js +1 -0
  33. package/dist/adapters/parse-copilot-usage.js.map +1 -0
  34. package/dist/adapters/parse-gemini-usage.d.ts +1 -0
  35. package/dist/adapters/parse-gemini-usage.d.ts.map +1 -0
  36. package/dist/adapters/parse-gemini-usage.js +1 -0
  37. package/dist/adapters/parse-gemini-usage.js.map +1 -0
  38. package/dist/cli.d.ts +1 -0
  39. package/dist/cli.d.ts.map +1 -0
  40. package/dist/cli.js +3 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/commands/auth-setup-command.d.ts +1 -0
  43. package/dist/commands/auth-setup-command.d.ts.map +1 -0
  44. package/dist/commands/auth-setup-command.js +1 -0
  45. package/dist/commands/auth-setup-command.js.map +1 -0
  46. package/dist/commands/auth-status-command.d.ts +1 -0
  47. package/dist/commands/auth-status-command.d.ts.map +1 -0
  48. package/dist/commands/auth-status-command.js +1 -0
  49. package/dist/commands/auth-status-command.js.map +1 -0
  50. package/dist/commands/fetch-service-usage.d.ts +5 -3
  51. package/dist/commands/fetch-service-usage.d.ts.map +1 -0
  52. package/dist/commands/fetch-service-usage.js +14 -27
  53. package/dist/commands/fetch-service-usage.js.map +1 -0
  54. package/dist/commands/run-auth-setup.d.ts +1 -0
  55. package/dist/commands/run-auth-setup.d.ts.map +1 -0
  56. package/dist/commands/run-auth-setup.js +1 -0
  57. package/dist/commands/run-auth-setup.js.map +1 -0
  58. package/dist/commands/serve-command.d.ts +2 -19
  59. package/dist/commands/serve-command.d.ts.map +1 -0
  60. package/dist/commands/serve-command.js +43 -104
  61. package/dist/commands/serve-command.js.map +1 -0
  62. package/dist/commands/usage-command.d.ts +3 -1
  63. package/dist/commands/usage-command.d.ts.map +1 -0
  64. package/dist/commands/usage-command.js +5 -0
  65. package/dist/commands/usage-command.js.map +1 -0
  66. package/dist/config/credential-sources.d.ts +1 -0
  67. package/dist/config/credential-sources.d.ts.map +1 -0
  68. package/dist/config/credential-sources.js +2 -0
  69. package/dist/config/credential-sources.js.map +1 -0
  70. package/dist/config/serve-config.d.ts +16 -0
  71. package/dist/config/serve-config.d.ts.map +1 -0
  72. package/dist/config/serve-config.js +58 -18
  73. package/dist/config/serve-config.js.map +1 -0
  74. package/dist/server/routes.d.ts +15 -8
  75. package/dist/server/routes.d.ts.map +1 -0
  76. package/dist/server/routes.js +112 -60
  77. package/dist/server/routes.js.map +1 -0
  78. package/dist/server/serve-logger.d.ts +5 -0
  79. package/dist/server/serve-logger.d.ts.map +1 -0
  80. package/dist/server/serve-logger.js +88 -0
  81. package/dist/server/serve-logger.js.map +1 -0
  82. package/dist/server/server.d.ts +15 -7
  83. package/dist/server/server.d.ts.map +1 -0
  84. package/dist/server/server.js +91 -56
  85. package/dist/server/server.js.map +1 -0
  86. package/dist/server/usage-cache.d.ts +26 -0
  87. package/dist/server/usage-cache.d.ts.map +1 -0
  88. package/dist/server/usage-cache.js +77 -0
  89. package/dist/server/usage-cache.js.map +1 -0
  90. package/dist/services/gemini-api.d.ts +1 -0
  91. package/dist/services/gemini-api.d.ts.map +1 -0
  92. package/dist/services/gemini-api.js +1 -0
  93. package/dist/services/gemini-api.js.map +1 -0
  94. package/dist/services/get-instance-access-token.d.ts +3 -1
  95. package/dist/services/get-instance-access-token.d.ts.map +1 -0
  96. package/dist/services/get-instance-access-token.js +1 -0
  97. package/dist/services/get-instance-access-token.js.map +1 -0
  98. package/dist/services/resolve-service-instances.d.ts +1 -0
  99. package/dist/services/resolve-service-instances.d.ts.map +1 -0
  100. package/dist/services/resolve-service-instances.js +1 -0
  101. package/dist/services/resolve-service-instances.js.map +1 -0
  102. package/dist/services/service-adapter-registry.d.ts +4 -2
  103. package/dist/services/service-adapter-registry.d.ts.map +1 -0
  104. package/dist/services/service-adapter-registry.js +4 -3
  105. package/dist/services/service-adapter-registry.js.map +1 -0
  106. package/dist/services/service-diagnostics.d.ts +1 -0
  107. package/dist/services/service-diagnostics.d.ts.map +1 -0
  108. package/dist/services/service-diagnostics.js +1 -0
  109. package/dist/services/service-diagnostics.js.map +1 -0
  110. package/dist/services/supported-service.d.ts +1 -0
  111. package/dist/services/supported-service.d.ts.map +1 -0
  112. package/dist/services/supported-service.js +6 -1
  113. package/dist/services/supported-service.js.map +1 -0
  114. package/dist/types/codex.d.ts +1 -0
  115. package/dist/types/codex.d.ts.map +1 -0
  116. package/dist/types/codex.js +1 -0
  117. package/dist/types/codex.js.map +1 -0
  118. package/dist/types/copilot.d.ts +1 -0
  119. package/dist/types/copilot.d.ts.map +1 -0
  120. package/dist/types/copilot.js +1 -0
  121. package/dist/types/copilot.js.map +1 -0
  122. package/dist/types/domain.d.ts +1 -0
  123. package/dist/types/domain.d.ts.map +1 -0
  124. package/dist/types/domain.js +1 -0
  125. package/dist/types/domain.js.map +1 -0
  126. package/dist/types/gemini.d.ts +1 -0
  127. package/dist/types/gemini.d.ts.map +1 -0
  128. package/dist/types/gemini.js +1 -0
  129. package/dist/types/gemini.js.map +1 -0
  130. package/dist/types/serve-api.d.ts +53 -0
  131. package/dist/types/serve-api.d.ts.map +1 -0
  132. package/dist/types/serve-api.js +34 -0
  133. package/dist/types/serve-api.js.map +1 -0
  134. package/dist/types/usage.d.ts +1 -0
  135. package/dist/types/usage.d.ts.map +1 -0
  136. package/dist/types/usage.js +1 -0
  137. package/dist/types/usage.js.map +1 -0
  138. package/dist/utils/calculate-usage-rate.d.ts +1 -0
  139. package/dist/utils/calculate-usage-rate.d.ts.map +1 -0
  140. package/dist/utils/calculate-usage-rate.js +1 -0
  141. package/dist/utils/calculate-usage-rate.js.map +1 -0
  142. package/dist/utils/check-cli-dependency.d.ts +1 -0
  143. package/dist/utils/check-cli-dependency.d.ts.map +1 -0
  144. package/dist/utils/check-cli-dependency.js +1 -0
  145. package/dist/utils/check-cli-dependency.js.map +1 -0
  146. package/dist/utils/classify-usage-rate.d.ts +1 -0
  147. package/dist/utils/classify-usage-rate.d.ts.map +1 -0
  148. package/dist/utils/classify-usage-rate.js +1 -0
  149. package/dist/utils/classify-usage-rate.js.map +1 -0
  150. package/dist/utils/color.d.ts +1 -0
  151. package/dist/utils/color.d.ts.map +1 -0
  152. package/dist/utils/color.js +1 -0
  153. package/dist/utils/color.js.map +1 -0
  154. package/dist/utils/copilot-gh-token.d.ts +1 -0
  155. package/dist/utils/copilot-gh-token.d.ts.map +1 -0
  156. package/dist/utils/copilot-gh-token.js +1 -0
  157. package/dist/utils/copilot-gh-token.js.map +1 -0
  158. package/dist/utils/format-prometheus-metrics.d.ts +1 -0
  159. package/dist/utils/format-prometheus-metrics.d.ts.map +1 -0
  160. package/dist/utils/format-prometheus-metrics.js +9 -2
  161. package/dist/utils/format-prometheus-metrics.js.map +1 -0
  162. package/dist/utils/format-requires-help-text.d.ts +1 -0
  163. package/dist/utils/format-requires-help-text.d.ts.map +1 -0
  164. package/dist/utils/format-requires-help-text.js +1 -0
  165. package/dist/utils/format-requires-help-text.js.map +1 -0
  166. package/dist/utils/format-service-usage.d.ts +3 -1
  167. package/dist/utils/format-service-usage.d.ts.map +1 -0
  168. package/dist/utils/format-service-usage.js +3 -2
  169. package/dist/utils/format-service-usage.js.map +1 -0
  170. package/dist/utils/validate-root-options.d.ts +1 -0
  171. package/dist/utils/validate-root-options.d.ts.map +1 -0
  172. package/dist/utils/validate-root-options.js +1 -0
  173. package/dist/utils/validate-root-options.js.map +1 -0
  174. package/package.json +16 -13
@@ -1,122 +1,61 @@
1
1
  /**
2
2
  * Serve command handler — starts an HTTP server exposing usage data.
3
3
  */
4
+ import closeWithGrace from "close-with-grace";
4
5
  import { getServeConfig } from "../config/serve-config.js";
5
6
  import { selectServicesToQuery } from "./fetch-service-usage.js";
6
7
  import { fetchServicesInParallel } from "./usage-command.js";
8
+ import { createDeferredServeLogger } from "../server/serve-logger.js";
7
9
  import { createServer } from "../server/server.js";
8
- import { createHealthRouter, createMetricsRouter, createUsageRouter, } from "../server/routes.js";
9
- import { getAvailableServices } from "../services/service-adapter-registry.js";
10
- /**
11
- * Creates an on-demand usage cache. Data is fetched via `doFetch` when a
12
- * caller requests fresh state and the cached snapshot is older than `intervalMs`.
13
- * Concurrent callers during a refresh all receive the same in-flight promise.
14
- * When all services fail, the cache retries after a short backoff (≤5s) rather
15
- * than waiting the full interval.
16
- */
17
- export function createUsageCache(doFetch, intervalMs) {
18
- let state;
19
- let refreshPromise;
20
- async function doRefresh() {
21
- const results = await doFetch();
22
- const usage = [];
23
- const errors = [];
24
- for (const { service, result } of results) {
25
- if (result.ok) {
26
- usage.push(result.value);
27
- }
28
- else {
29
- const statusSuffix = result.error.status === undefined
30
- ? ""
31
- : ` (HTTP ${String(result.error.status)})`;
32
- errors.push(`${service}: fetch failed${statusSuffix}`);
33
- console.error(`Warning: Failed to fetch ${service}: ${result.error.message}`);
34
- }
35
- }
36
- state = { usage, refreshedAt: new Date(), errors };
37
- }
38
- function ensureFresh() {
39
- const age = state === undefined ? Infinity : Date.now() - state.refreshedAt.getTime();
40
- // If the last refresh produced no data (all services failed), retry on a
41
- // short backoff so the server recovers promptly after transient failures
42
- // rather than waiting the full cache interval.
43
- const hasData = state !== undefined && state.usage.length > 0;
44
- const maxAge = hasData ? intervalMs : Math.min(intervalMs, 5000);
45
- if (age < maxAge)
46
- return Promise.resolve();
47
- refreshPromise ??= doRefresh().finally(() => {
48
- refreshPromise = undefined;
49
- });
50
- return refreshPromise;
51
- }
52
- return {
53
- getState: () => state,
54
- getFreshState: async () => {
55
- await ensureFresh();
56
- return state;
57
- },
58
- getStateStaleWhileRevalidate: async () => {
59
- if (state === undefined) {
60
- // No snapshot yet — block until we have something to serve.
61
- await ensureFresh();
62
- }
63
- else {
64
- // Serve the current snapshot immediately; kick off a background
65
- // refresh if stale. Errors are logged; callers are not affected.
66
- void ensureFresh().catch((error) => {
67
- console.error("Background metrics refresh failed:", error);
68
- });
69
- }
70
- return state;
71
- },
72
- };
73
- }
10
+ import { createHealthPlugin, createMetricsPlugin, createUsagePlugin, } from "../server/routes.js";
11
+ import { createUsageCache } from "../server/usage-cache.js";
74
12
  export async function serveCommand(options) {
75
13
  const config = getServeConfig(options);
76
- const availableServices = getAvailableServices();
77
- if (config.service !== undefined &&
78
- config.service.toLowerCase() !== "all" &&
79
- !availableServices.includes(config.service.toLowerCase())) {
80
- console.error(`Unknown service "${config.service}". Supported: ${availableServices.join(", ")}.`);
81
- if (process.exitCode === undefined)
82
- process.exitCode = 1;
83
- return;
84
- }
85
14
  const servicesToQuery = selectServicesToQuery(config.service);
86
- const cache = createUsageCache(() => fetchServicesInParallel(servicesToQuery), config.intervalMs);
15
+ const serverReference = { current: undefined };
16
+ const logger = createDeferredServeLogger(() => serverReference.current?.app.log);
17
+ let shuttingDown = false;
18
+ const cache = createUsageCache(() => fetchServicesInParallel(servicesToQuery), config.intervalMs, logger);
87
19
  const server = createServer(config, [
88
- createHealthRouter(servicesToQuery, cache.getState),
89
- createMetricsRouter(cache.getStateStaleWhileRevalidate),
90
- createUsageRouter(cache.getFreshState),
20
+ createHealthPlugin(servicesToQuery, cache.getState, () => shuttingDown),
21
+ createMetricsPlugin(cache.getStateStaleWhileRevalidate),
22
+ createUsagePlugin(cache.getFreshState),
91
23
  ]);
92
- const shutdown = () => {
93
- console.error("\nShutting down...");
94
- const forceExit = setTimeout(() => {
95
- console.error("Shutdown timed out, forcing exit");
96
- // eslint-disable-next-line unicorn/no-process-exit -- CLI graceful shutdown
97
- process.exit(1);
98
- }, 5000);
99
- forceExit.unref();
100
- server
101
- .stop()
102
- .finally(() => {
103
- clearTimeout(forceExit);
104
- })
105
- .then(() => {
106
- // eslint-disable-next-line unicorn/no-process-exit -- CLI graceful shutdown
107
- process.exit(0);
108
- }, (error) => {
109
- console.error("Error during shutdown:", error);
110
- // eslint-disable-next-line unicorn/no-process-exit -- CLI graceful shutdown
111
- process.exit(1);
24
+ serverReference.current = server;
25
+ // Register shutdown handler before the initial fetch so signals arriving
26
+ // at any point during startup are caught instead of using Node's default
27
+ // (immediate termination).
28
+ closeWithGrace({
29
+ delay: 5000,
30
+ logger: false,
31
+ onTimeout(delay) {
32
+ server.app.log.error({ delay }, "Graceful shutdown timed out");
33
+ },
34
+ }, async ({ signal, err, manual }) => {
35
+ shuttingDown = true;
36
+ cache.shutdown();
37
+ if (err) {
38
+ server.app.log.error({ err, signal, manual }, "Shutting down axusage server due to fatal error");
39
+ }
40
+ else {
41
+ server.app.log.info({ signal, manual }, "Shutting down axusage server");
42
+ }
43
+ await server.stop();
44
+ await cache.waitForPending().catch((error) => {
45
+ server.app.log.warn({ err: error }, "In-flight refresh failed during shutdown");
112
46
  });
113
- };
114
- process.once("SIGTERM", shutdown);
115
- process.once("SIGINT", shutdown);
47
+ });
116
48
  // Pre-populate the cache before accepting connections so /health returns a
117
49
  // meaningful status immediately (important for container readiness checks).
118
- console.error(`Fetching initial data for: ${servicesToQuery.join(", ")}`);
50
+ server.app.log.info({ services: servicesToQuery }, "Fetching initial data for serve mode");
119
51
  await cache.getFreshState();
52
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- mutated by closeWithGrace signal handler above
53
+ if (shuttingDown)
54
+ return;
120
55
  await server.start();
121
- console.error(`Serving usage for: ${servicesToQuery.join(", ")} (max age: ${String(config.intervalMs / 1000)}s)`);
56
+ server.app.log.info({
57
+ services: servicesToQuery,
58
+ maxAgeSeconds: config.intervalMs / 1000,
59
+ }, "Serving usage");
122
60
  }
61
+ //# sourceMappingURL=serve-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-command.js","sourceRoot":"","sources":["../../src/commands/serve-command.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,13 @@
1
1
  import type { ServiceResult } from "../types/domain.js";
2
+ import type { SupportedService } from "../services/supported-service.js";
2
3
  import type { UsageCommandOptions } from "./fetch-service-usage.js";
3
4
  /**
4
5
  * Fetches usage for all requested services in parallel.
5
6
  * Each service type may produce multiple results (multi-instance support).
6
7
  */
7
- export declare function fetchServicesInParallel(servicesToQuery: string[]): Promise<ServiceResult[]>;
8
+ export declare function fetchServicesInParallel(servicesToQuery: SupportedService[]): Promise<ServiceResult[]>;
8
9
  /**
9
10
  * Executes the usage command
10
11
  */
11
12
  export declare function usageCommand(options: UsageCommandOptions): Promise<void>;
13
+ //# sourceMappingURL=usage-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-command.d.ts","sourceRoot":"","sources":["../../src/commands/usage-command.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAQpE;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,gBAAgB,EAAE,GAClC,OAAO,CAAC,aAAa,EAAE,CAAC,CAO1B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsHf"}
@@ -109,8 +109,13 @@ export async function usageCommand(options) {
109
109
  }
110
110
  break;
111
111
  }
112
+ default: {
113
+ const _exhaustive = format;
114
+ throw new Error(`Unhandled format: ${String(_exhaustive)}`);
115
+ }
112
116
  }
113
117
  if (hasPartialFailures) {
114
118
  process.exitCode = 1;
115
119
  }
116
120
  }
121
+ //# sourceMappingURL=usage-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-command.js","sourceRoot":"","sources":["../../src/commands/usage-command.ts"],"names":[],"mappings":"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"}
@@ -41,3 +41,4 @@ declare function getCredentialSourcesPath(): string;
41
41
  declare function getServiceInstanceConfigs(service: SupportedService): ResolvedInstanceConfig[];
42
42
  export { getServiceInstanceConfigs, getCredentialSourcesPath };
43
43
  export type { ResolvedInstanceConfig };
44
+ //# sourceMappingURL=credential-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-sources.d.ts","sourceRoot":"","sources":["../../src/config/credential-sources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,6BAA6B;AAC7B,QAAA,MAAM,oBAAoB;;;;EAAqC,CAAC;AAChE,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAsBjE,iDAAiD;AACjD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AA6FD;;;;;;GAMG;AACH,iBAAS,wBAAwB,IAAI,MAAM,CAG1C;AAED;;;;;;GAMG;AACH,iBAAS,yBAAyB,CAChC,OAAO,EAAE,gBAAgB,GACxB,sBAAsB,EAAE,CA+B1B;AAED,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,CAAC;AAC/D,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
@@ -8,6 +8,7 @@
8
8
  * credential, requires vault (no local fallback) to prevent returning the same
9
9
  * local token for multiple instances. Vault must be configured for named credentials.
10
10
  */
11
+ /* eslint-disable @typescript-eslint/no-unnecessary-type-arguments -- Conf<SourcesStore> is required: removing the type parameter causes Conf to infer T from the schema option as { sources: unknown }, which is incompatible with our store shape. */
11
12
  import Conf from "conf";
12
13
  import envPaths from "env-paths";
13
14
  import path from "node:path";
@@ -149,3 +150,4 @@ function getServiceInstanceConfigs(service) {
149
150
  ];
150
151
  }
151
152
  export { getServiceInstanceConfigs, getCredentialSourcesPath };
153
+ //# sourceMappingURL=credential-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential-sources.js","sourceRoot":"","sources":["../../src/config/credential-sources.ts"],"names":[],"mappings":"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"}
@@ -3,18 +3,34 @@
3
3
  *
4
4
  * Priority: CLI flags > environment variables > defaults.
5
5
  */
6
+ import { z } from "zod";
7
+ export declare const SERVE_LOG_LEVELS: readonly ["trace", "debug", "info", "warn", "error", "fatal", "silent"];
8
+ declare const ServeLogLevelSchema: z.ZodEnum<{
9
+ error: "error";
10
+ trace: "trace";
11
+ debug: "debug";
12
+ info: "info";
13
+ warn: "warn";
14
+ fatal: "fatal";
15
+ silent: "silent";
16
+ }>;
17
+ export type ServeLogLevel = z.infer<typeof ServeLogLevelSchema>;
6
18
  export type ServeConfig = {
7
19
  readonly port: number;
8
20
  readonly host: string;
9
21
  readonly intervalMs: number;
10
22
  readonly service: string | undefined;
23
+ readonly logLevel: ServeLogLevel;
24
+ readonly trustProxy: boolean;
11
25
  };
12
26
  type ServeConfigOverrides = {
13
27
  readonly port?: string;
14
28
  readonly host?: string;
15
29
  readonly interval?: string;
16
30
  readonly service?: string;
31
+ readonly logLevel?: string;
17
32
  };
18
33
  /** Parse serve config from environment and CLI overrides */
19
34
  export declare function getServeConfig(overrides?: ServeConfigOverrides): ServeConfig;
20
35
  export {};
36
+ //# sourceMappingURL=serve-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-config.d.ts","sourceRoot":"","sources":["../../src/config/serve-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB,yEAQnB,CAAC;AAEX,QAAA,MAAM,mBAAmB;;;;;;;;EAA2B,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAcF,4DAA4D;AAC5D,wBAAgB,cAAc,CAC5B,SAAS,GAAE,oBAAyB,GACnC,WAAW,CAsCb"}
@@ -3,38 +3,78 @@
3
3
  *
4
4
  * Priority: CLI flags > environment variables > defaults.
5
5
  */
6
+ import { z } from "zod";
7
+ export const SERVE_LOG_LEVELS = [
8
+ "trace",
9
+ "debug",
10
+ "info",
11
+ "warn",
12
+ "error",
13
+ "fatal",
14
+ "silent",
15
+ ];
16
+ const ServeLogLevelSchema = z.enum(SERVE_LOG_LEVELS);
6
17
  const DEFAULT_PORT = 3848;
7
18
  const DEFAULT_HOST = "127.0.0.1";
8
19
  const DEFAULT_INTERVAL_SECONDS = 300; // 5 minutes
20
+ const DEFAULT_LOG_LEVEL = "info";
21
+ class ServeConfigError extends Error {
22
+ constructor(message) {
23
+ super(message);
24
+ this.name = "ServeConfigError";
25
+ }
26
+ }
9
27
  /** Parse serve config from environment and CLI overrides */
10
28
  export function getServeConfig(overrides = {}) {
11
- const port = parsePort(overrides.port ?? process.env.AXUSAGE_PORT);
12
- const host = overrides.host || process.env.AXUSAGE_HOST || DEFAULT_HOST;
13
- const intervalSeconds = parsePositiveInt(overrides.interval ?? process.env.AXUSAGE_INTERVAL, DEFAULT_INTERVAL_SECONDS, "AXUSAGE_INTERVAL");
14
- const service = (overrides.service ?? process.env.AXUSAGE_SERVICE) || undefined;
29
+ const port = parseIntegerOption(normalizeOptionalValue(overrides.port ?? process.env.AXUSAGE_PORT), {
30
+ label: "AXUSAGE_PORT",
31
+ defaultValue: DEFAULT_PORT,
32
+ min: 1,
33
+ max: 65_535,
34
+ });
35
+ const host = normalizeOptionalValue(overrides.host ?? process.env.AXUSAGE_HOST) ??
36
+ DEFAULT_HOST;
37
+ const intervalSeconds = parseIntegerOption(normalizeOptionalValue(overrides.interval ?? process.env.AXUSAGE_INTERVAL), {
38
+ label: "AXUSAGE_INTERVAL",
39
+ defaultValue: DEFAULT_INTERVAL_SECONDS,
40
+ min: 1,
41
+ });
42
+ const service = normalizeOptionalValue(overrides.service ?? process.env.AXUSAGE_SERVICE)?.toLowerCase();
43
+ const logLevel = parseLogLevel(normalizeOptionalValue(overrides.logLevel ?? process.env.AXUSAGE_LOG_LEVEL));
44
+ const trustProxy = normalizeOptionalValue(process.env.AXUSAGE_TRUST_PROXY) === "true";
15
45
  return {
16
46
  port,
17
47
  host,
18
48
  intervalMs: intervalSeconds * 1000,
19
49
  service,
50
+ logLevel,
51
+ trustProxy,
20
52
  };
21
53
  }
22
- function parsePort(value) {
23
- if (!value)
24
- return DEFAULT_PORT;
25
- const port = Number(value);
26
- if (!Number.isInteger(port) || port < 1 || port > 65_535) {
27
- throw new Error(`Invalid port: ${value}`);
28
- }
29
- return port;
54
+ function normalizeOptionalValue(value) {
55
+ const normalized = value?.trim();
56
+ return normalized || undefined;
30
57
  }
31
- function parsePositiveInt(value, defaultValue, name) {
32
- if (!value)
33
- return defaultValue;
58
+ function parseIntegerOption(value, options) {
59
+ if (value === undefined)
60
+ return options.defaultValue;
34
61
  const parsed = Number(value);
35
- if (!Number.isInteger(parsed) || parsed < 1) {
36
- console.error(`Invalid ${name} value "${value}", using default ${String(defaultValue)}`);
37
- return defaultValue;
62
+ if (!Number.isInteger(parsed) ||
63
+ parsed < options.min ||
64
+ (options.max !== undefined && parsed > options.max)) {
65
+ const bounds = options.max === undefined
66
+ ? `an integer >= ${String(options.min)}`
67
+ : `an integer between ${String(options.min)} and ${String(options.max)}`;
68
+ throw new ServeConfigError(`Invalid ${options.label} value "${value}". Expected ${bounds}.`);
38
69
  }
39
70
  return parsed;
40
71
  }
72
+ function parseLogLevel(value) {
73
+ if (value === undefined)
74
+ return DEFAULT_LOG_LEVEL;
75
+ const parsed = ServeLogLevelSchema.safeParse(value.toLowerCase());
76
+ if (parsed.success)
77
+ return parsed.data;
78
+ throw new ServeConfigError(`Invalid AXUSAGE_LOG_LEVEL value "${value}". Expected one of: ${SERVE_LOG_LEVELS.join(", ")}.`);
79
+ }
80
+ //# sourceMappingURL=serve-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-config.js","sourceRoot":"","sources":["../../src/config/serve-config.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,24 @@
1
1
  /**
2
2
  * Route handlers for axusage serve mode.
3
3
  */
4
- import { Router } from "express";
4
+ import type { FastifyPluginCallbackZod } from "fastify-type-provider-zod";
5
5
  import type { ServiceUsageData } from "../types/domain.js";
6
+ /** Structured error from a failed service fetch. */
7
+ export type ServerError = {
8
+ readonly service: string;
9
+ readonly message: string;
10
+ readonly status?: number;
11
+ };
6
12
  /** Snapshot produced by each refresh cycle. */
7
13
  export type ServerState = {
8
14
  readonly usage: readonly ServiceUsageData[];
9
15
  readonly refreshedAt: Date;
10
- readonly errors: readonly string[];
16
+ readonly errors: readonly ServerError[];
11
17
  };
12
- /** Create router for GET /health */
13
- export declare function createHealthRouter(services: readonly string[], getState: () => ServerState | undefined): Router;
14
- /** Create router for GET /metrics (Prometheus text exposition) */
15
- export declare function createMetricsRouter(getState: () => Promise<ServerState | undefined>): Router;
16
- /** Create router for GET /usage (JSON) */
17
- export declare function createUsageRouter(getFreshState: () => Promise<ServerState | undefined>): Router;
18
+ /** Create plugin for GET /health */
19
+ export declare function createHealthPlugin(services: readonly string[], getState: () => ServerState | undefined, isShuttingDown: () => boolean): FastifyPluginCallbackZod;
20
+ /** Create plugin for GET /metrics (Prometheus text exposition) */
21
+ export declare function createMetricsPlugin(getState: () => Promise<ServerState | undefined>): FastifyPluginCallbackZod;
22
+ /** Create plugin for GET /usage (JSON) */
23
+ export declare function createUsagePlugin(getFreshState: () => Promise<ServerState | undefined>): FastifyPluginCallbackZod;
24
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAG1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAS3D,oDAAoD;AACpD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC,CAAC;AASF,oCAAoC;AACpC,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,EACvC,cAAc,EAAE,MAAM,OAAO,GAC5B,wBAAwB,CAsC1B;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,GAC/C,wBAAwB,CA4C1B;AAED,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,GACpD,wBAAwB,CA6B1B"}
@@ -1,70 +1,122 @@
1
1
  /**
2
2
  * Route handlers for axusage serve mode.
3
3
  */
4
- import { Router } from "express";
5
4
  import packageJson from "../../package.json" with { type: "json" };
5
+ import { ErrorResponseSchema, HealthResponseSchema, UsageResponseSchema, } from "../types/serve-api.js";
6
6
  import { formatPrometheusMetrics } from "../utils/format-prometheus-metrics.js";
7
7
  import { toJsonObject } from "../utils/format-service-usage.js";
8
- /** Create router for GET /health */
9
- export function createHealthRouter(services, getState) {
10
- const router = Router();
11
- router.get("/health", (_request, response) => {
12
- const state = getState();
13
- const healthy = state !== undefined && state.usage.length > 0;
14
- response.status(healthy ? 200 : 503).json({
15
- status: healthy ? "ok" : "degraded",
16
- version: packageJson.version,
17
- lastRefresh: state?.refreshedAt.toISOString(),
18
- services,
19
- errors: state?.errors ?? [],
8
+ function formatServerError(error) {
9
+ if (error.status === undefined) {
10
+ return `${error.service}: ${error.message}`;
11
+ }
12
+ return `${error.service}: ${error.message} (HTTP ${String(error.status)})`;
13
+ }
14
+ /** Create plugin for GET /health */
15
+ export function createHealthPlugin(services, getState, isShuttingDown) {
16
+ return function healthPlugin(fastify, _options, done) {
17
+ fastify.route({
18
+ method: "GET",
19
+ url: "/health",
20
+ config: { rateLimit: false },
21
+ schema: {
22
+ response: {
23
+ 200: HealthResponseSchema,
24
+ 503: HealthResponseSchema,
25
+ 500: ErrorResponseSchema,
26
+ },
27
+ },
28
+ handler: async (_request, reply) => {
29
+ if (isShuttingDown()) {
30
+ const state = getState();
31
+ return reply.code(503).send({
32
+ status: "shutting_down",
33
+ version: packageJson.version,
34
+ lastRefresh: state?.refreshedAt.toISOString(),
35
+ services: [...services],
36
+ errors: state?.errors.map((error) => formatServerError(error)) ?? [],
37
+ });
38
+ }
39
+ const state = getState();
40
+ const healthy = state !== undefined && state.usage.length > 0;
41
+ return reply.code(healthy ? 200 : 503).send({
42
+ status: healthy ? "ok" : "degraded",
43
+ version: packageJson.version,
44
+ lastRefresh: state?.refreshedAt.toISOString(),
45
+ services: [...services],
46
+ errors: state?.errors.map((error) => formatServerError(error)) ?? [],
47
+ });
48
+ },
20
49
  });
21
- });
22
- return router;
50
+ done();
51
+ };
23
52
  }
24
- /** Create router for GET /metrics (Prometheus text exposition) */
25
- export function createMetricsRouter(getState) {
26
- const router = Router();
27
- // Memoize the rendered Prometheus text by the state snapshot's refreshedAt
28
- // timestamp. Scrapes within the same cache window reuse the same Promise,
29
- // avoiding recreating prom-client Registry/Gauge objects on each request.
30
- // Rate is computed at refreshedAt so output is deterministic per snapshot,
31
- // keeping the gauge coherent with the usage data it describes.
32
- // Assignments happen synchronously (before any await) so require-atomic-updates
33
- // is satisfied and concurrent scrapes naturally coalesce onto one render.
34
- let memoFor;
35
- let memoPromise = Promise.resolve("");
36
- router.get("/metrics", async (_request, response) => {
37
- const state = await getState();
38
- const usage = state?.usage;
39
- if (!usage || usage.length === 0) {
40
- response.status(503).type("text/plain").send("No data yet\n");
41
- return;
42
- }
43
- if (memoFor !== state.refreshedAt) {
44
- memoFor = state.refreshedAt;
45
- memoPromise = formatPrometheusMetrics(usage, state.refreshedAt.getTime());
46
- }
47
- const text = await memoPromise;
48
- response
49
- .status(200)
50
- .type("text/plain; version=0.0.4; charset=utf-8")
51
- .send(text);
52
- });
53
- return router;
53
+ /** Create plugin for GET /metrics (Prometheus text exposition) */
54
+ export function createMetricsPlugin(getState) {
55
+ return function metricsPlugin(fastify, _options, done) {
56
+ // Memoize the rendered Prometheus text by the state snapshot's refreshedAt
57
+ // timestamp. Scrapes within the same cache window reuse the same Promise,
58
+ // avoiding recreating prom-client Registry/Gauge objects on each request.
59
+ // Rate is computed at refreshedAt so output is deterministic per snapshot,
60
+ // keeping the gauge coherent with the usage data it describes.
61
+ // Assignments happen synchronously (before any await) so require-atomic-updates
62
+ // is satisfied and concurrent scrapes naturally coalesce onto one render.
63
+ let memoFor;
64
+ let memoPromise = Promise.resolve("");
65
+ fastify.route({
66
+ method: "GET",
67
+ url: "/metrics",
68
+ config: { rateLimit: false },
69
+ // No response schema: /metrics returns text/plain Prometheus exposition
70
+ // format for 200, which cannot be validated by a Zod object schema.
71
+ // Adding only a 503 schema would prevent Fastify's type provider from
72
+ // accepting the 200 text response. The 503 error returns JSON
73
+ // { error: "No data yet" } consistent with other error responses.
74
+ handler: async (_request, reply) => {
75
+ const state = await getState();
76
+ const usage = state?.usage;
77
+ if (!usage || usage.length === 0) {
78
+ return reply.code(503).send({ error: "No data yet" });
79
+ }
80
+ const refreshedAtMs = state.refreshedAt.getTime();
81
+ if (memoFor !== refreshedAtMs) {
82
+ memoFor = refreshedAtMs;
83
+ memoPromise = formatPrometheusMetrics(usage, state.refreshedAt.getTime());
84
+ }
85
+ const text = await memoPromise;
86
+ return reply
87
+ .code(200)
88
+ .type("text/plain; version=0.0.4; charset=utf-8")
89
+ .send(text);
90
+ },
91
+ });
92
+ done();
93
+ };
54
94
  }
55
- /** Create router for GET /usage (JSON) */
56
- export function createUsageRouter(getFreshState) {
57
- const router = Router();
58
- router.get("/usage", async (_request, response) => {
59
- const state = await getFreshState();
60
- const usage = state?.usage;
61
- if (!usage || usage.length === 0) {
62
- response.status(503).json({ error: "No data yet" });
63
- return;
64
- }
65
- response
66
- .status(200)
67
- .json(usage.map((entry) => toJsonObject(entry, state.refreshedAt.getTime())));
68
- });
69
- return router;
95
+ /** Create plugin for GET /usage (JSON) */
96
+ export function createUsagePlugin(getFreshState) {
97
+ return function usagePlugin(fastify, _options, done) {
98
+ fastify.route({
99
+ method: "GET",
100
+ url: "/usage",
101
+ schema: {
102
+ response: {
103
+ 200: UsageResponseSchema,
104
+ 503: ErrorResponseSchema,
105
+ 500: ErrorResponseSchema,
106
+ },
107
+ },
108
+ handler: async (_request, reply) => {
109
+ const state = await getFreshState();
110
+ const usage = state?.usage;
111
+ if (!usage || usage.length === 0) {
112
+ return reply.code(503).send({ error: "No data yet" });
113
+ }
114
+ return reply
115
+ .code(200)
116
+ .send(usage.map((entry) => toJsonObject(entry, state.refreshedAt.getTime())));
117
+ },
118
+ });
119
+ done();
120
+ };
70
121
  }
122
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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"}