@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,3 +1,4 @@
|
|
|
1
|
+
import { truncateRequestLabel } from '../limits.js';
|
|
1
2
|
/**
|
|
2
3
|
* Metric recorded for each request when `metricName` is not configured.
|
|
3
4
|
*
|
|
@@ -21,11 +22,17 @@ export function resolveMetricName(options, req, res) {
|
|
|
21
22
|
}
|
|
22
23
|
return options.metricName || DEFAULT_METRIC_NAME;
|
|
23
24
|
}
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Request path without its query string. Read off the incoming request, so an
|
|
27
|
+
* over-long path is cut to the ingestor's limit (512) instead of dropping the
|
|
28
|
+
* event — otherwise a caller could avoid metering with a long URL.
|
|
29
|
+
*/
|
|
27
30
|
export function endpointPathOf(url) {
|
|
28
|
-
return (url.split('?')[0] || '/')
|
|
31
|
+
return truncateRequestLabel('endpointPath', String(url).split('?')[0] || '/');
|
|
32
|
+
}
|
|
33
|
+
/** HTTP method off the incoming request, cut to the ingestor's limit (16). */
|
|
34
|
+
export function httpMethodOf(method) {
|
|
35
|
+
return truncateRequestLabel('httpMethod', String(method));
|
|
29
36
|
}
|
|
30
37
|
/** First non-empty string among the candidates, or null. */
|
|
31
38
|
export function firstNonEmpty(...values) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/middleware/common.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/middleware/common.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAA0B;IACpD,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC;AACpD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,OAA0B,EAAE,GAAQ,EAAE,GAAQ;IAC9E,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,mBAAmB,CAAC;IAC7D,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AAChF,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAAC,GAAG,MAAiB;IAChD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AforoClient } from '../client';
|
|
2
|
-
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf } from './common';
|
|
1
|
+
import { AforoClient } from '../client.js';
|
|
2
|
+
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf, httpMethodOf } from './common.js';
|
|
3
3
|
const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
4
4
|
/**
|
|
5
5
|
* Express middleware that automatically captures API usage events.
|
|
@@ -72,7 +72,7 @@ export function expressMiddleware(options) {
|
|
|
72
72
|
metadata,
|
|
73
73
|
productType: options.productType,
|
|
74
74
|
endpointPath: endpointPathOf(path),
|
|
75
|
-
httpMethod: method,
|
|
75
|
+
httpMethod: httpMethodOf(method),
|
|
76
76
|
statusCode,
|
|
77
77
|
responseTimeMs: Date.now() - startTime,
|
|
78
78
|
}).catch(() => { }); // Fire-and-forget
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AforoClient } from '../client';
|
|
2
|
-
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf } from './common';
|
|
1
|
+
import { AforoClient } from '../client.js';
|
|
2
|
+
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf, httpMethodOf } from './common.js';
|
|
3
3
|
const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
4
4
|
/**
|
|
5
5
|
* Fastify plugin that automatically captures API usage events.
|
|
@@ -67,7 +67,7 @@ export async function fastifyPlugin(fastify, options) {
|
|
|
67
67
|
metadata,
|
|
68
68
|
productType: options.productType,
|
|
69
69
|
endpointPath: endpointPathOf(path),
|
|
70
|
-
httpMethod: method,
|
|
70
|
+
httpMethod: httpMethodOf(method),
|
|
71
71
|
statusCode,
|
|
72
72
|
...(typeof elapsed === 'number' ? { responseTimeMs: Math.round(elapsed) } : {}),
|
|
73
73
|
}).catch(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/middleware/fastify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AforoClient } from '../client';
|
|
2
|
-
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf } from './common';
|
|
1
|
+
import { AforoClient } from '../client.js';
|
|
2
|
+
import { isPreflight, resolveMetricName, firstNonEmpty, endpointPathOf, httpMethodOf } from './common.js';
|
|
3
3
|
const DEFAULT_EXCLUDE_PATHS = ['/health', '/ready', '/metrics', '/favicon.ico'];
|
|
4
4
|
/**
|
|
5
5
|
* Koa middleware that automatically captures API usage events.
|
|
@@ -66,7 +66,7 @@ export function koaMiddleware(options) {
|
|
|
66
66
|
metadata,
|
|
67
67
|
productType: options.productType,
|
|
68
68
|
endpointPath: endpointPathOf(path),
|
|
69
|
-
httpMethod: method,
|
|
69
|
+
httpMethod: httpMethodOf(method),
|
|
70
70
|
statusCode,
|
|
71
71
|
responseTimeMs: Date.now() - startTime,
|
|
72
72
|
}).catch(() => { });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../../src/middleware/koa.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
package/dist/esm/transport.js
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* - POST /v1/ingest/batch with X-API-Key: {apiKey} (never Authorization: Bearer -- the ingestor parses Bearer as a JWT and rejects the request 401)
|
|
5
5
|
* - Retry on 5xx, 408, 429 with exponential backoff
|
|
6
6
|
* - Respects Retry-After header on 429
|
|
7
|
-
* - No retry on 4xx (bad input)
|
|
7
|
+
* - No retry on 4xx (bad input); the server's error message is surfaced
|
|
8
|
+
* - A 2xx whose body reports per-event failures (`errors[]`) is a partial
|
|
9
|
+
* failure: those events are reported back as rejected
|
|
8
10
|
* - AbortController timeout per request
|
|
9
11
|
*/
|
|
10
12
|
export class Transport {
|
|
@@ -37,12 +39,29 @@ export class Transport {
|
|
|
37
39
|
});
|
|
38
40
|
clearTimeout(timer);
|
|
39
41
|
if (response.ok) {
|
|
42
|
+
// A 2xx can still carry per-event rejections (`failed` / `errors[]`).
|
|
43
|
+
const rejected = await readRejectedEvents(response, events.length);
|
|
44
|
+
if (rejected.count > 0) {
|
|
45
|
+
return {
|
|
46
|
+
sent: events.length - rejected.count,
|
|
47
|
+
failed: rejected.count,
|
|
48
|
+
reason: 'rejected',
|
|
49
|
+
...(rejected.identified ? { rejected: rejected.errors } : {}),
|
|
50
|
+
...(rejected.errors[0] ? { message: rejected.errors[0].message } : {}),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
40
53
|
return { sent: events.length, failed: 0 };
|
|
41
54
|
}
|
|
42
55
|
// 4xx (except 408, 429) — bad input, don't retry
|
|
43
56
|
if (response.status >= 400 && response.status < 500
|
|
44
57
|
&& response.status !== 408 && response.status !== 429) {
|
|
45
|
-
|
|
58
|
+
const message = await readErrorMessage(response);
|
|
59
|
+
return {
|
|
60
|
+
sent: 0,
|
|
61
|
+
failed: events.length,
|
|
62
|
+
reason: 'rejected',
|
|
63
|
+
message: `HTTP ${response.status}${message ? `: ${message}` : ''}`,
|
|
64
|
+
};
|
|
46
65
|
}
|
|
47
66
|
// 429 — respect Retry-After header
|
|
48
67
|
if (response.status === 429) {
|
|
@@ -60,7 +79,7 @@ export class Transport {
|
|
|
60
79
|
await this.sleep(this.retryBaseMs * Math.pow(2, attempt));
|
|
61
80
|
continue;
|
|
62
81
|
}
|
|
63
|
-
return { sent: 0, failed: events.length };
|
|
82
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
64
83
|
}
|
|
65
84
|
catch (err) {
|
|
66
85
|
// Network error or abort — retry
|
|
@@ -68,10 +87,10 @@ export class Transport {
|
|
|
68
87
|
await this.sleep(this.retryBaseMs * Math.pow(2, attempt));
|
|
69
88
|
continue;
|
|
70
89
|
}
|
|
71
|
-
return { sent: 0, failed: events.length };
|
|
90
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
|
-
return { sent: 0, failed: events.length };
|
|
93
|
+
return { sent: 0, failed: events.length, reason: 'retry_exhausted' };
|
|
75
94
|
}
|
|
76
95
|
/**
|
|
77
96
|
* Send a single event in its own request, once, best-effort.
|
|
@@ -109,4 +128,55 @@ export class Transport {
|
|
|
109
128
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
110
129
|
}
|
|
111
130
|
}
|
|
131
|
+
async function readJson(response) {
|
|
132
|
+
try {
|
|
133
|
+
if (typeof response?.json === 'function')
|
|
134
|
+
return unwrapEnvelope(await response.json());
|
|
135
|
+
if (typeof response?.text === 'function')
|
|
136
|
+
return unwrapEnvelope(JSON.parse(await response.text()));
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Empty or non-JSON body — nothing to report.
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
/** Per-event rejections reported inside a 2xx batch response. */
|
|
144
|
+
async function readRejectedEvents(response, batchSize) {
|
|
145
|
+
const body = await readJson(response);
|
|
146
|
+
const none = { count: 0, identified: false, errors: [] };
|
|
147
|
+
if (!body || typeof body !== 'object')
|
|
148
|
+
return none;
|
|
149
|
+
const seen = new Set();
|
|
150
|
+
const errors = [];
|
|
151
|
+
if (Array.isArray(body.errors)) {
|
|
152
|
+
for (const e of body.errors) {
|
|
153
|
+
const index = Number(e?.index);
|
|
154
|
+
if (!Number.isInteger(index) || index < 0 || index >= batchSize || seen.has(index))
|
|
155
|
+
continue;
|
|
156
|
+
seen.add(index);
|
|
157
|
+
errors.push({ index, message: String(e?.message ?? 'rejected by the ingestor').slice(0, 500) });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const reported = typeof body.failed === 'number' && body.failed > 0 ? Math.floor(body.failed) : 0;
|
|
161
|
+
const count = Math.min(batchSize, Math.max(reported, errors.length));
|
|
162
|
+
// Only name events when the indexes account for every reported failure.
|
|
163
|
+
return { count, identified: errors.length > 0 && errors.length === count, errors };
|
|
164
|
+
}
|
|
165
|
+
/** Best-effort server explanation for a rejected request. */
|
|
166
|
+
async function readErrorMessage(response) {
|
|
167
|
+
const body = await readJson(response);
|
|
168
|
+
if (!body || typeof body !== 'object')
|
|
169
|
+
return undefined;
|
|
170
|
+
const first = Array.isArray(body.errors) ? body.errors[0] : undefined;
|
|
171
|
+
const text = first?.message ?? body.detail ?? body.message ?? body.error ?? body.title;
|
|
172
|
+
return typeof text === 'string' && text ? text.slice(0, 500) : undefined;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* The ingestor wraps every 2xx JSON body in `{success, data, meta}`. Returns
|
|
176
|
+
* the inner `data` object when present, else the body unchanged (bare shape).
|
|
177
|
+
*/
|
|
178
|
+
function unwrapEnvelope(body) {
|
|
179
|
+
const data = body && typeof body === 'object' && !Array.isArray(body) ? body.data : undefined;
|
|
180
|
+
return data && typeof data === 'object' && !Array.isArray(data) ? data : body;
|
|
181
|
+
}
|
|
112
182
|
//# 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/types/buffer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolvedEvent } from './types';
|
|
1
|
+
import { ResolvedEvent } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Bounded ring buffer for usage events.
|
|
4
4
|
* Thread-safe for Node.js single-threaded event loop.
|
|
@@ -13,6 +13,12 @@ export declare class RingBuffer {
|
|
|
13
13
|
constructor(capacity?: number);
|
|
14
14
|
/** Add an event to the buffer. Returns true if added, false if overflow (oldest dropped). */
|
|
15
15
|
push(event: ResolvedEvent): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Add an event to the buffer. On overflow, returns the evicted OLDEST
|
|
18
|
+
* event so the caller can surface the drop; returns null when no
|
|
19
|
+
* eviction occurred.
|
|
20
|
+
*/
|
|
21
|
+
pushEvict(event: ResolvedEvent): ResolvedEvent | null;
|
|
16
22
|
/** Drain all events from the buffer. Returns a new array and clears the buffer. */
|
|
17
23
|
drain(): ResolvedEvent[];
|
|
18
24
|
/** Drain up to `max` events from the front of the buffer. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"buffer.d.ts","sourceRoot":"","sources":["../../src/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAK;gBAEN,QAAQ,GAAE,MAAe;IAMrC,6FAA6F;IAC7F,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAInC;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI;IAiBrD,mFAAmF;IACnF,KAAK,IAAI,aAAa,EAAE;IAgBxB,6DAA6D;IAC7D,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE;IAgBvC,8CAA8C;IAC9C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,mCAAmC;IACnC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,yCAAyC;IACzC,IAAI,MAAM,IAAI,OAAO,CAEpB;CACF"}
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AforoOptions, TrackEvent, FlushResult } from './types';
|
|
1
|
+
import { AforoOptions, TrackEvent, FlushResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Aforo metering client.
|
|
4
4
|
*
|
|
@@ -20,6 +20,10 @@ export declare class AforoClient {
|
|
|
20
20
|
private readonly flushInterval;
|
|
21
21
|
private readonly shutdownTimeoutMs;
|
|
22
22
|
private readonly productType;
|
|
23
|
+
private readonly onDrop?;
|
|
24
|
+
private dropped;
|
|
25
|
+
private overflowDrops;
|
|
26
|
+
private invalidDrops;
|
|
23
27
|
private flushTimer;
|
|
24
28
|
private flushing;
|
|
25
29
|
private closed;
|
|
@@ -28,6 +32,7 @@ export declare class AforoClient {
|
|
|
28
32
|
private activeSessionId;
|
|
29
33
|
private sessionStartedAt;
|
|
30
34
|
private sessionProductType;
|
|
35
|
+
private readonly signalHandler;
|
|
31
36
|
constructor(options: AforoOptions);
|
|
32
37
|
/**
|
|
33
38
|
* Start a session and emit `system.session.heartbeat` events: one now, then
|
|
@@ -55,18 +60,27 @@ export declare class AforoClient {
|
|
|
55
60
|
* Returns immediately — does not await HTTP.
|
|
56
61
|
* Triggers a flush if the buffer reaches flushCount.
|
|
57
62
|
*
|
|
58
|
-
* Throws
|
|
59
|
-
* or over-long `customerId` / `metricName` /
|
|
60
|
-
* that is not positive or carries more than
|
|
61
|
-
* places, an `occurredAt` that is not an
|
|
62
|
-
* capped field that is too long
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* See `limits.ts` for the limits and where each one comes from.
|
|
63
|
+
* Throws only when the client is shut down. An event the ingestor would
|
|
64
|
+
* reject — a blank or over-long `customerId` / `metricName` /
|
|
65
|
+
* `idempotencyKey`, a `quantity` that is not positive or carries more than
|
|
66
|
+
* 14 integer digits / 6 decimal places, an `occurredAt` that is not an
|
|
67
|
+
* ISO-8601 instant, or any other capped field that is too long — is NOT
|
|
68
|
+
* buffered and NOT sent. It is counted in `droppedCount`, WARN-logged with
|
|
69
|
+
* the field, the limit and the offending value, and passed to the opt-in
|
|
70
|
+
* `onDrop` hook with reason `'invalid'`. Limits the server makes
|
|
71
|
+
* configurable (event age, clock skew, metadata size) are left to the
|
|
72
|
+
* server. See `limits.ts` for the limits and where each one comes from.
|
|
68
73
|
*/
|
|
69
74
|
track(event: TrackEvent): Promise<void>;
|
|
75
|
+
/** Buffer an event; surface the evicted-oldest event if the push overflowed. */
|
|
76
|
+
private enqueue;
|
|
77
|
+
/**
|
|
78
|
+
* Account for permanently lost events: bump the counter, WARN-log, and
|
|
79
|
+
* invoke the opt-in onDrop hook. Overflow logs are throttled (first, then
|
|
80
|
+
* every 1000th eviction) so sustained overflow can't storm the log;
|
|
81
|
+
* failed-batch drops log every time (bounded by flush cadence).
|
|
82
|
+
*/
|
|
83
|
+
private recordDrop;
|
|
70
84
|
/**
|
|
71
85
|
* Force-flush all buffered events to the ingestor.
|
|
72
86
|
* Safe to call concurrently — only one flush runs at a time.
|
|
@@ -80,6 +94,8 @@ export declare class AforoClient {
|
|
|
80
94
|
shutdown(): Promise<void>;
|
|
81
95
|
/** Number of events currently buffered. */
|
|
82
96
|
get bufferedCount(): number;
|
|
97
|
+
/** Total events permanently dropped (overflow, failed batches, server-rejected and invalid events) since creation. */
|
|
98
|
+
get droppedCount(): number;
|
|
83
99
|
/** Whether the client has been shut down. */
|
|
84
100
|
get isShutdown(): boolean;
|
|
85
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAiB,WAAW,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAiB,WAAW,EAAc,MAAM,YAAY,CAAC;AAuB9F;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAwD;IAIhF,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAqC;IAGzD,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,kBAAkB,CAAwC;IAIlE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;gBAE/B,OAAO,EAAE,YAAY;IAuCjC;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,MAAqC,GAAG,IAAI;IAezF;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAkC5B;;;;;;;;;;;;;;;OAeG;IACG,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA8D7C,gFAAgF;IAChF,OAAO,CAAC,OAAO;IAOf;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAqClB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;YAgBrB,OAAO;IAsCrB;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC/B,2CAA2C;IAC3C,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,sHAAsH;IACtH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,6CAA6C;IAC7C,IAAI,UAAU,IAAI,OAAO,CAExB;CACF"}
|
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Formula: SHA256(customerId + metricName + quantity + occurredAt)
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* WARNING - collapse hazard: two legitimately DISTINCT events with identical
|
|
8
|
+
* fields in the same timestamp instant produce the SAME key, so the second
|
|
9
|
+
* dedups away (silent under-billing). The SDK therefore no longer uses this
|
|
10
|
+
* as the automatic fallback for keyless track() calls (2026-07-05 - mirrors
|
|
11
|
+
* Aforo ingest's April 2026 H4 fix). Use it only when your events are
|
|
12
|
+
* guaranteed unique per (customer, metric, quantity, occurredAt).
|
|
13
13
|
*/
|
|
14
14
|
export declare function generateIdempotencyKey(customerId: string, metricName: string, quantity: number, occurredAt: string): string;
|
|
15
15
|
/**
|
|
16
|
-
* Generate a random UUID
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Generate a random UUID key - the automatic fallback for keyless track()
|
|
17
|
+
* calls. No caller key = dedup opt-out: every call is a distinct event; the
|
|
18
|
+
* key is stamped once at enqueue so flush retries stay dedup-safe.
|
|
19
19
|
*/
|
|
20
20
|
export declare function generateRandomKey(): string;
|
|
21
21
|
//# sourceMappingURL=idempotency.d.ts.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { AforoClient } from './client';
|
|
2
|
-
export { expressMiddleware, middleware } from './middleware/express';
|
|
3
|
-
export { fastifyPlugin } from './middleware/fastify';
|
|
4
|
-
export { koaMiddleware } from './middleware/koa';
|
|
5
|
-
export { normalizePath } from './path-normalizer';
|
|
6
|
-
export { DEFAULT_METRIC_NAME } from './middleware/common';
|
|
7
|
-
export { MAX_LENGTHS, MAX_QUANTITY_DECIMAL_PLACES, MAX_QUANTITY_INTEGER_DIGITS, describeLimitViolation, } from './limits';
|
|
8
|
-
export type { AforoOptions, TrackEvent, MiddlewareOptions, FlushResult, BatchRequest, BatchResponse, } from './types';
|
|
1
|
+
export { AforoClient } from './client.js';
|
|
2
|
+
export { expressMiddleware, middleware } from './middleware/express.js';
|
|
3
|
+
export { fastifyPlugin } from './middleware/fastify.js';
|
|
4
|
+
export { koaMiddleware } from './middleware/koa.js';
|
|
5
|
+
export { normalizePath } from './path-normalizer.js';
|
|
6
|
+
export { DEFAULT_METRIC_NAME } from './middleware/common.js';
|
|
7
|
+
export { MAX_LENGTHS, MAX_QUANTITY_DECIMAL_PLACES, MAX_QUANTITY_INTEGER_DIGITS, describeLimitViolation, truncateToLimit, } from './limits.js';
|
|
8
|
+
export type { AforoOptions, TrackEvent, MiddlewareOptions, FlushResult, BatchRequest, BatchResponse, ResolvedEvent, DropReason, } from './types.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,WAAW,EACX,2BAA2B,EAC3B,2BAA2B,EAC3B,sBAAsB,EACtB,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,UAAU,GACX,MAAM,YAAY,CAAC"}
|
package/dist/types/limits.d.ts
CHANGED
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
* billed. The server reports it per event (`errors[]` in the batch response,
|
|
6
6
|
* indexed), so the rest of the batch survives — but the SDK sends in the
|
|
7
7
|
* background, so that report reaches nobody: the usage is simply gone. Checking
|
|
8
|
-
* the same limits at `track()`
|
|
9
|
-
*
|
|
8
|
+
* the same limits at `track()` reports the problem where it happens: the event
|
|
9
|
+
* is not buffered or sent, it is counted in `droppedCount`, WARN-logged with
|
|
10
|
+
* the field, the limit and the offending value, and handed to the opt-in
|
|
11
|
+
* `onDrop` hook with reason `'invalid'`. `track()` does not throw for it.
|
|
10
12
|
*
|
|
11
13
|
* Source: `dto/IngestUsageEventRequest` (aforo-nextgen-usage-ingestor-service) —
|
|
12
14
|
* the `@Size` and `@Digits` bean constraints, which are compiled into the
|
|
@@ -21,9 +23,15 @@
|
|
|
21
23
|
* Only `occurredAt`'s shape is checked, since a malformed timestamp is invalid
|
|
22
24
|
* under every configuration.
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* offending value.
|
|
26
|
+
* The limit check never truncates or rounds a value the caller set — that would
|
|
27
|
+
* change what is billed. The offending event is dropped instead (reason
|
|
28
|
+
* `'invalid'`), naming the field, the limit, and the offending value.
|
|
29
|
+
*
|
|
30
|
+
* The one exception is a label the SDK itself reads off an incoming request
|
|
31
|
+
* (the middlewares' `endpointPath` and `httpMethod`): dropping there would let
|
|
32
|
+
* an API consumer avoid metering by sending an over-long path. Those are cut to
|
|
33
|
+
* the limit where they are derived (`truncateRequestLabel`) and the event is
|
|
34
|
+
* still sent.
|
|
27
35
|
*/
|
|
28
36
|
/** Maximum characters the ingestor accepts per string field (`@Size(max = ...)`). */
|
|
29
37
|
export declare const MAX_LENGTHS: {
|
|
@@ -36,12 +44,35 @@ export declare const MAX_LENGTHS: {
|
|
|
36
44
|
readonly sessionId: 64;
|
|
37
45
|
readonly agentId: 36;
|
|
38
46
|
readonly toolName: 64;
|
|
47
|
+
readonly capabilityName: 64;
|
|
39
48
|
readonly endpointPath: 512;
|
|
40
49
|
readonly httpMethod: 16;
|
|
50
|
+
readonly subscriptionId: 64;
|
|
51
|
+
readonly grpcService: 255;
|
|
52
|
+
readonly grpcMethod: 128;
|
|
53
|
+
readonly gqlOperationName: 255;
|
|
54
|
+
readonly wsConnectionId: 64;
|
|
55
|
+
readonly mqttTopic: 500;
|
|
56
|
+
readonly mqttClientId: 128;
|
|
41
57
|
};
|
|
42
58
|
/** `@Digits(integer = 14, fraction = 6)` — `usage_events.quantity` is NUMERIC(20,6). */
|
|
43
59
|
export declare const MAX_QUANTITY_INTEGER_DIGITS = 14;
|
|
44
60
|
export declare const MAX_QUANTITY_DECIMAL_PLACES = 6;
|
|
61
|
+
/** Fields whose length the ingestor caps, checked when the caller sets them. */
|
|
62
|
+
type LengthCheckedField = keyof typeof MAX_LENGTHS;
|
|
63
|
+
/**
|
|
64
|
+
* Cut `value` to at most `max` UTF-16 code units — how the ingestor counts —
|
|
65
|
+
* without leaving half a surrogate pair at the end.
|
|
66
|
+
*/
|
|
67
|
+
export declare function truncateToLimit(value: string, max: number): string;
|
|
68
|
+
/**
|
|
69
|
+
* Bound a label the SDK derived from an incoming request to the ingestor's
|
|
70
|
+
* limit for `field`. Logs one WARN per field per process. Not for values the
|
|
71
|
+
* SDK caller sets: those are never altered (an over-long one drops the event).
|
|
72
|
+
*/
|
|
73
|
+
export declare function truncateRequestLabel(field: LengthCheckedField, value: string): string;
|
|
74
|
+
/** Test hook: forget which labels were already reported as truncated. */
|
|
75
|
+
export declare function resetTruncationWarnings(): void;
|
|
45
76
|
/**
|
|
46
77
|
* Integer and decimal digit counts as the ingestor's `@Digits` sees them, i.e.
|
|
47
78
|
* as `BigDecimal` reads the number the SDK puts on the wire:
|
|
@@ -70,11 +101,20 @@ export interface LimitCheckedEvent {
|
|
|
70
101
|
sessionId?: unknown;
|
|
71
102
|
agentId?: unknown;
|
|
72
103
|
toolName?: unknown;
|
|
104
|
+
capabilityName?: unknown;
|
|
105
|
+
subscriptionId?: unknown;
|
|
106
|
+
grpcService?: unknown;
|
|
107
|
+
grpcMethod?: unknown;
|
|
108
|
+
gqlOperationName?: unknown;
|
|
109
|
+
wsConnectionId?: unknown;
|
|
110
|
+
mqttTopic?: unknown;
|
|
111
|
+
mqttClientId?: unknown;
|
|
73
112
|
}
|
|
74
113
|
/**
|
|
75
114
|
* Describe the first ingestor constraint this event breaks, or `null` when it
|
|
76
|
-
* would be accepted.
|
|
77
|
-
*
|
|
115
|
+
* would be accepted. `AforoClient.track()` uses it to drop an invalid event
|
|
116
|
+
* (reason `'invalid'`) before it is buffered.
|
|
78
117
|
*/
|
|
79
118
|
export declare function describeLimitViolation(event: LimitCheckedEvent): string | null;
|
|
119
|
+
export {};
|
|
80
120
|
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/limits.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,qFAAqF;AACrF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;CAoBd,CAAC;AAEX,wFAAwF;AACxF,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAC9C,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAc7C,gFAAgF;AAChF,KAAK,kBAAkB,GAAG,MAAM,OAAO,WAAW,CAAC;AAUnD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE;AAKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWrF;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAaD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAYnG;AA+BD,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAe9E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MiddlewareOptions } from '../types';
|
|
1
|
+
import { MiddlewareOptions } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Metric recorded for each request when `metricName` is not configured.
|
|
4
4
|
*
|
|
@@ -15,8 +15,14 @@ export declare const DEFAULT_METRIC_NAME = "api_calls";
|
|
|
15
15
|
export declare function isPreflight(method: string | undefined): boolean;
|
|
16
16
|
/** Resolve the metric: resolver function, then fixed name, then DEFAULT_METRIC_NAME. */
|
|
17
17
|
export declare function resolveMetricName(options: MiddlewareOptions, req: any, res: any): string;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Request path without its query string. Read off the incoming request, so an
|
|
20
|
+
* over-long path is cut to the ingestor's limit (512) instead of dropping the
|
|
21
|
+
* event — otherwise a caller could avoid metering with a long URL.
|
|
22
|
+
*/
|
|
19
23
|
export declare function endpointPathOf(url: string): string;
|
|
24
|
+
/** HTTP method off the incoming request, cut to the ingestor's limit (16). */
|
|
25
|
+
export declare function httpMethodOf(method: string): string;
|
|
20
26
|
/** First non-empty string among the candidates, or null. */
|
|
21
27
|
export declare function firstNonEmpty(...values: unknown[]): string | null;
|
|
22
28
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/middleware/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/middleware/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAE/D;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,CAKxF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,IAAI,CAOjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,IAUlB,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAgEtE;AAeD,eAAO,MAAM,UAAU,0BAAoB,CAAC"}
|
|
@@ -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"}
|