@aforoai/metering 1.0.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -9
- package/dist/cjs/buffer.d.ts +7 -1
- package/dist/cjs/buffer.d.ts.map +1 -1
- package/dist/cjs/buffer.js +11 -3
- package/dist/cjs/buffer.js.map +1 -1
- package/dist/cjs/client.d.ts +27 -11
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +212 -55
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/idempotency.d.ts +9 -9
- package/dist/cjs/idempotency.js +9 -9
- package/dist/cjs/index.d.ts +8 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +20 -19
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/limits.d.ts +47 -7
- package/dist/cjs/limits.d.ts.map +1 -1
- package/dist/cjs/limits.js +65 -10
- package/dist/cjs/limits.js.map +1 -1
- package/dist/cjs/middleware/common.d.ts +8 -2
- package/dist/cjs/middleware/common.d.ts.map +1 -1
- package/dist/cjs/middleware/common.js +12 -4
- package/dist/cjs/middleware/common.js.map +1 -1
- package/dist/cjs/middleware/express.d.ts +1 -1
- package/dist/cjs/middleware/express.d.ts.map +1 -1
- package/dist/cjs/middleware/express.js +8 -8
- package/dist/cjs/middleware/express.js.map +1 -1
- package/dist/cjs/middleware/fastify.d.ts +1 -1
- package/dist/cjs/middleware/fastify.d.ts.map +1 -1
- package/dist/cjs/middleware/fastify.js +8 -8
- package/dist/cjs/middleware/fastify.js.map +1 -1
- package/dist/cjs/middleware/koa.d.ts +1 -1
- package/dist/cjs/middleware/koa.d.ts.map +1 -1
- package/dist/cjs/middleware/koa.js +8 -8
- package/dist/cjs/middleware/koa.js.map +1 -1
- package/dist/cjs/transport.d.ts +4 -2
- package/dist/cjs/transport.d.ts.map +1 -1
- package/dist/cjs/transport.js +75 -5
- package/dist/cjs/transport.js.map +1 -1
- package/dist/cjs/types.d.ts +53 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/buffer.js +11 -3
- package/dist/esm/buffer.js.map +1 -1
- package/dist/esm/client.js +209 -52
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/idempotency.js +9 -9
- package/dist/esm/index.js +7 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/limits.js +62 -10
- package/dist/esm/limits.js.map +1 -1
- package/dist/esm/middleware/common.js +11 -4
- package/dist/esm/middleware/common.js.map +1 -1
- package/dist/esm/middleware/express.js +3 -3
- package/dist/esm/middleware/express.js.map +1 -1
- package/dist/esm/middleware/fastify.js +3 -3
- package/dist/esm/middleware/fastify.js.map +1 -1
- package/dist/esm/middleware/koa.js +3 -3
- package/dist/esm/middleware/koa.js.map +1 -1
- package/dist/esm/package.json +1 -0
- package/dist/esm/transport.js +75 -5
- package/dist/esm/transport.js.map +1 -1
- package/dist/types/buffer.d.ts +7 -1
- package/dist/types/buffer.d.ts.map +1 -1
- package/dist/types/client.d.ts +27 -11
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/idempotency.d.ts +9 -9
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/limits.d.ts +47 -7
- package/dist/types/limits.d.ts.map +1 -1
- package/dist/types/middleware/common.d.ts +8 -2
- package/dist/types/middleware/common.d.ts.map +1 -1
- package/dist/types/middleware/express.d.ts +1 -1
- package/dist/types/middleware/express.d.ts.map +1 -1
- package/dist/types/middleware/fastify.d.ts +1 -1
- package/dist/types/middleware/fastify.d.ts.map +1 -1
- package/dist/types/middleware/koa.d.ts +1 -1
- package/dist/types/middleware/koa.d.ts.map +1 -1
- package/dist/types/transport.d.ts +4 -2
- package/dist/types/transport.d.ts.map +1 -1
- package/dist/types/types.d.ts +53 -1
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +22 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,iBAwE3E"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fastifyPlugin = fastifyPlugin;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const client_js_1 = require("../client.js");
|
|
5
|
+
const common_js_1 = require("./common.js");
|
|
6
6
|
const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
7
7
|
/**
|
|
8
8
|
* Fastify plugin that automatically captures API usage events.
|
|
@@ -15,7 +15,7 @@ const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
async function fastifyPlugin(fastify, options) {
|
|
18
|
-
const client = new
|
|
18
|
+
const client = new client_js_1.AforoClient({
|
|
19
19
|
apiKey: options.apiKey,
|
|
20
20
|
baseUrl: options.baseUrl,
|
|
21
21
|
...options.clientOptions,
|
|
@@ -27,13 +27,13 @@ async function fastifyPlugin(fastify, options) {
|
|
|
27
27
|
const path = request.url || '/';
|
|
28
28
|
const method = request.method || 'UNKNOWN';
|
|
29
29
|
const statusCode = reply.statusCode || 0;
|
|
30
|
-
if ((0,
|
|
30
|
+
if ((0, common_js_1.isPreflight)(method))
|
|
31
31
|
return done();
|
|
32
32
|
if (excludePaths.some((p) => path.startsWith(p)))
|
|
33
33
|
return done();
|
|
34
34
|
if (excludeStatusCodes.includes(statusCode))
|
|
35
35
|
return done();
|
|
36
|
-
const metricName = (0,
|
|
36
|
+
const metricName = (0, common_js_1.resolveMetricName)(options, request, reply);
|
|
37
37
|
let quantity;
|
|
38
38
|
if (typeof options.quantity === 'function') {
|
|
39
39
|
quantity = options.quantity(request, reply);
|
|
@@ -50,7 +50,7 @@ async function fastifyPlugin(fastify, options) {
|
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
// Never the caller's X-Api-Key: that is a secret, not a customer id.
|
|
53
|
-
customerId = (0,
|
|
53
|
+
customerId = (0, common_js_1.firstNonEmpty)(request.user?.id, request.headers?.['x-customer-id']);
|
|
54
54
|
}
|
|
55
55
|
if (!customerId)
|
|
56
56
|
return done();
|
|
@@ -69,8 +69,8 @@ async function fastifyPlugin(fastify, options) {
|
|
|
69
69
|
quantity,
|
|
70
70
|
metadata,
|
|
71
71
|
productType: options.productType,
|
|
72
|
-
endpointPath: (0,
|
|
73
|
-
httpMethod: method,
|
|
72
|
+
endpointPath: (0, common_js_1.endpointPathOf)(path),
|
|
73
|
+
httpMethod: (0, common_js_1.httpMethodOf)(method),
|
|
74
74
|
statusCode,
|
|
75
75
|
...(typeof elapsed === 'number' ? { responseTimeMs: Math.round(elapsed) } : {}),
|
|
76
76
|
}).catch(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":";;AAgBA,sCAwEC;AAxFD,
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,IAUR,KAAK,GAAG,EAAE,MAAM,GAAG,mBAuDlE"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.koaMiddleware = koaMiddleware;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const client_js_1 = require("../client.js");
|
|
5
|
+
const common_js_1 = require("./common.js");
|
|
6
6
|
const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
7
7
|
/**
|
|
8
8
|
* Koa middleware that automatically captures API usage events.
|
|
@@ -15,7 +15,7 @@ const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
function koaMiddleware(options) {
|
|
18
|
-
const client = new
|
|
18
|
+
const client = new client_js_1.AforoClient({
|
|
19
19
|
apiKey: options.apiKey,
|
|
20
20
|
baseUrl: options.baseUrl,
|
|
21
21
|
...options.clientOptions,
|
|
@@ -29,13 +29,13 @@ function koaMiddleware(options) {
|
|
|
29
29
|
const path = ctx.path || ctx.url || '/';
|
|
30
30
|
const method = ctx.method || 'UNKNOWN';
|
|
31
31
|
const statusCode = ctx.status || 0;
|
|
32
|
-
if ((0,
|
|
32
|
+
if ((0, common_js_1.isPreflight)(method))
|
|
33
33
|
return;
|
|
34
34
|
if (excludePaths.some((p) => path.startsWith(p)))
|
|
35
35
|
return;
|
|
36
36
|
if (excludeStatusCodes.includes(statusCode))
|
|
37
37
|
return;
|
|
38
|
-
const metricName = (0,
|
|
38
|
+
const metricName = (0, common_js_1.resolveMetricName)(options, ctx.request, ctx.response);
|
|
39
39
|
let quantity;
|
|
40
40
|
if (typeof options.quantity === 'function') {
|
|
41
41
|
quantity = options.quantity(ctx.request, ctx.response);
|
|
@@ -52,7 +52,7 @@ function koaMiddleware(options) {
|
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
54
|
// Never the caller's X-Api-Key: that is a secret, not a customer id.
|
|
55
|
-
customerId = (0,
|
|
55
|
+
customerId = (0, common_js_1.firstNonEmpty)(ctx.state?.user?.id, ctx.get('x-customer-id'));
|
|
56
56
|
}
|
|
57
57
|
if (!customerId)
|
|
58
58
|
return;
|
|
@@ -68,8 +68,8 @@ function koaMiddleware(options) {
|
|
|
68
68
|
quantity,
|
|
69
69
|
metadata,
|
|
70
70
|
productType: options.productType,
|
|
71
|
-
endpointPath: (0,
|
|
72
|
-
httpMethod: method,
|
|
71
|
+
endpointPath: (0, common_js_1.endpointPathOf)(path),
|
|
72
|
+
httpMethod: (0, common_js_1.httpMethodOf)(method),
|
|
73
73
|
statusCode,
|
|
74
74
|
responseTimeMs: Date.now() - startTime,
|
|
75
75
|
}).catch(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":";;AAgBA,sCAiEC;AAjFD,
|
|
1
|
+
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolvedEvent, FlushResult } from './types';
|
|
1
|
+
import { ResolvedEvent, FlushResult } from './types.js';
|
|
2
2
|
export interface TransportOptions {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
apiKey: string;
|
|
@@ -12,7 +12,9 @@ export interface TransportOptions {
|
|
|
12
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
13
|
* - Retry on 5xx, 408, 429 with exponential backoff
|
|
14
14
|
* - Respects Retry-After header on 429
|
|
15
|
-
* - No retry on 4xx (bad input)
|
|
15
|
+
* - No retry on 4xx (bad input); the server's error message is surfaced
|
|
16
|
+
* - A 2xx whose body reports per-event failures (`errors[]`) is a partial
|
|
17
|
+
* failure: those events are reported back as rejected
|
|
16
18
|
* - AbortController timeout per request
|
|
17
19
|
*/
|
|
18
20
|
export declare class Transport {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgB,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgB,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE,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;;;;;;;;;;GAUG;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;IAoFzD;;;;;;;;OAQG;IACG,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBlE,OAAO,CAAC,KAAK;CAGd"}
|
package/dist/cjs/transport.js
CHANGED
|
@@ -7,7 +7,9 @@ exports.Transport = void 0;
|
|
|
7
7
|
* - POST /v1/ingest/batch with X-API-Key: {apiKey} (never Authorization: Bearer -- the ingestor parses Bearer as a JWT and rejects the request 401)
|
|
8
8
|
* - Retry on 5xx, 408, 429 with exponential backoff
|
|
9
9
|
* - Respects Retry-After header on 429
|
|
10
|
-
* - No retry on 4xx (bad input)
|
|
10
|
+
* - No retry on 4xx (bad input); the server's error message is surfaced
|
|
11
|
+
* - A 2xx whose body reports per-event failures (`errors[]`) is a partial
|
|
12
|
+
* failure: those events are reported back as rejected
|
|
11
13
|
* - AbortController timeout per request
|
|
12
14
|
*/
|
|
13
15
|
class Transport {
|
|
@@ -40,12 +42,29 @@ class Transport {
|
|
|
40
42
|
});
|
|
41
43
|
clearTimeout(timer);
|
|
42
44
|
if (response.ok) {
|
|
45
|
+
// A 2xx can still carry per-event rejections (`failed` / `errors[]`).
|
|
46
|
+
const rejected = await readRejectedEvents(response, events.length);
|
|
47
|
+
if (rejected.count > 0) {
|
|
48
|
+
return {
|
|
49
|
+
sent: events.length - rejected.count,
|
|
50
|
+
failed: rejected.count,
|
|
51
|
+
reason: 'rejected',
|
|
52
|
+
...(rejected.identified ? { rejected: rejected.errors } : {}),
|
|
53
|
+
...(rejected.errors[0] ? { message: rejected.errors[0].message } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
43
56
|
return { sent: events.length, failed: 0 };
|
|
44
57
|
}
|
|
45
58
|
// 4xx (except 408, 429) — bad input, don't retry
|
|
46
59
|
if (response.status >= 400 && response.status < 500
|
|
47
60
|
&& response.status !== 408 && response.status !== 429) {
|
|
48
|
-
|
|
61
|
+
const message = await readErrorMessage(response);
|
|
62
|
+
return {
|
|
63
|
+
sent: 0,
|
|
64
|
+
failed: events.length,
|
|
65
|
+
reason: 'rejected',
|
|
66
|
+
message: `HTTP ${response.status}${message ? `: ${message}` : ''}`,
|
|
67
|
+
};
|
|
49
68
|
}
|
|
50
69
|
// 429 — respect Retry-After header
|
|
51
70
|
if (response.status === 429) {
|
|
@@ -63,7 +82,7 @@ class Transport {
|
|
|
63
82
|
await this.sleep(this.retryBaseMs * Math.pow(2, attempt));
|
|
64
83
|
continue;
|
|
65
84
|
}
|
|
66
|
-
return { sent: 0, failed: events.length };
|
|
85
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
67
86
|
}
|
|
68
87
|
catch (err) {
|
|
69
88
|
// Network error or abort — retry
|
|
@@ -71,10 +90,10 @@ class Transport {
|
|
|
71
90
|
await this.sleep(this.retryBaseMs * Math.pow(2, attempt));
|
|
72
91
|
continue;
|
|
73
92
|
}
|
|
74
|
-
return { sent: 0, failed: events.length };
|
|
93
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
75
94
|
}
|
|
76
95
|
}
|
|
77
|
-
return { sent: 0, failed: events.length };
|
|
96
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
78
97
|
}
|
|
79
98
|
/**
|
|
80
99
|
* Send a single event in its own request, once, best-effort.
|
|
@@ -113,4 +132,55 @@ class Transport {
|
|
|
113
132
|
}
|
|
114
133
|
}
|
|
115
134
|
exports.Transport = Transport;
|
|
135
|
+
async function readJson(response) {
|
|
136
|
+
try {
|
|
137
|
+
if (typeof response?.json === 'function')
|
|
138
|
+
return unwrapEnvelope(await response.json());
|
|
139
|
+
if (typeof response?.text === 'function')
|
|
140
|
+
return unwrapEnvelope(JSON.parse(await response.text()));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Empty or non-JSON body — nothing to report.
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
/** Per-event rejections reported inside a 2xx batch response. */
|
|
148
|
+
async function readRejectedEvents(response, batchSize) {
|
|
149
|
+
const body = await readJson(response);
|
|
150
|
+
const none = { count: 0, identified: false, errors: [] };
|
|
151
|
+
if (!body || typeof body !== 'object')
|
|
152
|
+
return none;
|
|
153
|
+
const seen = new Set();
|
|
154
|
+
const errors = [];
|
|
155
|
+
if (Array.isArray(body.errors)) {
|
|
156
|
+
for (const e of body.errors) {
|
|
157
|
+
const index = Number(e?.index);
|
|
158
|
+
if (!Number.isInteger(index) || index < 0 || index >= batchSize || seen.has(index))
|
|
159
|
+
continue;
|
|
160
|
+
seen.add(index);
|
|
161
|
+
errors.push({ index, message: String(e?.message ?? 'rejected by the ingestor').slice(0, 500) });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const reported = typeof body.failed === 'number' && body.failed > 0 ? Math.floor(body.failed) : 0;
|
|
165
|
+
const count = Math.min(batchSize, Math.max(reported, errors.length));
|
|
166
|
+
// Only name events when the indexes account for every reported failure.
|
|
167
|
+
return { count, identified: errors.length > 0 && errors.length === count, errors };
|
|
168
|
+
}
|
|
169
|
+
/** Best-effort server explanation for a rejected request. */
|
|
170
|
+
async function readErrorMessage(response) {
|
|
171
|
+
const body = await readJson(response);
|
|
172
|
+
if (!body || typeof body !== 'object')
|
|
173
|
+
return undefined;
|
|
174
|
+
const first = Array.isArray(body.errors) ? body.errors[0] : undefined;
|
|
175
|
+
const text = first?.message ?? body.detail ?? body.message ?? body.error ?? body.title;
|
|
176
|
+
return typeof text === 'string' && text ? text.slice(0, 500) : undefined;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The ingestor wraps every 2xx JSON body in `{success, data, meta}`. Returns
|
|
180
|
+
* the inner `data` object when present, else the body unchanged (bare shape).
|
|
181
|
+
*/
|
|
182
|
+
function unwrapEnvelope(body) {
|
|
183
|
+
const data = body && typeof body === 'object' && !Array.isArray(body) ? body.data : undefined;
|
|
184
|
+
return data && typeof data === 'object' && !Array.isArray(data) ? data : body;
|
|
185
|
+
}
|
|
116
186
|
//# sourceMappingURL=transport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":";;;AAUA
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a buffered event was permanently dropped by the SDK.
|
|
3
|
+
* - 'overflow': the ring buffer was full — the OLDEST event was evicted to make room.
|
|
4
|
+
* - 'retry_exhausted': a batch failed after all transport retries (ingest outage).
|
|
5
|
+
* - 'rejected': the ingestor rejected the batch with a non-retryable 4xx, or
|
|
6
|
+
* rejected this event individually in a partially accepted batch.
|
|
7
|
+
* - 'invalid': the event failed a client-side check at track() (blank
|
|
8
|
+
* customerId/metricName, quantity <= 0, a field over the ingestor's size
|
|
9
|
+
* limit, a malformed occurredAt) and was never buffered or sent.
|
|
10
|
+
*/
|
|
11
|
+
export type DropReason = 'overflow' | 'retry_exhausted' | 'rejected' | 'invalid';
|
|
1
12
|
/** Options for creating an AforoClient instance. */
|
|
2
13
|
export interface AforoOptions {
|
|
3
14
|
/** Aforo API key for authentication. */
|
|
@@ -26,6 +37,17 @@ export interface AforoOptions {
|
|
|
26
37
|
timeout?: number;
|
|
27
38
|
/** Graceful shutdown timeout in milliseconds. Default: 5000 */
|
|
28
39
|
shutdownTimeoutMs?: number;
|
|
40
|
+
/**
|
|
41
|
+
* OPT-IN hook invoked with events the SDK is about to lose permanently
|
|
42
|
+
* (buffer overflow, retry exhaustion, non-retryable rejection, or an event
|
|
43
|
+
* that failed client-side validation — reason 'invalid'), so the
|
|
44
|
+
* app can persist / alert / replay them. Dropped events keep their
|
|
45
|
+
* idempotency keys — re-submitting them via track() after recovery is
|
|
46
|
+
* dedup-safe. Default: none (drops are still counted in droppedCount and
|
|
47
|
+
* WARN-logged). Exceptions thrown by the hook are swallowed — a hook bug
|
|
48
|
+
* can never break flushing.
|
|
49
|
+
*/
|
|
50
|
+
onDrop?: (events: ResolvedEvent[], reason: DropReason) => void;
|
|
29
51
|
}
|
|
30
52
|
/** A usage event to track. */
|
|
31
53
|
export interface TrackEvent {
|
|
@@ -40,12 +62,27 @@ export interface TrackEvent {
|
|
|
40
62
|
* default. Trimmed, uppercased and sent as top-level `productType`.
|
|
41
63
|
*/
|
|
42
64
|
productType?: string;
|
|
43
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Optional idempotency key — supply a STABLE value to dedup retries of the
|
|
67
|
+
* same logical event. Omitted = dedup opt-out: the SDK stamps a unique
|
|
68
|
+
* random key per track() call (still stable across the SDK's own flush
|
|
69
|
+
* retries of the buffered event).
|
|
70
|
+
*/
|
|
44
71
|
idempotencyKey?: string;
|
|
45
72
|
/** When the event occurred. Defaults to now. ISO 8601 string or epoch ms. */
|
|
46
73
|
occurredAt?: string | number;
|
|
47
74
|
/** Arbitrary key-value metadata attached to the event. */
|
|
48
75
|
metadata?: Record<string, string | number | boolean>;
|
|
76
|
+
/**
|
|
77
|
+
* Optional outcome of the request (used by OUTCOME_BASED pricing, which bills
|
|
78
|
+
* each event at the weight set for its status). Events without a status bill
|
|
79
|
+
* at full price. Trimmed and upper-cased by the SDK; blank is treated as absent.
|
|
80
|
+
* Accepted values: SUCCESS, PARTIAL, TIMEOUT, ERROR, VALIDATION_FAILED, FAILED,
|
|
81
|
+
* FAILURE, CANCELLED, PENDING, BLOCKED, HITL_REQUIRED (max 20 chars). Any other
|
|
82
|
+
* value is logged with a warning and omitted (the event is still sent, without
|
|
83
|
+
* a status), because the server would reject the event.
|
|
84
|
+
*/
|
|
85
|
+
executionStatus?: string;
|
|
49
86
|
/** Optional HTTP context, sent as top-level fields. */
|
|
50
87
|
endpointPath?: string;
|
|
51
88
|
httpMethod?: string;
|
|
@@ -61,6 +98,8 @@ export interface ResolvedEvent {
|
|
|
61
98
|
occurredAt: string;
|
|
62
99
|
productType: string;
|
|
63
100
|
metadata?: Record<string, string | number | boolean>;
|
|
101
|
+
/** Normalized (trimmed, upper-cased) execution status; omitted when not set. */
|
|
102
|
+
executionStatus?: string;
|
|
64
103
|
endpointPath?: string;
|
|
65
104
|
httpMethod?: string;
|
|
66
105
|
statusCode?: number;
|
|
@@ -124,5 +163,18 @@ export interface MiddlewareOptions {
|
|
|
124
163
|
export interface FlushResult {
|
|
125
164
|
sent: number;
|
|
126
165
|
failed: number;
|
|
166
|
+
/** Why the batch failed, when failed > 0. Absent on success. */
|
|
167
|
+
reason?: DropReason;
|
|
168
|
+
/**
|
|
169
|
+
* Events the ingestor rejected individually inside a batch it otherwise
|
|
170
|
+
* accepted (per-event `errors[]` in the response). `index` is the position
|
|
171
|
+
* in the sent batch. Present only when the response identified them.
|
|
172
|
+
*/
|
|
173
|
+
rejected?: Array<{
|
|
174
|
+
index: number;
|
|
175
|
+
message: string;
|
|
176
|
+
}>;
|
|
177
|
+
/** Server-provided explanation for a failed batch, when one was returned. */
|
|
178
|
+
message?: string;
|
|
127
179
|
}
|
|
128
180
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/cjs/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IAEf,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/buffer.js
CHANGED
|
@@ -15,17 +15,25 @@ export class RingBuffer {
|
|
|
15
15
|
}
|
|
16
16
|
/** Add an event to the buffer. Returns true if added, false if overflow (oldest dropped). */
|
|
17
17
|
push(event) {
|
|
18
|
-
|
|
18
|
+
return this.pushEvict(event) === null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Add an event to the buffer. On overflow, returns the evicted OLDEST
|
|
22
|
+
* event so the caller can surface the drop; returns null when no
|
|
23
|
+
* eviction occurred.
|
|
24
|
+
*/
|
|
25
|
+
pushEvict(event) {
|
|
26
|
+
let evicted = null;
|
|
19
27
|
if (this.count === this.capacity) {
|
|
20
28
|
// Buffer full — drop oldest (advance head)
|
|
29
|
+
evicted = this.items[this.head];
|
|
21
30
|
this.head = (this.head + 1) % this.capacity;
|
|
22
31
|
this.count--;
|
|
23
|
-
overflow = true;
|
|
24
32
|
}
|
|
25
33
|
this.items[this.tail] = event;
|
|
26
34
|
this.tail = (this.tail + 1) % this.capacity;
|
|
27
35
|
this.count++;
|
|
28
|
-
return
|
|
36
|
+
return evicted;
|
|
29
37
|
}
|
|
30
38
|
/** Drain all events from the buffer. Returns a new array and clears the buffer. */
|
|
31
39
|
drain() {
|
package/dist/esm/buffer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../src/buffer.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAOrB,YAAY,WAAmB,KAAM;QAJ7B,SAAI,GAAG,CAAC,CAAC;QACT,SAAI,GAAG,CAAC,CAAC;QACT,UAAK,GAAG,CAAC,CAAC;QAGhB,IAAI,QAAQ,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,6FAA6F;IAC7F,IAAI,CAAC,KAAoB;QACvB,IAAI,
|
|
1
|
+
{"version":3,"file":"buffer.js","sourceRoot":"","sources":["../../src/buffer.ts"],"names":[],"mappings":"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"}
|