axusage 3.8.2 → 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 (57) hide show
  1. package/README.md +19 -8
  2. package/dist/cli.js +2 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/fetch-service-usage.d.ts +4 -3
  5. package/dist/commands/fetch-service-usage.d.ts.map +1 -1
  6. package/dist/commands/fetch-service-usage.js +13 -27
  7. package/dist/commands/fetch-service-usage.js.map +1 -1
  8. package/dist/commands/serve-command.d.ts +1 -19
  9. package/dist/commands/serve-command.d.ts.map +1 -1
  10. package/dist/commands/serve-command.js +42 -104
  11. package/dist/commands/serve-command.js.map +1 -1
  12. package/dist/commands/usage-command.d.ts +2 -1
  13. package/dist/commands/usage-command.d.ts.map +1 -1
  14. package/dist/commands/usage-command.js +4 -0
  15. package/dist/commands/usage-command.js.map +1 -1
  16. package/dist/config/serve-config.d.ts +15 -0
  17. package/dist/config/serve-config.d.ts.map +1 -1
  18. package/dist/config/serve-config.js +57 -18
  19. package/dist/config/serve-config.js.map +1 -1
  20. package/dist/server/routes.d.ts +14 -8
  21. package/dist/server/routes.d.ts.map +1 -1
  22. package/dist/server/routes.js +111 -60
  23. package/dist/server/routes.js.map +1 -1
  24. package/dist/server/serve-logger.d.ts +5 -0
  25. package/dist/server/serve-logger.d.ts.map +1 -0
  26. package/dist/server/serve-logger.js +88 -0
  27. package/dist/server/serve-logger.js.map +1 -0
  28. package/dist/server/server.d.ts +14 -7
  29. package/dist/server/server.d.ts.map +1 -1
  30. package/dist/server/server.js +90 -56
  31. package/dist/server/server.js.map +1 -1
  32. package/dist/server/usage-cache.d.ts +26 -0
  33. package/dist/server/usage-cache.d.ts.map +1 -0
  34. package/dist/server/usage-cache.js +77 -0
  35. package/dist/server/usage-cache.js.map +1 -0
  36. package/dist/services/get-instance-access-token.d.ts +2 -1
  37. package/dist/services/get-instance-access-token.d.ts.map +1 -1
  38. package/dist/services/get-instance-access-token.js.map +1 -1
  39. package/dist/services/service-adapter-registry.d.ts +3 -2
  40. package/dist/services/service-adapter-registry.d.ts.map +1 -1
  41. package/dist/services/service-adapter-registry.js +3 -3
  42. package/dist/services/service-adapter-registry.js.map +1 -1
  43. package/dist/services/supported-service.d.ts.map +1 -1
  44. package/dist/services/supported-service.js +5 -1
  45. package/dist/services/supported-service.js.map +1 -1
  46. package/dist/types/serve-api.d.ts +53 -0
  47. package/dist/types/serve-api.d.ts.map +1 -0
  48. package/dist/types/serve-api.js +34 -0
  49. package/dist/types/serve-api.js.map +1 -0
  50. package/dist/utils/format-prometheus-metrics.d.ts.map +1 -1
  51. package/dist/utils/format-prometheus-metrics.js +8 -2
  52. package/dist/utils/format-prometheus-metrics.js.map +1 -1
  53. package/dist/utils/format-service-usage.d.ts +2 -1
  54. package/dist/utils/format-service-usage.d.ts.map +1 -1
  55. package/dist/utils/format-service-usage.js +2 -2
  56. package/dist/utils/format-service-usage.js.map +1 -1
  57. package/package.json +6 -3
@@ -1,73 +1,107 @@
1
1
  /**
2
- * Express HTTP server for axusage metrics.
2
+ * Fastify HTTP server for axusage metrics.
3
3
  *
4
4
  * Designed for both CLI and library usage via factory pattern.
5
5
  */
6
- import express, {} from "express";
7
- /** Create and configure Express application */
8
- function createApp(routers) {
9
- const app = express();
10
- // Security: disable X-Powered-By header
11
- app.disable("x-powered-by");
12
- // Register all routers
13
- for (const router of routers) {
14
- app.use(router);
6
+ import helmet from "@fastify/helmet";
7
+ import rateLimit from "@fastify/rate-limit";
8
+ import Fastify, {} from "fastify";
9
+ import { hasZodFastifySchemaValidationErrors, isResponseSerializationError, serializerCompiler, validatorCompiler, } from "fastify-type-provider-zod";
10
+ function buildApp(config, plugins) {
11
+ const app = Fastify({
12
+ logger: {
13
+ level: config.logLevel,
14
+ redact: [
15
+ "req.headers.authorization",
16
+ "req.headers.cookie",
17
+ "headers.authorization",
18
+ "headers.cookie",
19
+ ],
20
+ },
21
+ connectionTimeout: 30_000,
22
+ requestTimeout: 30_000,
23
+ trustProxy: config.trustProxy,
24
+ });
25
+ app.setValidatorCompiler(validatorCompiler);
26
+ app.setSerializerCompiler(serializerCompiler);
27
+ app.register(helmet);
28
+ app.register(rateLimit, {
29
+ max: 100,
30
+ timeWindow: "1 minute",
31
+ errorResponseBuilder: (_request, context) => {
32
+ const error = new Error("Too many requests");
33
+ // @fastify/rate-limit throws whatever errorResponseBuilder returns.
34
+ // Fastify's error handler reads statusCode from the thrown object to
35
+ // set the HTTP status; without it the response falls back to 500.
36
+ error.statusCode = context.statusCode;
37
+ return error;
38
+ },
39
+ });
40
+ const typedApp = app.withTypeProvider();
41
+ typedApp.setErrorHandler((error, request, reply) => {
42
+ request.log.error({ err: error }, "Request error");
43
+ if (hasZodFastifySchemaValidationErrors(error)) {
44
+ return reply.code(400).send({ error: "Validation failed" });
45
+ }
46
+ if (isResponseSerializationError(error)) {
47
+ return reply.code(500).send({ error: "Internal Server Error" });
48
+ }
49
+ const statusCode = error.statusCode !== undefined && error.statusCode >= 400
50
+ ? error.statusCode
51
+ : 500;
52
+ const message = statusCode >= 500 ? "Internal Server Error" : error.message;
53
+ return reply.code(statusCode).send({ error: message });
54
+ });
55
+ for (const plugin of plugins) {
56
+ typedApp.register(plugin);
15
57
  }
16
- // 404 handler for unmatched routes
17
- app.use((_request, response) => {
18
- response.status(404).json({ error: "Not found" });
58
+ // Rate-limit the 404 handler. setNotFoundHandler must receive the
59
+ // rateLimit() preHandler, otherwise custom 404s bypass rate limiting
60
+ // entirely (@fastify/rate-limit README, "Preventing guessing of URLs
61
+ // through 404s"). The decorator is available after the plugin queue
62
+ // has been processed, so we defer via after().
63
+ typedApp.after(() => {
64
+ typedApp.setNotFoundHandler({ preHandler: app.rateLimit() }, async (_request, reply) => {
65
+ return reply.code(404).send({ error: "Not found" });
66
+ });
19
67
  });
20
68
  return app;
21
69
  }
22
70
  /** Create an axusage server instance */
23
- export function createServer(config, routers) {
24
- const app = createApp(routers);
25
- let server;
26
- let stopPromise;
27
- return {
28
- app,
29
- start() {
30
- if (server) {
31
- return Promise.reject(new Error("Server is already running. Call stop() before restarting."));
32
- }
33
- stopPromise = undefined;
34
- return new Promise((resolve, reject) => {
35
- const onStartupError = (error) => {
36
- server = undefined;
37
- reject(error);
38
- };
39
- server = app.listen(config.port, config.host, () => {
40
- server?.removeListener("error", onStartupError);
41
- server?.on("error", (error) => {
42
- console.error("Server error:", error);
43
- });
44
- console.error(`axusage listening on http://${config.host}:${String(config.port)}`);
45
- resolve();
46
- });
47
- server.once("error", onStartupError);
48
- });
71
+ export function createServer(config, plugins) {
72
+ let app = buildApp(config, plugins);
73
+ let started = false;
74
+ let stopped = false;
75
+ const server = {
76
+ get app() {
77
+ return app;
49
78
  },
50
- stop() {
51
- if (stopPromise) {
52
- return stopPromise;
79
+ async start() {
80
+ if (started) {
81
+ throw new Error("Server is already running. Call stop() before restarting.");
53
82
  }
54
- if (!server) {
55
- return Promise.resolve();
83
+ // Fastify instances cannot be reopened after close, so rebuild
84
+ // on restart. Skip rebuild on first start since we already have
85
+ // a fresh instance from createServer.
86
+ if (stopped) {
87
+ app = buildApp(config, plugins);
56
88
  }
57
- const serverToClose = server;
58
- server = undefined;
59
- stopPromise = new Promise((resolve, reject) => {
60
- serverToClose.close((error) => {
61
- if (error) {
62
- reject(error);
63
- }
64
- else {
65
- resolve();
66
- }
67
- });
89
+ const address = await app.listen({
90
+ port: config.port,
91
+ host: config.host,
68
92
  });
69
- return stopPromise;
93
+ // eslint-disable-next-line require-atomic-updates -- guarded by the started check above; no concurrent callers
94
+ started = true;
95
+ app.log.info({ address }, "axusage listening");
96
+ },
97
+ async stop() {
98
+ if (!started)
99
+ return;
100
+ started = false;
101
+ stopped = true;
102
+ await app.close();
70
103
  },
71
104
  };
105
+ return server;
72
106
  }
73
107
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,OAAO,EAAE,EAA6B,MAAM,SAAS,CAAC;AAc7D,+CAA+C;AAC/C,SAAS,SAAS,CAAC,OAAiB;IAClC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IAEtB,wCAAwC;IACxC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5B,uBAAuB;IACvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,mCAAmC;IACnC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;QAC7B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,YAAY,CAC1B,MAA0C,EAC1C,OAAiB;IAEjB,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,MAA0B,CAAC;IAC/B,IAAI,WAAsC,CAAC;IAE3C,OAAO;QACL,GAAG;QAEH,KAAK;YACH,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CACP,2DAA2D,CAC5D,CACF,CAAC;YACJ,CAAC;YAED,WAAW,GAAG,SAAS,CAAC;YAExB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,cAAc,GAAG,CAAC,KAAY,EAAQ,EAAE;oBAC5C,MAAM,GAAG,SAAS,CAAC;oBACnB,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC,CAAC;gBAEF,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;oBACjD,MAAM,EAAE,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;oBAEhD,MAAM,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;wBACnC,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;oBACxC,CAAC,CAAC,CAAC;oBAEH,OAAO,CAAC,KAAK,CACX,+BAA+B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CACpE,CAAC;oBACF,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI;YACF,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,CAAC;YAC7B,MAAM,GAAG,SAAS,CAAC;YAEnB,WAAW,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC5C,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC5B,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACN,OAAO,EAAE,CAAC;oBACZ,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,OAAO,WAAW,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ServiceResult } from "../types/domain.js";
2
+ import { type ServeLogger } from "./serve-logger.js";
3
+ import type { ServerState } from "./routes.js";
4
+ type UsageCache = {
5
+ readonly getState: () => ServerState | undefined;
6
+ /** Waits for a fresh snapshot before returning. Use for data endpoints where staleness is unacceptable. */
7
+ readonly getFreshState: () => Promise<ServerState | undefined>;
8
+ /** Serves the current snapshot immediately; triggers a background refresh when stale.
9
+ * Blocks only if no snapshot exists yet (first ever request). Use for Prometheus /metrics
10
+ * where scrape latency matters more than strict freshness. */
11
+ readonly getStateStaleWhileRevalidate: () => Promise<ServerState | undefined>;
12
+ /** Waits for any in-flight refresh to complete. Use during shutdown to avoid dangling promises. */
13
+ readonly waitForPending: () => Promise<void>;
14
+ /** Signal that the server is shutting down. Prevents new fetches from starting. */
15
+ readonly shutdown: () => void;
16
+ };
17
+ /**
18
+ * Creates an on-demand usage cache. Data is fetched via `doFetch` when a
19
+ * caller requests fresh state and the cached snapshot is older than `intervalMs`.
20
+ * Concurrent callers during a refresh all receive the same in-flight promise.
21
+ * When all services fail, the cache retries after a short backoff (≤5s) rather
22
+ * than waiting the full interval.
23
+ */
24
+ export declare function createUsageCache(doFetch: () => Promise<ServiceResult[]>, intervalMs: number, logger?: ServeLogger): UsageCache;
25
+ export {};
26
+ //# sourceMappingURL=usage-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-cache.d.ts","sourceRoot":"","sources":["../../src/server/usage-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,KAAK,WAAW,EAA4B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,WAAW,GAAG,SAAS,CAAC;IACjD,2GAA2G;IAC3G,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC/D;;mEAE+D;IAC/D,QAAQ,CAAC,4BAA4B,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IAC9E,mGAAmG;IACnG,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,EACvC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,WAAwC,GAC/C,UAAU,CA0EZ"}
@@ -0,0 +1,77 @@
1
+ import { createConsoleServeLogger } from "./serve-logger.js";
2
+ /**
3
+ * Creates an on-demand usage cache. Data is fetched via `doFetch` when a
4
+ * caller requests fresh state and the cached snapshot is older than `intervalMs`.
5
+ * Concurrent callers during a refresh all receive the same in-flight promise.
6
+ * When all services fail, the cache retries after a short backoff (≤5s) rather
7
+ * than waiting the full interval.
8
+ */
9
+ export function createUsageCache(doFetch, intervalMs, logger = createConsoleServeLogger()) {
10
+ let state;
11
+ let refreshPromise;
12
+ let isShutDown = false;
13
+ async function doRefresh() {
14
+ const results = await doFetch();
15
+ const usage = [];
16
+ const errors = [];
17
+ for (const { service, result } of results) {
18
+ if (result.ok) {
19
+ usage.push(result.value);
20
+ }
21
+ else {
22
+ errors.push({
23
+ service,
24
+ message: result.error.message,
25
+ status: result.error.status,
26
+ });
27
+ logger.warn({ service, error: result.error.message, status: result.error.status }, "Failed to fetch service");
28
+ }
29
+ }
30
+ state = { usage, refreshedAt: new Date(), errors };
31
+ }
32
+ const FAILURE_RETRY_MS = 5000;
33
+ function ensureFresh() {
34
+ if (isShutDown)
35
+ return Promise.resolve();
36
+ const age = state === undefined ? Infinity : Date.now() - state.refreshedAt.getTime();
37
+ // If the last refresh produced no data (all services failed), retry on a
38
+ // short backoff (capped at 5s) so the server recovers promptly after
39
+ // transient failures without hammering failing services.
40
+ const hasData = state !== undefined && state.usage.length > 0;
41
+ const maxAge = hasData
42
+ ? intervalMs
43
+ : Math.min(intervalMs, FAILURE_RETRY_MS);
44
+ if (age < maxAge)
45
+ return Promise.resolve();
46
+ refreshPromise ??= doRefresh().finally(() => {
47
+ refreshPromise = undefined;
48
+ });
49
+ return refreshPromise;
50
+ }
51
+ return {
52
+ getState: () => state,
53
+ getFreshState: async () => {
54
+ await ensureFresh();
55
+ return state;
56
+ },
57
+ getStateStaleWhileRevalidate: async () => {
58
+ if (state === undefined) {
59
+ // No snapshot yet — block until we have something to serve.
60
+ await ensureFresh();
61
+ }
62
+ else {
63
+ // Serve the current snapshot immediately; kick off a background
64
+ // refresh if stale. Errors are logged; callers are not affected.
65
+ void ensureFresh().catch((error) => {
66
+ logger.error({ err: error }, "Background metrics refresh failed");
67
+ });
68
+ }
69
+ return state;
70
+ },
71
+ waitForPending: () => refreshPromise ?? Promise.resolve(),
72
+ shutdown: () => {
73
+ isShutDown = true;
74
+ },
75
+ };
76
+ }
77
+ //# sourceMappingURL=usage-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-cache.js","sourceRoot":"","sources":["../../src/server/usage-cache.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  * returning vault metadata (displayName) alongside the token.
6
6
  */
7
7
  import type { ResolvedInstanceConfig } from "../config/credential-sources.js";
8
+ import type { SupportedService } from "./supported-service.js";
8
9
  /** Result of resolving an instance token */
9
10
  interface InstanceTokenResult {
10
11
  token: string | undefined;
@@ -16,6 +17,6 @@ interface InstanceTokenResult {
16
17
  * Returns vault metadata (displayName) alongside the token
17
18
  * for multi-instance identification.
18
19
  */
19
- declare function getInstanceAccessToken(service: string, config: ResolvedInstanceConfig): Promise<InstanceTokenResult>;
20
+ declare function getInstanceAccessToken(service: SupportedService, config: ResolvedInstanceConfig): Promise<InstanceTokenResult>;
20
21
  export { getInstanceAccessToken };
21
22
  //# sourceMappingURL=get-instance-access-token.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get-instance-access-token.d.ts","sourceRoot":"","sources":["../../src/services/get-instance-access-token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AA8C9E,4CAA4C;AAC5C,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAwDD;;;;;GAKG;AACH,iBAAe,sBAAsB,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6C9B;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
1
+ {"version":3,"file":"get-instance-access-token.d.ts","sourceRoot":"","sources":["../../src/services/get-instance-access-token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AA8C/D,4CAA4C;AAC5C,UAAU,mBAAmB;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAwDD;;;;;GAKG;AACH,iBAAe,sBAAsB,CACnC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6C9B;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"get-instance-access-token.js","sourceRoot":"","sources":["../../src/services/get-instance-access-token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-instance-access-token.js","sourceRoot":"","sources":["../../src/services/get-instance-access-token.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import type { ServiceUsageFetcher } from "../types/domain.js";
2
+ import { type SupportedService } from "./supported-service.js";
2
3
  /**
3
4
  * Get a token-based usage fetcher by service type
4
5
  */
5
- export declare function getServiceUsageFetcher(name: string): ServiceUsageFetcher | undefined;
6
+ export declare function getServiceUsageFetcher(name: SupportedService): ServiceUsageFetcher;
6
7
  /**
7
8
  * Get all available service names
8
9
  */
9
- export declare function getAvailableServices(): string[];
10
+ export declare function getAvailableServices(): SupportedService[];
10
11
  //# sourceMappingURL=service-adapter-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-adapter-registry.d.ts","sourceRoot":"","sources":["../../src/services/service-adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAgB9D;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GACX,mBAAmB,GAAG,SAAS,CAGjC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C"}
1
+ {"version":3,"file":"service-adapter-registry.d.ts","sourceRoot":"","sources":["../../src/services/service-adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAYhC;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,gBAAgB,GACrB,mBAAmB,CAErB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,gBAAgB,EAAE,CAEzD"}
@@ -2,6 +2,7 @@ import { codexUsageFetcher } from "../adapters/codex.js";
2
2
  import { claudeUsageFetcher } from "../adapters/claude.js";
3
3
  import { geminiUsageFetcher } from "../adapters/gemini.js";
4
4
  import { copilotUsageFetcher } from "../adapters/copilot.js";
5
+ import { SUPPORTED_SERVICES, } from "./supported-service.js";
5
6
  /**
6
7
  * Registry of token-based usage fetchers
7
8
  */
@@ -15,13 +16,12 @@ const SERVICE_USAGE_FETCHERS = {
15
16
  * Get a token-based usage fetcher by service type
16
17
  */
17
18
  export function getServiceUsageFetcher(name) {
18
- const key = name.toLowerCase();
19
- return SERVICE_USAGE_FETCHERS[key];
19
+ return SERVICE_USAGE_FETCHERS[name];
20
20
  }
21
21
  /**
22
22
  * Get all available service names
23
23
  */
24
24
  export function getAvailableServices() {
25
- return Object.keys(SERVICE_USAGE_FETCHERS);
25
+ return [...SUPPORTED_SERVICES];
26
26
  }
27
27
  //# sourceMappingURL=service-adapter-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-adapter-registry.js","sourceRoot":"","sources":["../../src/services/service-adapter-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;GAEG;AACH,MAAM,sBAAsB,GAAG;IAC7B,MAAM,EAAE,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB;IACxB,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,kBAAkB;CAC4B,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAyC,CAAC;IACtE,OAAO,sBAAsB,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"service-adapter-registry.js","sourceRoot":"","sources":["../../src/services/service-adapter-registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,kBAAkB,GAEnB,MAAM,wBAAwB,CAAC;AAEhC;;GAEG;AACH,MAAM,sBAAsB,GAAG;IAC7B,MAAM,EAAE,kBAAkB;IAC1B,KAAK,EAAE,iBAAiB;IACxB,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,kBAAkB;CACsC,CAAC;AAEnE;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAsB;IAEtB,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,GAAG,kBAAkB,CAAC,CAAC;AACjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"supported-service.d.ts","sourceRoot":"","sources":["../../src/services/supported-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAE7D,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAEhD,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAgB7E"}
1
+ {"version":3,"file":"supported-service.d.ts","sourceRoot":"","sources":["../../src/services/supported-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAE7D,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAEhD,CAAC;AAQF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAgB7E"}
@@ -1,12 +1,16 @@
1
1
  import { AGENT_CLIS } from "axauth";
2
2
  export const SUPPORTED_SERVICES = AGENT_CLIS.filter((cli) => cli !== "opencode");
3
+ const SUPPORTED_SERVICE_SET = new Set(SUPPORTED_SERVICES);
4
+ function isSupportedService(service) {
5
+ return SUPPORTED_SERVICE_SET.has(service);
6
+ }
3
7
  export function validateService(service) {
4
8
  if (!service) {
5
9
  throw new Error(`Service is required. Supported services: ${SUPPORTED_SERVICES.join(", ")}. ` +
6
10
  "Run 'axusage --help' for usage.");
7
11
  }
8
12
  const normalizedService = service.toLowerCase();
9
- if (!SUPPORTED_SERVICES.includes(normalizedService)) {
13
+ if (!isSupportedService(normalizedService)) {
10
14
  throw new Error(`Unsupported service: ${service}. Supported services: ${SUPPORTED_SERVICES.join(", ")}. ` +
11
15
  "Run 'axusage --help' for usage.");
12
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"supported-service.js","sourceRoot":"","sources":["../../src/services/supported-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAUpC,MAAM,CAAC,MAAM,kBAAkB,GAAuB,UAAU,CAAC,MAAM,CACrE,CAAC,GAAG,EAA2B,EAAE,CAAC,GAAG,KAAK,UAAU,CACrD,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,OAA2B;IACzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4CAA4C,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC3E,iCAAiC,CACpC,CAAC;IACJ,CAAC;IAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAsB,CAAC;IACpE,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,yBAAyB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACvF,iCAAiC,CACpC,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"supported-service.js","sourceRoot":"","sources":["../../src/services/supported-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAUpC,MAAM,CAAC,MAAM,kBAAkB,GAAuB,UAAU,CAAC,MAAM,CACrE,CAAC,GAAG,EAA2B,EAAE,CAAC,GAAG,KAAK,UAAU,CACrD,CAAC;AAEF,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAS,kBAAkB,CAAC,CAAC;AAElE,SAAS,kBAAkB,CAAC,OAAe;IACzC,OAAO,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAA2B;IACzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4CAA4C,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC3E,iCAAiC,CACpC,CAAC;IACJ,CAAC;IAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,yBAAyB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACvF,iCAAiC,CACpC,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ export declare const ServiceUsageResponseSchema: z.ZodObject<{
3
+ service: z.ZodString;
4
+ serviceType: z.ZodString;
5
+ instanceId: z.ZodOptional<z.ZodString>;
6
+ planType: z.ZodOptional<z.ZodString>;
7
+ windows: z.ZodArray<z.ZodObject<{
8
+ name: z.ZodString;
9
+ utilization: z.ZodNumber;
10
+ rate: z.ZodOptional<z.ZodNumber>;
11
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
12
+ periodDurationMs: z.ZodNumber;
13
+ }, z.core.$strip>>;
14
+ metadata: z.ZodOptional<z.ZodObject<{
15
+ allowed: z.ZodOptional<z.ZodBoolean>;
16
+ limitReached: z.ZodOptional<z.ZodBoolean>;
17
+ }, z.core.$strip>>;
18
+ }, z.core.$strip>;
19
+ export declare const UsageResponseSchema: z.ZodArray<z.ZodObject<{
20
+ service: z.ZodString;
21
+ serviceType: z.ZodString;
22
+ instanceId: z.ZodOptional<z.ZodString>;
23
+ planType: z.ZodOptional<z.ZodString>;
24
+ windows: z.ZodArray<z.ZodObject<{
25
+ name: z.ZodString;
26
+ utilization: z.ZodNumber;
27
+ rate: z.ZodOptional<z.ZodNumber>;
28
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
29
+ periodDurationMs: z.ZodNumber;
30
+ }, z.core.$strip>>;
31
+ metadata: z.ZodOptional<z.ZodObject<{
32
+ allowed: z.ZodOptional<z.ZodBoolean>;
33
+ limitReached: z.ZodOptional<z.ZodBoolean>;
34
+ }, z.core.$strip>>;
35
+ }, z.core.$strip>>;
36
+ export declare const HealthResponseSchema: z.ZodObject<{
37
+ status: z.ZodEnum<{
38
+ ok: "ok";
39
+ degraded: "degraded";
40
+ shutting_down: "shutting_down";
41
+ }>;
42
+ version: z.ZodString;
43
+ lastRefresh: z.ZodOptional<z.ZodISODateTime>;
44
+ services: z.ZodArray<z.ZodString>;
45
+ errors: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strip>;
47
+ export declare const ErrorResponseSchema: z.ZodObject<{
48
+ error: z.ZodString;
49
+ }, z.core.$strip>;
50
+ export type ServiceUsageResponse = z.infer<typeof ServiceUsageResponseSchema>;
51
+ export type UsageResponse = z.infer<typeof UsageResponseSchema>;
52
+ export type HealthResponse = z.infer<typeof HealthResponseSchema>;
53
+ //# sourceMappingURL=serve-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-api.d.ts","sourceRoot":"","sources":["../../src/types/serve-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;iBAOrC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;kBAAsC,CAAC;AAEvE,eAAO,MAAM,oBAAoB;;;;;;;;;;iBAM/B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;iBAE9B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ const UsageWindowResponseSchema = z.object({
3
+ name: z.string(),
4
+ utilization: z.number(),
5
+ rate: z.number().optional(),
6
+ resetsAt: z.iso.datetime({ offset: true }).optional(),
7
+ periodDurationMs: z.number().nonnegative(),
8
+ });
9
+ const ServiceMetadataResponseSchema = z
10
+ .object({
11
+ allowed: z.boolean().optional(),
12
+ limitReached: z.boolean().optional(),
13
+ })
14
+ .optional();
15
+ export const ServiceUsageResponseSchema = z.object({
16
+ service: z.string(),
17
+ serviceType: z.string(),
18
+ instanceId: z.string().optional(),
19
+ planType: z.string().optional(),
20
+ windows: z.array(UsageWindowResponseSchema),
21
+ metadata: ServiceMetadataResponseSchema,
22
+ });
23
+ export const UsageResponseSchema = z.array(ServiceUsageResponseSchema);
24
+ export const HealthResponseSchema = z.object({
25
+ status: z.enum(["ok", "degraded", "shutting_down"]),
26
+ version: z.string(),
27
+ lastRefresh: z.iso.datetime({ offset: true }).optional(),
28
+ services: z.array(z.string()),
29
+ errors: z.array(z.string()),
30
+ });
31
+ export const ErrorResponseSchema = z.object({
32
+ error: z.string(),
33
+ });
34
+ //# sourceMappingURL=serve-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-api.js","sourceRoot":"","sources":["../../src/types/serve-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;IACrD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;CAC3C,CAAC,CAAC;AAEH,MAAM,6BAA6B,GAAG,CAAC;KACpC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACrC,CAAC;KACD,QAAQ,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC;IAC3C,QAAQ,EAAE,6BAA6B;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAEvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IACnD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"format-prometheus-metrics.d.ts","sourceRoot":"","sources":["../../src/utils/format-prometheus-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAI3D;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,SAAS,gBAAgB,EAAE,EACjC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
1
+ {"version":3,"file":"format-prometheus-metrics.d.ts","sourceRoot":"","sources":["../../src/utils/format-prometheus-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAa3D;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,SAAS,gBAAgB,EAAE,EACjC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
@@ -1,5 +1,11 @@
1
1
  import { Gauge, Registry } from "prom-client";
2
2
  import { calculateUsageRate } from "./calculate-usage-rate.js";
3
+ const LABEL_NAMES = [
4
+ "service",
5
+ "service_type",
6
+ "instance_id",
7
+ "window",
8
+ ];
3
9
  /**
4
10
  * Formats service usage data as Prometheus text exposition using prom-client.
5
11
  * Emits gauges `axusage_utilization_percent` and `axusage_usage_rate` per window.
@@ -9,13 +15,13 @@ export async function formatPrometheusMetrics(data, now) {
9
15
  const utilizationGauge = new Gauge({
10
16
  name: "axusage_utilization_percent",
11
17
  help: "Current utilization percentage by service/window",
12
- labelNames: ["service", "service_type", "instance_id", "window"],
18
+ labelNames: [...LABEL_NAMES],
13
19
  registers: [registry],
14
20
  });
15
21
  const rateGauge = new Gauge({
16
22
  name: "axusage_usage_rate",
17
23
  help: "Usage rate (utilization / elapsed fraction of period); >1 means over budget",
18
- labelNames: ["service", "service_type", "instance_id", "window"],
24
+ labelNames: [...LABEL_NAMES],
19
25
  registers: [registry],
20
26
  });
21
27
  for (const entry of data) {
@@ -1 +1 @@
1
- {"version":3,"file":"format-prometheus-metrics.js","sourceRoot":"","sources":["../../src/utils/format-prometheus-metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAiC,EACjC,GAAW;IAEX,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAEhC,MAAM,gBAAgB,GAAG,IAAI,KAAK,CAAC;QACjC,IAAI,EAAE,6BAA6B;QACnC,IAAI,EAAE,kDAAkD;QACxD,UAAU,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC;QAChE,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC;QAC1B,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,6EAA6E;QACnF,UAAU,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC;QAChE,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB,CAAC,CAAC;IAEH,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG;gBACb,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,YAAY,EAAE,KAAK,CAAC,WAAW;gBAC/B,WAAW,EAAE,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW;gBAClD,MAAM,EAAE,CAAC,CAAC,IAAI;aACf,CAAC;YACF,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YAE5C,MAAM,IAAI,GAAG,kBAAkB,CAC7B,CAAC,CAAC,WAAW,EACb,CAAC,CAAC,QAAQ,EACV,CAAC,CAAC,gBAAgB,EAClB,GAAG,CACJ,CAAC;YACF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"format-prometheus-metrics.js","sourceRoot":"","sources":["../../src/utils/format-prometheus-metrics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,GAAG;IAClB,SAAS;IACT,cAAc;IACd,aAAa;IACb,QAAQ;CACA,CAAC;AAIX;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAiC,EACjC,GAAW;IAEX,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAEhC,MAAM,gBAAgB,GAAG,IAAI,KAAK,CAAC;QACjC,IAAI,EAAE,6BAA6B;QACnC,IAAI,EAAE,kDAAkD;QACxD,UAAU,EAAE,CAAC,GAAG,WAAW,CAAC;QAC5B,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC;QAC1B,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,6EAA6E;QACnF,UAAU,EAAE,CAAC,GAAG,WAAW,CAAC;QAC5B,SAAS,EAAE,CAAC,QAAQ,CAAC;KACtB,CAAC,CAAC;IAEH,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAiB;gBAC3B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,YAAY,EAAE,KAAK,CAAC,WAAW;gBAC/B,WAAW,EAAE,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW;gBAClD,MAAM,EAAE,CAAC,CAAC,IAAI;aACf,CAAC;YACF,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YAE5C,MAAM,IAAI,GAAG,kBAAkB,CAC7B,CAAC,CAAC,WAAW,EACb,CAAC,CAAC,QAAQ,EACV,CAAC,CAAC,gBAAgB,EAClB,GAAG,CACJ,CAAC;YACF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import type { ServiceUsageData } from "../types/domain.js";
2
+ import type { ServiceUsageResponse } from "../types/serve-api.js";
2
3
  /**
3
4
  * Formats complete service usage data for human-readable display
4
5
  */
@@ -6,7 +7,7 @@ export declare function formatServiceUsageData(data: ServiceUsageData): string;
6
7
  /**
7
8
  * Converts service usage data to a plain JSON-serializable object
8
9
  */
9
- export declare function toJsonObject(data: ServiceUsageData, now: number): unknown;
10
+ export declare function toJsonObject(data: ServiceUsageData, now: number): ServiceUsageResponse;
10
11
  /**
11
12
  * Formats service usage data as JSON string
12
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"format-service-usage.d.ts","sourceRoot":"","sources":["../../src/utils/format-service-usage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AAuDxE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAqBrE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAuBzE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAG3E;AAoCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAGxE"}
1
+ {"version":3,"file":"format-service-usage.d.ts","sourceRoot":"","sources":["../../src/utils/format-service-usage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAuDlE;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAqBrE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE,MAAM,GACV,oBAAoB,CAuBtB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAG3E;AAoCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAGxE"}
@@ -72,16 +72,16 @@ export function toJsonObject(data, now) {
72
72
  return {
73
73
  service: data.service,
74
74
  serviceType: data.serviceType,
75
- ...(data.instanceId !== undefined && { instanceId: data.instanceId }),
75
+ instanceId: data.instanceId,
76
76
  planType: data.planType,
77
77
  windows: data.windows.map((w) => {
78
78
  const rate = calculateUsageRate(w.utilization, w.resetsAt, w.periodDurationMs, now);
79
79
  return {
80
80
  name: w.name,
81
81
  utilization: w.utilization,
82
+ periodDurationMs: w.periodDurationMs,
82
83
  rate,
83
84
  resetsAt: w.resetsAt?.toISOString(),
84
- periodDurationMs: w.periodDurationMs,
85
85
  };
86
86
  }),
87
87
  metadata: data.metadata,