@aforoai/metering 1.0.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.
Files changed (98) hide show
  1. package/README.md +88 -0
  2. package/dist/cjs/buffer.d.ts +27 -0
  3. package/dist/cjs/buffer.d.ts.map +1 -0
  4. package/dist/cjs/buffer.js +75 -0
  5. package/dist/cjs/buffer.js.map +1 -0
  6. package/dist/cjs/client.d.ts +86 -0
  7. package/dist/cjs/client.d.ts.map +1 -0
  8. package/dist/cjs/client.js +301 -0
  9. package/dist/cjs/client.js.map +1 -0
  10. package/dist/cjs/idempotency.d.ts +21 -0
  11. package/dist/cjs/idempotency.d.ts.map +1 -0
  12. package/dist/cjs/idempotency.js +31 -0
  13. package/dist/cjs/idempotency.js.map +1 -0
  14. package/dist/cjs/index.d.ts +9 -0
  15. package/dist/cjs/index.d.ts.map +1 -0
  16. package/dist/cjs/index.js +23 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/limits.d.ts +80 -0
  19. package/dist/cjs/limits.d.ts.map +1 -0
  20. package/dist/cjs/limits.js +143 -0
  21. package/dist/cjs/limits.js.map +1 -0
  22. package/dist/cjs/middleware/common.d.ts +22 -0
  23. package/dist/cjs/middleware/common.d.ts.map +1 -0
  24. package/dist/cjs/middleware/common.js +48 -0
  25. package/dist/cjs/middleware/common.js.map +1 -0
  26. package/dist/cjs/middleware/express.d.ts +15 -0
  27. package/dist/cjs/middleware/express.d.ts.map +1 -0
  28. package/dist/cjs/middleware/express.js +104 -0
  29. package/dist/cjs/middleware/express.js.map +1 -0
  30. package/dist/cjs/middleware/fastify.d.ts +13 -0
  31. package/dist/cjs/middleware/fastify.d.ts.map +1 -0
  32. package/dist/cjs/middleware/fastify.js +90 -0
  33. package/dist/cjs/middleware/fastify.js.map +1 -0
  34. package/dist/cjs/middleware/koa.d.ts +13 -0
  35. package/dist/cjs/middleware/koa.d.ts.map +1 -0
  36. package/dist/cjs/middleware/koa.js +82 -0
  37. package/dist/cjs/middleware/koa.js.map +1 -0
  38. package/dist/cjs/path-normalizer.d.ts +15 -0
  39. package/dist/cjs/path-normalizer.d.ts.map +1 -0
  40. package/dist/cjs/path-normalizer.js +49 -0
  41. package/dist/cjs/path-normalizer.js.map +1 -0
  42. package/dist/cjs/transport.d.ts +39 -0
  43. package/dist/cjs/transport.d.ts.map +1 -0
  44. package/dist/cjs/transport.js +116 -0
  45. package/dist/cjs/transport.js.map +1 -0
  46. package/dist/cjs/types.d.ts +128 -0
  47. package/dist/cjs/types.d.ts.map +1 -0
  48. package/dist/cjs/types.js +3 -0
  49. package/dist/cjs/types.js.map +1 -0
  50. package/dist/esm/buffer.js +71 -0
  51. package/dist/esm/buffer.js.map +1 -0
  52. package/dist/esm/client.js +297 -0
  53. package/dist/esm/client.js.map +1 -0
  54. package/dist/esm/idempotency.js +27 -0
  55. package/dist/esm/idempotency.js.map +1 -0
  56. package/dist/esm/index.js +9 -0
  57. package/dist/esm/index.js.map +1 -0
  58. package/dist/esm/limits.js +138 -0
  59. package/dist/esm/limits.js.map +1 -0
  60. package/dist/esm/middleware/common.js +41 -0
  61. package/dist/esm/middleware/common.js.map +1 -0
  62. package/dist/esm/middleware/express.js +100 -0
  63. package/dist/esm/middleware/express.js.map +1 -0
  64. package/dist/esm/middleware/fastify.js +87 -0
  65. package/dist/esm/middleware/fastify.js.map +1 -0
  66. package/dist/esm/middleware/koa.js +79 -0
  67. package/dist/esm/middleware/koa.js.map +1 -0
  68. package/dist/esm/path-normalizer.js +46 -0
  69. package/dist/esm/path-normalizer.js.map +1 -0
  70. package/dist/esm/transport.js +112 -0
  71. package/dist/esm/transport.js.map +1 -0
  72. package/dist/esm/types.js +2 -0
  73. package/dist/esm/types.js.map +1 -0
  74. package/dist/types/buffer.d.ts +27 -0
  75. package/dist/types/buffer.d.ts.map +1 -0
  76. package/dist/types/client.d.ts +86 -0
  77. package/dist/types/client.d.ts.map +1 -0
  78. package/dist/types/idempotency.d.ts +21 -0
  79. package/dist/types/idempotency.d.ts.map +1 -0
  80. package/dist/types/index.d.ts +9 -0
  81. package/dist/types/index.d.ts.map +1 -0
  82. package/dist/types/limits.d.ts +80 -0
  83. package/dist/types/limits.d.ts.map +1 -0
  84. package/dist/types/middleware/common.d.ts +22 -0
  85. package/dist/types/middleware/common.d.ts.map +1 -0
  86. package/dist/types/middleware/express.d.ts +15 -0
  87. package/dist/types/middleware/express.d.ts.map +1 -0
  88. package/dist/types/middleware/fastify.d.ts +13 -0
  89. package/dist/types/middleware/fastify.d.ts.map +1 -0
  90. package/dist/types/middleware/koa.d.ts +13 -0
  91. package/dist/types/middleware/koa.d.ts.map +1 -0
  92. package/dist/types/path-normalizer.d.ts +15 -0
  93. package/dist/types/path-normalizer.d.ts.map +1 -0
  94. package/dist/types/transport.d.ts +39 -0
  95. package/dist/types/transport.d.ts.map +1 -0
  96. package/dist/types/types.d.ts +128 -0
  97. package/dist/types/types.d.ts.map +1 -0
  98. package/package.json +74 -0
@@ -0,0 +1,15 @@
1
+ import { MiddlewareOptions } from '../types';
2
+ /**
3
+ * Express middleware that automatically captures API usage events.
4
+ *
5
+ * Hooks into `res.on('finish')` — runs AFTER the response is sent to the client.
6
+ * Zero latency impact on the API call itself.
7
+ *
8
+ * ```typescript
9
+ * import { expressMiddleware } from '@aforoai/metering/middleware/express';
10
+ * app.use(expressMiddleware({ apiKey: process.env.AFORO_API_KEY, productType: 'API' }));
11
+ * ```
12
+ */
13
+ export declare function expressMiddleware(options: MiddlewareOptions): (req: any, res: any, next: any) => void;
14
+ export declare const middleware: typeof expressMiddleware;
15
+ //# sourceMappingURL=express.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK7C;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,IAUlB,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAgEtE;AAeD,eAAO,MAAM,UAAU,0BAAoB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { MiddlewareOptions } from '../types';
2
+ /**
3
+ * Fastify plugin that automatically captures API usage events.
4
+ *
5
+ * Uses the `onResponse` hook — runs AFTER the response is sent.
6
+ *
7
+ * ```typescript
8
+ * import { fastifyPlugin } from '@aforoai/metering/middleware/fastify';
9
+ * fastify.register(fastifyPlugin, { apiKey: process.env.AFORO_API_KEY, productType: 'API' });
10
+ * ```
11
+ */
12
+ export declare function fastifyPlugin(fastify: any, options: MiddlewareOptions): Promise<void>;
13
+ //# sourceMappingURL=fastify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK7C;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,iBAwE3E"}
@@ -0,0 +1,13 @@
1
+ import { MiddlewareOptions } from '../types';
2
+ /**
3
+ * Koa middleware that automatically captures API usage events.
4
+ *
5
+ * Captures after `await next()` completes — runs after the response is generated.
6
+ *
7
+ * ```typescript
8
+ * import { koaMiddleware } from '@aforoai/metering/middleware/koa';
9
+ * app.use(koaMiddleware({ apiKey: process.env.AFORO_API_KEY, productType: 'API' }));
10
+ * ```
11
+ */
12
+ export declare function koaMiddleware(options: MiddlewareOptions): (ctx: any, next: any) => Promise<void>;
13
+ //# sourceMappingURL=koa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK7C;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,IAUR,KAAK,GAAG,EAAE,MAAM,GAAG,mBAuDlE"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Normalize a URL path by replacing dynamic segments with parameter placeholders.
3
+ *
4
+ * If a framework route template is available (e.g., Express `req.route?.path`),
5
+ * use that directly — it already has :param placeholders.
6
+ *
7
+ * Otherwise, apply heuristic normalization:
8
+ * /users/123 → /users/:id
9
+ * /orders/abc-def → /orders/:id
10
+ * /v1/items/42/reviews/7 → /v1/items/:id/reviews/:id
11
+ *
12
+ * UUIDs, numeric IDs, and alphanumeric slugs are detected and replaced.
13
+ */
14
+ export declare function normalizePath(actualPath: string, routeTemplate?: string): string;
15
+ //# sourceMappingURL=path-normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-normalizer.d.ts","sourceRoot":"","sources":["../../src/path-normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAuBR"}
@@ -0,0 +1,39 @@
1
+ import { ResolvedEvent, FlushResult } from './types';
2
+ export interface TransportOptions {
3
+ baseUrl: string;
4
+ apiKey: string;
5
+ timeout: number;
6
+ maxRetries: number;
7
+ retryBaseMs: number;
8
+ }
9
+ /**
10
+ * HTTP transport that sends batched usage events to the Aforo ingestor.
11
+ *
12
+ * - POST /v1/ingest/batch with X-API-Key: {apiKey} (never Authorization: Bearer -- the ingestor parses Bearer as a JWT and rejects the request 401)
13
+ * - Retry on 5xx, 408, 429 with exponential backoff
14
+ * - Respects Retry-After header on 429
15
+ * - No retry on 4xx (bad input)
16
+ * - AbortController timeout per request
17
+ */
18
+ export declare class Transport {
19
+ private readonly baseUrl;
20
+ private readonly apiKey;
21
+ private readonly timeout;
22
+ private readonly maxRetries;
23
+ private readonly retryBaseMs;
24
+ constructor(options: TransportOptions);
25
+ /** Send a batch of events. Returns the number sent and failed. */
26
+ send(events: ResolvedEvent[]): Promise<FlushResult>;
27
+ /**
28
+ * Send a single event in its own request, once, best-effort.
29
+ *
30
+ * Used for session heartbeats: a heartbeat must never share a batch with
31
+ * usage (a large batch takes the high-throughput path, which does not
32
+ * intercept heartbeats), and a lost heartbeat is simply superseded by the
33
+ * next one -- so there is no retry and every failure is swallowed.
34
+ * Resolves to true when the ingestor accepted the request.
35
+ */
36
+ sendSingleBestEffort(event: ResolvedEvent): Promise<boolean>;
37
+ private sleep;
38
+ }
39
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgB,WAAW,EAAE,MAAM,SAAS,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,EAAE,gBAAgB;IAQrC,kEAAkE;IAC5D,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAmEzD;;;;;;;;OAQG;IACG,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBlE,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,128 @@
1
+ /** Options for creating an AforoClient instance. */
2
+ export interface AforoOptions {
3
+ /** Aforo API key for authentication. */
4
+ apiKey: string;
5
+ /** Base URL for the Aforo ingestor service. Defaults to https://api.aforo.ai */
6
+ baseUrl?: string;
7
+ /**
8
+ * Default product type stamped on every event (top-level `productType`).
9
+ * Required by the Aforo ingestor in production. One of API, AGENTIC_API,
10
+ * AI_AGENT, MCP_SERVER, GRPC_API, GRAPHQL_API, WEBSOCKET_API, MQTT_BROKER.
11
+ * Values are trimmed, uppercased and passed through. Default: "API".
12
+ * A per-event `productType` on `track()` overrides this.
13
+ */
14
+ productType?: string;
15
+ /** Maximum events to buffer before flushing (capped at 1000, the ingestor's batch limit). Default: 50 */
16
+ flushCount?: number;
17
+ /** Flush interval in milliseconds. Default: 5000 (5 seconds) */
18
+ flushInterval?: number;
19
+ /** Maximum events in the ring buffer. Oldest dropped on overflow. Default: 10000 */
20
+ maxQueueSize?: number;
21
+ /** Maximum retries on 5xx/timeout. Default: 3 */
22
+ maxRetries?: number;
23
+ /** Base delay in ms for exponential backoff. Default: 1000 */
24
+ retryBaseMs?: number;
25
+ /** Request timeout in milliseconds. Default: 10000 */
26
+ timeout?: number;
27
+ /** Graceful shutdown timeout in milliseconds. Default: 5000 */
28
+ shutdownTimeoutMs?: number;
29
+ }
30
+ /** A usage event to track. */
31
+ export interface TrackEvent {
32
+ /** Customer identifier (who is being billed). */
33
+ customerId: string;
34
+ /** Metric name (e.g., "api_calls", "ai_tokens", "GET /users"). */
35
+ metricName: string;
36
+ /** Quantity of usage. Must be > 0 (the ingestor rejects 0). Default: 1 */
37
+ quantity?: number;
38
+ /**
39
+ * Product type for this event. Overrides the client-level `productType`
40
+ * default. Trimmed, uppercased and sent as top-level `productType`.
41
+ */
42
+ productType?: string;
43
+ /** Optional override for idempotency key. Auto-generated if omitted. */
44
+ idempotencyKey?: string;
45
+ /** When the event occurred. Defaults to now. ISO 8601 string or epoch ms. */
46
+ occurredAt?: string | number;
47
+ /** Arbitrary key-value metadata attached to the event. */
48
+ metadata?: Record<string, string | number | boolean>;
49
+ /** Optional HTTP context, sent as top-level fields. */
50
+ endpointPath?: string;
51
+ httpMethod?: string;
52
+ statusCode?: number;
53
+ responseTimeMs?: number;
54
+ }
55
+ /** Internal event with all fields resolved (the exact wire shape). */
56
+ export interface ResolvedEvent {
57
+ customerId: string;
58
+ metricName: string;
59
+ quantity: number;
60
+ idempotencyKey: string;
61
+ occurredAt: string;
62
+ productType: string;
63
+ metadata?: Record<string, string | number | boolean>;
64
+ endpointPath?: string;
65
+ httpMethod?: string;
66
+ statusCode?: number;
67
+ responseTimeMs?: number;
68
+ sessionId?: string;
69
+ sessionBoundary?: 'HEARTBEAT' | 'SESSION_END';
70
+ }
71
+ /** Batch request body sent to POST /v1/ingest/batch. */
72
+ export interface BatchRequest {
73
+ events: ResolvedEvent[];
74
+ }
75
+ /** Response from the ingestor batch endpoint. */
76
+ export interface BatchResponse {
77
+ accepted: number;
78
+ duplicates: number;
79
+ failed: number;
80
+ errors: Array<{
81
+ index: number;
82
+ message: string;
83
+ }>;
84
+ killedSessionIds?: string[];
85
+ }
86
+ /** Options for Express/Koa/Fastify middleware. */
87
+ export interface MiddlewareOptions {
88
+ /** Aforo API key. */
89
+ apiKey: string;
90
+ /** Base URL for the ingestor. */
91
+ baseUrl?: string;
92
+ /**
93
+ * Product type stamped on every metered request (top-level `productType`).
94
+ * Default: the client default ("API", or `clientOptions.productType`).
95
+ */
96
+ productType?: string;
97
+ /**
98
+ * Metric to record for each request: a fixed name, or a function of the
99
+ * request/response. Default: `"api_calls"` (DEFAULT_METRIC_NAME).
100
+ *
101
+ * Must name a metric that exists in your Aforo catalog. The ingestor rejects
102
+ * unknown metrics, and one rejected event fails the whole batch it is in.
103
+ */
104
+ metricName?: string | ((req: any, res: any) => string);
105
+ /** Static quantity or function to derive from request/response. Requests with quantity <= 0 are not metered. */
106
+ quantity?: number | ((req: any, res: any) => number);
107
+ /**
108
+ * Aforo customer id: a fixed value, or a function of the request.
109
+ * Default: the authenticated user's id (`req.user.id` / `.sub`), then the
110
+ * `X-Customer-Id` header. Requests with no customer are not metered. The
111
+ * caller's `X-Api-Key` header is never used -- it is a secret, not an id.
112
+ */
113
+ customerId?: string | ((req: any) => string | null);
114
+ /** Paths to exclude from metering. Default: ["/health", "/ready", "/metrics", "/favicon.ico"] */
115
+ excludePaths?: string[];
116
+ /** Status codes to exclude. Default: none */
117
+ excludeStatusCodes?: number[];
118
+ /** Function to extract metadata from request/response. */
119
+ metadata?: (req: any, res: any) => Record<string, string | number | boolean>;
120
+ /** AforoClient options (flushCount, flushInterval, etc.) */
121
+ clientOptions?: Omit<AforoOptions, 'apiKey' | 'baseUrl'>;
122
+ }
123
+ /** Flush result for internal tracking. */
124
+ export interface FlushResult {
125
+ sent: number;
126
+ failed: number;
127
+ }
128
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@aforoai/metering",
3
+ "version": "1.0.0",
4
+ "description": "Aforo usage metering SDK — track API usage events with batching, retry, and framework middleware",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/esm/index.js",
11
+ "require": "./dist/cjs/index.js",
12
+ "types": "./dist/types/index.d.ts"
13
+ },
14
+ "./middleware/express": {
15
+ "import": "./dist/esm/middleware/express.js",
16
+ "require": "./dist/cjs/middleware/express.js",
17
+ "types": "./dist/types/middleware/express.d.ts"
18
+ },
19
+ "./middleware/fastify": {
20
+ "import": "./dist/esm/middleware/fastify.js",
21
+ "require": "./dist/cjs/middleware/fastify.js",
22
+ "types": "./dist/types/middleware/fastify.d.ts"
23
+ },
24
+ "./middleware/koa": {
25
+ "import": "./dist/esm/middleware/koa.js",
26
+ "require": "./dist/cjs/middleware/koa.js",
27
+ "types": "./dist/types/middleware/koa.d.ts"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md"
33
+ ],
34
+ "engines": {
35
+ "node": ">=18.0.0"
36
+ },
37
+ "scripts": {
38
+ "build": "npm run build:cjs && npm run build:esm && npm run build:types",
39
+ "build:cjs": "tsc -p tsconfig.cjs.json",
40
+ "build:esm": "tsc -p tsconfig.esm.json",
41
+ "build:types": "tsc -p tsconfig.types.json",
42
+ "test": "jest --coverage",
43
+ "lint": "tsc --noEmit",
44
+ "prepublishOnly": "npm run lint && npm test && npm run build"
45
+ },
46
+ "devDependencies": {
47
+ "@types/jest": "^29.5.0",
48
+ "@types/node": "^20.0.0",
49
+ "jest": "^29.7.0",
50
+ "ts-jest": "^29.1.0",
51
+ "typescript": "^5.4.0"
52
+ },
53
+ "peerDependencies": {
54
+ "@types/express": ">=4.0.0",
55
+ "@types/koa": ">=2.0.0",
56
+ "fastify": ">=4.0.0"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "@types/express": { "optional": true },
60
+ "@types/koa": { "optional": true },
61
+ "fastify": { "optional": true }
62
+ },
63
+ "keywords": ["aforo", "metering", "usage", "billing", "api", "middleware", "express", "fastify", "koa"],
64
+ "license": "Apache-2.0",
65
+ "repository": {
66
+ "type": "git",
67
+ "url": "git+https://github.com/aforoai/SDKs.git",
68
+ "directory": "aforo-metering-sdks/node"
69
+ },
70
+ "homepage": "https://github.com/aforoai/SDKs/tree/main/aforo-metering-sdks/node#readme",
71
+ "bugs": {
72
+ "url": "https://github.com/aforoai/SDKs/issues"
73
+ }
74
+ }