@fonoster/common 0.27.0 → 0.31.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.
- package/dist/{voice/PlayDtmf.d.ts → agents/index.d.ts} +3 -5
- package/dist/{assistants → agents}/index.js +2 -6
- package/dist/agents/sessionAgentSchema.d.ts +755 -0
- package/dist/agents/sessionAgentSchema.js +117 -0
- package/dist/{voice/Dial.d.ts → calls/index.d.ts} +16 -13
- package/dist/calls/index.js +44 -0
- package/dist/cellsecrets/index.d.ts +91 -0
- package/dist/cellsecrets/index.js +299 -0
- package/dist/config/cli/check.d.ts +6 -0
- package/dist/config/cli/check.js +202 -0
- package/dist/config/cli/envFile.d.ts +23 -0
- package/dist/config/cli/envFile.js +81 -0
- package/dist/config/cli/exposure.d.ts +10 -0
- package/dist/config/cli/exposure.js +93 -0
- package/dist/config/cli/index.d.ts +2 -0
- package/dist/{identity/tokenHasAccessKeyId.js → config/cli/index.js} +7 -8
- package/dist/config/cli/info.d.ts +6 -0
- package/dist/config/cli/info.js +62 -0
- package/dist/config/cli/init.d.ts +9 -0
- package/dist/config/cli/init.js +152 -0
- package/dist/config/cli/main.d.ts +11 -0
- package/dist/config/cli/main.js +155 -0
- package/dist/config/cli/render.d.ts +44 -0
- package/dist/config/cli/render.js +129 -0
- package/dist/config/cli/secrets.d.ts +21 -0
- package/dist/config/cli/secrets.js +117 -0
- package/dist/config/cli/types.d.ts +24 -0
- package/dist/config/cli/types.js +7 -0
- package/dist/{assistants/index.d.ts → config/configHints.d.ts} +8 -7
- package/dist/config/configHints.js +47 -0
- package/dist/{voice → config}/index.d.ts +11 -13
- package/dist/{voice → config}/index.js +11 -13
- package/dist/config/interpolateEnv.d.ts +34 -0
- package/dist/config/interpolateEnv.js +70 -0
- package/dist/config/loadServiceConfig.d.ts +28 -0
- package/dist/config/loadServiceConfig.js +112 -0
- package/dist/config/logsSchema.d.ts +76 -0
- package/dist/config/logsSchema.js +49 -0
- package/dist/config/natsConnection.d.ts +53 -0
- package/dist/config/natsConnection.js +58 -0
- package/dist/config/parseConfigFile.d.ts +7 -0
- package/dist/config/parseConfigFile.js +60 -0
- package/dist/config/resolveConfigFile.d.ts +17 -0
- package/dist/config/resolveConfigFile.js +54 -0
- package/dist/config/resolveSecretRefs.d.ts +35 -0
- package/dist/config/resolveSecretRefs.js +129 -0
- package/dist/{assistants/audioFiltersSchema.d.ts → config/strictDeep.d.ts} +9 -12
- package/dist/config/strictDeep.js +58 -0
- package/dist/config/telemetrySchema.d.ts +39 -0
- package/dist/config/telemetrySchema.js +44 -0
- package/dist/config/toJsonSchema.d.ts +30 -0
- package/dist/config/toJsonSchema.js +161 -0
- package/dist/constants.d.ts +1 -6
- package/dist/constants.js +4 -7
- package/dist/envs.d.ts +2 -1
- package/dist/envs.js +13 -11
- package/dist/errors/handleZodError.js +3 -1
- package/dist/filters/index.d.ts +70 -0
- package/dist/filters/index.js +101 -0
- package/dist/identity/createAuthInterceptor.d.ts +9 -2
- package/dist/identity/createAuthInterceptor.js +36 -30
- package/dist/identity/hasAccess.d.ts +9 -3
- package/dist/identity/hasAccess.js +32 -8
- package/dist/identity/index.d.ts +1 -0
- package/dist/identity/index.js +1 -0
- package/dist/identity/isValidToken.d.ts +12 -2
- package/dist/identity/isValidToken.js +25 -9
- package/dist/identity/roles.js +33 -7
- package/dist/identity/types.d.ts +6 -1
- package/dist/identity/types.js +1 -0
- package/dist/{assistants/LanguageModelProvider.js → identity/verifyAccessToken.d.ts} +10 -11
- package/dist/identity/verifyAccessToken.js +44 -0
- package/dist/index.d.ts +15 -2
- package/dist/index.js +18 -3
- package/dist/net/assertPublicDestination.d.ts +52 -0
- package/dist/net/assertPublicDestination.js +342 -0
- package/dist/{voice/StopSay.d.ts → net/index.d.ts} +1 -6
- package/dist/net/index.js +35 -0
- package/dist/notifications/createSendEmail.js +3 -1
- package/dist/protos/applications.proto +138 -3
- package/dist/protos/authz.proto +26 -4
- package/dist/protos/billing.proto +92 -0
- package/dist/protos/calls.proto +4 -0
- package/dist/protos/capabilities.proto +102 -0
- package/dist/protos/identity.proto +26 -1
- package/dist/protos/providers.proto +139 -0
- package/dist/protos/roomr.proto +146 -0
- package/dist/protos/session.proto +194 -0
- package/dist/protos/usage.proto +59 -0
- package/dist/protos/webhooks.proto +140 -0
- package/dist/{utils/types.d.ts → regions/hub/index.d.ts} +1 -5
- package/dist/regions/hub/index.js +35 -0
- package/dist/regions/hub/natsJwt.d.ts +63 -0
- package/dist/regions/hub/natsJwt.js +195 -0
- package/dist/registry/Registry.d.ts +87 -0
- package/dist/registry/Registry.js +432 -0
- package/dist/registry/cli.d.ts +20 -0
- package/dist/registry/cli.js +436 -0
- package/dist/registry/features.d.ts +31 -0
- package/dist/registry/features.js +38 -0
- package/dist/registry/index.d.ts +24 -0
- package/dist/registry/index.js +40 -0
- package/dist/registry/prisma.d.ts +67 -0
- package/dist/registry/prisma.js +399 -0
- package/dist/registry/stores.d.ts +21 -0
- package/dist/{assistants/languageModelConfigSchema.js → registry/stores.js} +55 -38
- package/dist/registry/types.d.ts +110 -0
- package/dist/{assistants/LanguageModelProvider.d.ts → registry/types.js} +6 -8
- package/dist/registry/workspaceKeys.d.ts +41 -0
- package/dist/registry/workspaceKeys.js +64 -0
- package/dist/roomr/health.d.ts +9 -0
- package/dist/{assistants/eventsHookSchema.js → roomr/health.js} +22 -18
- package/dist/roomr/index.d.ts +75 -0
- package/dist/roomr/index.js +146 -0
- package/dist/roomr/session.d.ts +133 -0
- package/dist/roomr/session.js +132 -0
- package/dist/session/index.d.ts +19 -0
- package/dist/session/index.js +35 -0
- package/dist/session/schema.d.ts +2140 -0
- package/dist/session/schema.js +448 -0
- package/dist/sessions/index.d.ts +96 -0
- package/dist/sessions/index.js +197 -0
- package/dist/telemetry.d.ts +76 -0
- package/dist/telemetry.js +360 -0
- package/dist/types.d.ts +3 -5
- package/dist/{voice/Gather.d.ts → usage/CallUsage.d.ts} +19 -18
- package/dist/usage/CallUsage.js +76 -0
- package/dist/usage/index.d.ts +22 -0
- package/dist/usage/index.js +38 -0
- package/dist/usage/meters.d.ts +113 -0
- package/dist/usage/meters.js +90 -0
- package/dist/usage/types.d.ts +159 -0
- package/dist/usage/types.js +84 -0
- package/dist/usage/usageId.d.ts +6 -0
- package/dist/usage/usageId.js +45 -0
- package/dist/utils/{findIntegrationsCredentials.js → WriteBehind.d.ts} +13 -10
- package/dist/utils/WriteBehind.js +64 -0
- package/dist/utils/index.d.ts +1 -3
- package/dist/utils/index.js +1 -3
- package/dist/utils/{createFetchSingleCallByCallId.d.ts → logUnhandledRejections.d.ts} +8 -4
- package/dist/{assistants/audioFiltersSchema.js → utils/logUnhandledRejections.js} +17 -12
- package/dist/utils/withErrorHandling.js +1 -1
- package/dist/validators/calls.d.ts +3 -0
- package/dist/validators/calls.js +12 -2
- package/dist/validators/identity.d.ts +37 -8
- package/dist/validators/identity.js +22 -3
- package/dist/validators/index.d.ts +1 -0
- package/dist/validators/index.js +1 -0
- package/dist/validators/sip.d.ts +40 -0
- package/dist/validators/sip.js +99 -0
- package/dist/validators/sipnet/credentials.d.ts +2 -2
- package/dist/validators/sipnet/domains.js +7 -7
- package/dist/validators/sipnet/trunks.d.ts +14 -14
- package/dist/validators/sipnet/trunks.js +4 -2
- package/dist/webhooks/Dispatcher.d.ts +87 -0
- package/dist/webhooks/Dispatcher.js +225 -0
- package/dist/webhooks/bus.d.ts +68 -0
- package/dist/webhooks/bus.js +178 -0
- package/dist/webhooks/events.d.ts +66 -0
- package/dist/webhooks/events.js +62 -0
- package/dist/webhooks/index.d.ts +23 -0
- package/dist/webhooks/index.js +39 -0
- package/dist/webhooks/prisma.d.ts +55 -0
- package/dist/webhooks/prisma.js +242 -0
- package/dist/webhooks/signing.d.ts +8 -0
- package/dist/webhooks/signing.js +53 -0
- package/package.json +25 -11
- package/schema/session.v1.json +871 -0
- package/dist/assistants/assistantSchema.d.ts +0 -739
- package/dist/assistants/assistantSchema.js +0 -37
- package/dist/assistants/conversationSettingsSchema.d.ts +0 -122
- package/dist/assistants/conversationSettingsSchema.js +0 -133
- package/dist/assistants/eventsHookSchema.d.ts +0 -38
- package/dist/assistants/languageModelConfigSchema.d.ts +0 -206
- package/dist/identity/tokenHasAccessKeyId.d.ts +0 -2
- package/dist/protos/voice.proto +0 -557
- package/dist/utils/createFetchSingleCallByCallId.js +0 -33
- package/dist/utils/findIntegrationsCredentials.d.ts +0 -23
- package/dist/utils/types.js +0 -2
- package/dist/voice/Dial.js +0 -20
- package/dist/voice/Gather.js +0 -9
- package/dist/voice/Mute.d.ts +0 -31
- package/dist/voice/Mute.js +0 -9
- package/dist/voice/Play.d.ts +0 -30
- package/dist/voice/Play.js +0 -2
- package/dist/voice/PlayDtmf.js +0 -2
- package/dist/voice/PlaybackControl.d.ts +0 -31
- package/dist/voice/PlaybackControl.js +0 -11
- package/dist/voice/Record.d.ts +0 -36
- package/dist/voice/Record.js +0 -7
- package/dist/voice/Say.d.ts +0 -28
- package/dist/voice/Say.js +0 -2
- package/dist/voice/StopSay.js +0 -2
- package/dist/voice/Stream.d.ts +0 -53
- package/dist/voice/Stream.js +0 -19
- package/dist/voice/StreamGather.d.ts +0 -34
- package/dist/voice/StreamGather.js +0 -9
- package/dist/voice/Verb.d.ts +0 -27
- package/dist/voice/Verb.js +0 -2
- package/dist/voice/voice.d.ts +0 -171
- package/dist/voice/voice.js +0 -65
- package/dist/{assistants → agents}/testCasesSchema.d.ts +4 -4
- /package/dist/{assistants → agents}/testCasesSchema.js +0 -0
- /package/dist/{assistants → agents}/tools/index.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/index.js +0 -0
- /package/dist/{assistants → agents}/tools/propertySchema.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/propertySchema.js +0 -0
- /package/dist/{assistants → agents}/tools/toolSchema.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/toolSchema.js +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
12
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
13
|
+
var m = o[Symbol.asyncIterator], i;
|
|
14
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
15
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
16
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.SessionLeases = exports.sessionKey = exports.SESSIONS_REFRESH_MS = exports.SESSIONS_TTL_MS = exports.SESSIONS_BUCKET = void 0;
|
|
20
|
+
exports.openSessions = openSessions;
|
|
21
|
+
exports.watchSessions = watchSessions;
|
|
22
|
+
exports.getSession = getSession;
|
|
23
|
+
/**
|
|
24
|
+
* The session registry (add-platform 2.3, add-roomr 3.2, decision D3): one NATS JetStream KV
|
|
25
|
+
* bucket shared by every service. Keys are `<kind>.<id>`:
|
|
26
|
+
*
|
|
27
|
+
* calls.<callRef> appbridge: { callRef, bridgeRef, nodeId, roomRef, direction, at }
|
|
28
|
+
* + once answered: { appRef, workspaceRef, from, to, startedAt }
|
|
29
|
+
* appbridges.<bridgeRef> retired: AppBridge no longer writes it (redesign-roomr 15.3)
|
|
30
|
+
* placements.<callRef> apiserver: { callRef, nodeRef, controlAddr, roomRef?, at }
|
|
31
|
+
* while an outbound call is being placed (CreateCall)
|
|
32
|
+
*
|
|
33
|
+
* Roomr nodes write nothing here (core NATS only: heartbeat and events); the control plane learns
|
|
34
|
+
* nodes from their heartbeats.
|
|
35
|
+
*
|
|
36
|
+
* The control plane reads `calls` (billing counts active calls from them). A call that loses its
|
|
37
|
+
* AppBridge mid-call is reported by its node's `call.ended` with cause `app_gone` (redesign-roomr
|
|
38
|
+
* 15.4), not by expired `appbridges` entries.
|
|
39
|
+
*
|
|
40
|
+
* Entries are leases: the bucket keeps a value for SESSIONS_TTL_MS after its last write, owners
|
|
41
|
+
* rewrite theirs every SESSIONS_REFRESH_MS, and a crashed owner's entries expire on their own.
|
|
42
|
+
*/
|
|
43
|
+
exports.SESSIONS_BUCKET = "fonoster_sessions";
|
|
44
|
+
exports.SESSIONS_TTL_MS = 15000;
|
|
45
|
+
exports.SESSIONS_REFRESH_MS = 5000;
|
|
46
|
+
/** `<kind>.<id>` with characters KV keys do not allow replaced by `_`. */
|
|
47
|
+
const sessionKey = (kind, id) => `${kind}.${id.replace(/[^-_=/.a-zA-Z0-9]/g, "_")}`;
|
|
48
|
+
exports.sessionKey = sessionKey;
|
|
49
|
+
/** Opens the bucket, creating it when it does not exist yet. */
|
|
50
|
+
function openSessions(nc_1) {
|
|
51
|
+
return __awaiter(this, arguments, void 0, function* (nc, options = {}) {
|
|
52
|
+
var _a;
|
|
53
|
+
const bucket = (_a = options.bucket) !== null && _a !== void 0 ? _a : exports.SESSIONS_BUCKET;
|
|
54
|
+
const open = () => {
|
|
55
|
+
var _a;
|
|
56
|
+
return nc.jetstream().views.kv(bucket, {
|
|
57
|
+
history: 1,
|
|
58
|
+
ttl: (_a = options.ttlMs) !== null && _a !== void 0 ? _a : exports.SESSIONS_TTL_MS,
|
|
59
|
+
description: "Fonoster session registry: nodes, rooms, calls, appbridges (leases)"
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
try {
|
|
63
|
+
return yield open();
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
// Another service created it at the same moment with a slightly different config: bind.
|
|
67
|
+
if (/already in use/i.test(e.message))
|
|
68
|
+
return nc.jetstream().views.kv(bucket, { bindOnly: true });
|
|
69
|
+
throw e;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* An owner's entries, kept alive until deleted (AppBridge's calls and its own appbridge entry).
|
|
75
|
+
* Writes never throw: the registry is best effort and entries are rewritten on the next refresh.
|
|
76
|
+
*/
|
|
77
|
+
class SessionLeases {
|
|
78
|
+
constructor(kv, options = {}) {
|
|
79
|
+
var _a, _b, _c;
|
|
80
|
+
this.kv = kv;
|
|
81
|
+
this.options = options;
|
|
82
|
+
this.entries = new Map();
|
|
83
|
+
this.chain = Promise.resolve();
|
|
84
|
+
this.closed = false;
|
|
85
|
+
this.timer = setInterval(() => this.refresh(), (_a = options.refreshMs) !== null && _a !== void 0 ? _a : exports.SESSIONS_REFRESH_MS);
|
|
86
|
+
(_c = (_b = this.timer).unref) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
87
|
+
}
|
|
88
|
+
write(key, value) {
|
|
89
|
+
// One write at a time, in order (a delete never overtakes the put before it).
|
|
90
|
+
this.chain = this.chain.then(() => __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
var _a;
|
|
92
|
+
try {
|
|
93
|
+
if (value)
|
|
94
|
+
yield this.kv.put(key, JSON.stringify(Object.assign(Object.assign({}, value), { at: new Date().toISOString() })));
|
|
95
|
+
else
|
|
96
|
+
yield this.kv.delete(key);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
(_a = this.options.logger) === null || _a === void 0 ? void 0 : _a.warn(`session registry write ${key} failed: ${e.message}`);
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
return this.chain;
|
|
103
|
+
}
|
|
104
|
+
/** Writes the entry now and keeps it alive. */
|
|
105
|
+
set(kind, id, value) {
|
|
106
|
+
if (this.closed)
|
|
107
|
+
return Promise.resolve();
|
|
108
|
+
const key = (0, exports.sessionKey)(kind, id);
|
|
109
|
+
this.entries.set(key, value);
|
|
110
|
+
return this.write(key, value);
|
|
111
|
+
}
|
|
112
|
+
/** Removes the entry. */
|
|
113
|
+
delete(kind, id) {
|
|
114
|
+
if (this.closed)
|
|
115
|
+
return Promise.resolve();
|
|
116
|
+
const key = (0, exports.sessionKey)(kind, id);
|
|
117
|
+
this.entries.delete(key);
|
|
118
|
+
return this.write(key);
|
|
119
|
+
}
|
|
120
|
+
/** Reads any owner's entry from the bucket (undefined when absent or expired). */
|
|
121
|
+
get(kind, id) {
|
|
122
|
+
return getSession(this.kv, kind, id);
|
|
123
|
+
}
|
|
124
|
+
/** Rewrites every live entry (called on a timer). */
|
|
125
|
+
refresh() {
|
|
126
|
+
for (const [key, value] of this.entries)
|
|
127
|
+
void this.write(key, value);
|
|
128
|
+
return this.chain;
|
|
129
|
+
}
|
|
130
|
+
/** Stops refreshing; with `remove`, deletes every entry first (clean shutdown). */
|
|
131
|
+
close() {
|
|
132
|
+
return __awaiter(this, arguments, void 0, function* (remove = true) {
|
|
133
|
+
if (this.closed)
|
|
134
|
+
return;
|
|
135
|
+
clearInterval(this.timer);
|
|
136
|
+
if (remove)
|
|
137
|
+
for (const key of this.entries.keys())
|
|
138
|
+
void this.write(key);
|
|
139
|
+
this.closed = true;
|
|
140
|
+
this.entries.clear();
|
|
141
|
+
yield this.chain;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.SessionLeases = SessionLeases;
|
|
146
|
+
/**
|
|
147
|
+
* Follows one kind of entries: the current ones first (so a restarted replica knows the registry
|
|
148
|
+
* at once), then every change. Returns a stop function.
|
|
149
|
+
*/
|
|
150
|
+
function watchSessions(kv, kind, onEntry) {
|
|
151
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
152
|
+
const iter = yield kv.watch({ key: `${kind}.>` });
|
|
153
|
+
void (() => __awaiter(this, void 0, void 0, function* () {
|
|
154
|
+
var _a, e_1, _b, _c;
|
|
155
|
+
try {
|
|
156
|
+
for (var _d = true, _e = __asyncValues(iter), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
157
|
+
_c = _f.value;
|
|
158
|
+
_d = false;
|
|
159
|
+
const e = _c;
|
|
160
|
+
const id = e.key.slice(kind.length + 1);
|
|
161
|
+
let value;
|
|
162
|
+
if (e.operation === "PUT") {
|
|
163
|
+
try {
|
|
164
|
+
value = JSON.parse(e.string());
|
|
165
|
+
}
|
|
166
|
+
catch (_g) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
onEntry({ kind, id, value, writtenAt: e.created });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
174
|
+
finally {
|
|
175
|
+
try {
|
|
176
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
177
|
+
}
|
|
178
|
+
finally { if (e_1) throw e_1.error; }
|
|
179
|
+
}
|
|
180
|
+
}))();
|
|
181
|
+
return () => iter.stop();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/** Reads one entry (undefined when absent or expired). */
|
|
185
|
+
function getSession(kv, kind, id) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
const e = yield kv.get((0, exports.sessionKey)(kind, id));
|
|
188
|
+
if (!e || e.operation !== "PUT")
|
|
189
|
+
return undefined;
|
|
190
|
+
try {
|
|
191
|
+
return JSON.parse(e.string());
|
|
192
|
+
}
|
|
193
|
+
catch (_a) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
+
* http://github.com/fonoster/fonoster
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Fonoster
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the MIT License (the "License");
|
|
8
|
+
* you may not use this file except in compliance with
|
|
9
|
+
* the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* https://opensource.org/licenses/MIT
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* OpenTelemetry bootstrap shared by the TypeScript services (add-platform, observability).
|
|
21
|
+
*
|
|
22
|
+
* Driven by the standard OTEL_* variables and a complete no-op when no OTLP endpoint is set:
|
|
23
|
+
* nothing is loaded, nothing is sent, and the service only writes its normal logs. Signals go
|
|
24
|
+
* over OTLP/HTTP with JSON bodies (collector port 4318) using only `@opentelemetry/api`,
|
|
25
|
+
* `sdk-trace-base`, `sdk-trace-node` and `resources`, so no exporter package is needed.
|
|
26
|
+
*
|
|
27
|
+
* Every call-scoped span, log record and metric carries `fonoster.call_ref`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CALL_REF_ATTR = "fonoster.call_ref";
|
|
30
|
+
type Attrs = Record<string, string | number | boolean>;
|
|
31
|
+
export interface CallSpan {
|
|
32
|
+
/** Adds a timeline event to the call's span. */
|
|
33
|
+
event(name: string, attrs?: Attrs): void;
|
|
34
|
+
/** Ends the span; `error` marks it failed. */
|
|
35
|
+
end(attrs?: Attrs, error?: string): void;
|
|
36
|
+
}
|
|
37
|
+
/** A span not tied to a call (a gRPC request, a registry command), optionally continuing a trace. */
|
|
38
|
+
export interface Span extends CallSpan {
|
|
39
|
+
/** The W3C `traceparent` of this span, to send with outgoing messages ("" when disabled). */
|
|
40
|
+
traceparent: string;
|
|
41
|
+
}
|
|
42
|
+
/** NATS/gRPC header carrying the W3C trace context between services. */
|
|
43
|
+
export declare const TRACEPARENT_HEADER = "traceparent";
|
|
44
|
+
export interface Telemetry {
|
|
45
|
+
enabled: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Starts the span of one call; the returned handle is a no-op when disabled. `parent` (a W3C
|
|
48
|
+
* traceparent from another service, e.g. the Roomr node) makes it a child in that trace.
|
|
49
|
+
*/
|
|
50
|
+
startCall(callRef: string, name: string, attrs?: Attrs, parent?: string): CallSpan;
|
|
51
|
+
/**
|
|
52
|
+
* Starts a span; with `parent` (a W3C traceparent received from another service) it joins that
|
|
53
|
+
* trace. A no-op handle when disabled.
|
|
54
|
+
*/
|
|
55
|
+
startSpan(name: string, attrs?: Attrs, parent?: string): Span;
|
|
56
|
+
/** The W3C traceparent of a call's span (to propagate over NATS), when one is active. */
|
|
57
|
+
traceparent(callRef: string): string | undefined;
|
|
58
|
+
/** An OTLP log record correlated by call ref (and the active trace, when any). */
|
|
59
|
+
log(level: "debug" | "info" | "warn" | "error", message: string, attrs?: Attrs & {
|
|
60
|
+
callRef?: string;
|
|
61
|
+
}): void;
|
|
62
|
+
/** Adds to a monotonic counter. */
|
|
63
|
+
count(name: string, value?: number, attrs?: Attrs): void;
|
|
64
|
+
/** Reads `fn` at every export and reports it as a gauge. */
|
|
65
|
+
gauge(name: string, fn: () => number, attrs?: Attrs): void;
|
|
66
|
+
/** Flushes and stops the exporters. */
|
|
67
|
+
shutdown(): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
/** True when any OTLP endpoint is configured and the SDK is not disabled. */
|
|
70
|
+
export declare function telemetryEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Starts telemetry for one service. Safe to call once at startup; returns a no-op handle when no
|
|
73
|
+
* OTLP endpoint is configured or the OpenTelemetry packages are not installed.
|
|
74
|
+
*/
|
|
75
|
+
export declare function initTelemetry(service: string, instanceId?: string, env?: Record<string, string | undefined>): Telemetry;
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
4
|
+
* http://github.com/fonoster/fonoster
|
|
5
|
+
*
|
|
6
|
+
* This file is part of Fonoster
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the MIT License (the "License");
|
|
9
|
+
* you may not use this file except in compliance with
|
|
10
|
+
* the License. You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* https://opensource.org/licenses/MIT
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/
|
|
20
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-require-imports */
|
|
21
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
31
|
+
var t = {};
|
|
32
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
33
|
+
t[p] = s[p];
|
|
34
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
35
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
36
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
37
|
+
t[p[i]] = s[p[i]];
|
|
38
|
+
}
|
|
39
|
+
return t;
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.TRACEPARENT_HEADER = exports.CALL_REF_ATTR = void 0;
|
|
43
|
+
exports.telemetryEnabled = telemetryEnabled;
|
|
44
|
+
exports.initTelemetry = initTelemetry;
|
|
45
|
+
/**
|
|
46
|
+
* OpenTelemetry bootstrap shared by the TypeScript services (add-platform, observability).
|
|
47
|
+
*
|
|
48
|
+
* Driven by the standard OTEL_* variables and a complete no-op when no OTLP endpoint is set:
|
|
49
|
+
* nothing is loaded, nothing is sent, and the service only writes its normal logs. Signals go
|
|
50
|
+
* over OTLP/HTTP with JSON bodies (collector port 4318) using only `@opentelemetry/api`,
|
|
51
|
+
* `sdk-trace-base`, `sdk-trace-node` and `resources`, so no exporter package is needed.
|
|
52
|
+
*
|
|
53
|
+
* Every call-scoped span, log record and metric carries `fonoster.call_ref`.
|
|
54
|
+
*/
|
|
55
|
+
exports.CALL_REF_ATTR = "fonoster.call_ref";
|
|
56
|
+
/** NATS/gRPC header carrying the W3C trace context between services. */
|
|
57
|
+
exports.TRACEPARENT_HEADER = "traceparent";
|
|
58
|
+
const NOOP_SPAN = {
|
|
59
|
+
event: () => undefined,
|
|
60
|
+
end: () => undefined,
|
|
61
|
+
traceparent: ""
|
|
62
|
+
};
|
|
63
|
+
const NOOP = {
|
|
64
|
+
enabled: false,
|
|
65
|
+
startCall: () => NOOP_SPAN,
|
|
66
|
+
startSpan: () => NOOP_SPAN,
|
|
67
|
+
traceparent: () => undefined,
|
|
68
|
+
log: () => undefined,
|
|
69
|
+
count: () => undefined,
|
|
70
|
+
gauge: () => undefined,
|
|
71
|
+
shutdown: () => __awaiter(void 0, void 0, void 0, function* () { return undefined; })
|
|
72
|
+
};
|
|
73
|
+
/** True when any OTLP endpoint is configured and the SDK is not disabled. */
|
|
74
|
+
function telemetryEnabled(env = process.env) {
|
|
75
|
+
if (env.OTEL_SDK_DISABLED === "true")
|
|
76
|
+
return false;
|
|
77
|
+
return [
|
|
78
|
+
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
79
|
+
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
80
|
+
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
|
|
81
|
+
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT"
|
|
82
|
+
].some((k) => !!env[k]);
|
|
83
|
+
}
|
|
84
|
+
function toValue(v) {
|
|
85
|
+
if (typeof v === "number")
|
|
86
|
+
return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };
|
|
87
|
+
if (typeof v === "boolean")
|
|
88
|
+
return { boolValue: v };
|
|
89
|
+
return { stringValue: String(v) };
|
|
90
|
+
}
|
|
91
|
+
function toAttrs(a = {}) {
|
|
92
|
+
return Object.entries(a)
|
|
93
|
+
.filter(([, v]) => v !== undefined && v !== null)
|
|
94
|
+
.map(([key, value]) => ({ key, value: toValue(value) }));
|
|
95
|
+
}
|
|
96
|
+
const hrToNano = (t) => (BigInt(t[0]) * BigInt(1000000000) + BigInt(t[1])).toString();
|
|
97
|
+
function signalUrl(env, signal) {
|
|
98
|
+
const specific = env[`OTEL_EXPORTER_OTLP_${signal.toUpperCase()}_ENDPOINT`];
|
|
99
|
+
if (specific)
|
|
100
|
+
return specific;
|
|
101
|
+
const base = env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
102
|
+
return base ? `${base.replace(/\/$/, "")}/v1/${signal}` : undefined;
|
|
103
|
+
}
|
|
104
|
+
function headers(env) {
|
|
105
|
+
var _a;
|
|
106
|
+
const h = { "content-type": "application/json" };
|
|
107
|
+
for (const pair of ((_a = env.OTEL_EXPORTER_OTLP_HEADERS) !== null && _a !== void 0 ? _a : "")
|
|
108
|
+
.split(",")
|
|
109
|
+
.filter(Boolean)) {
|
|
110
|
+
const i = pair.indexOf("=");
|
|
111
|
+
if (i > 0)
|
|
112
|
+
h[pair.slice(0, i).trim()] = pair.slice(i + 1).trim();
|
|
113
|
+
}
|
|
114
|
+
return h;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Starts telemetry for one service. Safe to call once at startup; returns a no-op handle when no
|
|
118
|
+
* OTLP endpoint is configured or the OpenTelemetry packages are not installed.
|
|
119
|
+
*/
|
|
120
|
+
function initTelemetry(service, instanceId, env) {
|
|
121
|
+
var _a, _b, _c;
|
|
122
|
+
if (instanceId === void 0) { instanceId = (_a = process.env.HOSTNAME) !== null && _a !== void 0 ? _a : String(process.pid); }
|
|
123
|
+
if (env === void 0) { env = process.env; }
|
|
124
|
+
if (!telemetryEnabled(env))
|
|
125
|
+
return NOOP;
|
|
126
|
+
let api, base, nodeSdk, resources;
|
|
127
|
+
try {
|
|
128
|
+
api = require("@opentelemetry/api");
|
|
129
|
+
base = require("@opentelemetry/sdk-trace-base");
|
|
130
|
+
nodeSdk = require("@opentelemetry/sdk-trace-node");
|
|
131
|
+
resources = require("@opentelemetry/resources");
|
|
132
|
+
}
|
|
133
|
+
catch (_d) {
|
|
134
|
+
return NOOP;
|
|
135
|
+
}
|
|
136
|
+
const resourceAttrs = {
|
|
137
|
+
"service.name": (_b = env.OTEL_SERVICE_NAME) !== null && _b !== void 0 ? _b : service,
|
|
138
|
+
"service.instance.id": instanceId
|
|
139
|
+
};
|
|
140
|
+
const resource = { attributes: toAttrs(resourceAttrs) };
|
|
141
|
+
const hdrs = headers(env);
|
|
142
|
+
const post = (url, body) => {
|
|
143
|
+
if (!url)
|
|
144
|
+
return Promise.resolve();
|
|
145
|
+
return fetch(url, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: hdrs,
|
|
148
|
+
body: JSON.stringify(body)
|
|
149
|
+
})
|
|
150
|
+
.then(() => undefined)
|
|
151
|
+
.catch(() => undefined);
|
|
152
|
+
};
|
|
153
|
+
// Traces
|
|
154
|
+
const tracesUrl = signalUrl(env, "traces");
|
|
155
|
+
const exporter = {
|
|
156
|
+
export(spans, done) {
|
|
157
|
+
const body = {
|
|
158
|
+
resourceSpans: [
|
|
159
|
+
{
|
|
160
|
+
resource,
|
|
161
|
+
scopeSpans: [
|
|
162
|
+
{
|
|
163
|
+
scope: { name: "fonoster" },
|
|
164
|
+
spans: spans.map((s) => {
|
|
165
|
+
var _a, _b;
|
|
166
|
+
return ({
|
|
167
|
+
traceId: s.spanContext().traceId,
|
|
168
|
+
spanId: s.spanContext().spanId,
|
|
169
|
+
parentSpanId: ((_a = s.parentSpanContext) === null || _a === void 0 ? void 0 : _a.spanId) || undefined,
|
|
170
|
+
name: s.name,
|
|
171
|
+
kind: 1 + ((_b = s.kind) !== null && _b !== void 0 ? _b : 0),
|
|
172
|
+
startTimeUnixNano: hrToNano(s.startTime),
|
|
173
|
+
endTimeUnixNano: hrToNano(s.endTime),
|
|
174
|
+
attributes: toAttrs(s.attributes),
|
|
175
|
+
events: s.events.map((e) => ({
|
|
176
|
+
name: e.name,
|
|
177
|
+
timeUnixNano: hrToNano(e.time),
|
|
178
|
+
attributes: toAttrs(e.attributes)
|
|
179
|
+
})),
|
|
180
|
+
status: s.status.code === 2
|
|
181
|
+
? { code: 2, message: s.status.message }
|
|
182
|
+
: { code: s.status.code }
|
|
183
|
+
});
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
};
|
|
190
|
+
void post(tracesUrl, body).then(() => done({ code: 0 }));
|
|
191
|
+
},
|
|
192
|
+
shutdown: () => __awaiter(this, void 0, void 0, function* () { return undefined; })
|
|
193
|
+
};
|
|
194
|
+
const provider = new nodeSdk.NodeTracerProvider({
|
|
195
|
+
resource: resources.resourceFromAttributes(resourceAttrs),
|
|
196
|
+
spanProcessors: [new base.BatchSpanProcessor(exporter)]
|
|
197
|
+
});
|
|
198
|
+
provider.register();
|
|
199
|
+
// The provider's own tracer: the global one stays the first registered (tests init twice).
|
|
200
|
+
const tracer = provider.getTracer("fonoster");
|
|
201
|
+
// Logs
|
|
202
|
+
const logsUrl = signalUrl(env, "logs");
|
|
203
|
+
const logQueue = [];
|
|
204
|
+
const severity = { debug: 5, info: 9, warn: 13, error: 17 };
|
|
205
|
+
const flushLogs = () => {
|
|
206
|
+
if (!logQueue.length)
|
|
207
|
+
return Promise.resolve();
|
|
208
|
+
const records = logQueue.splice(0);
|
|
209
|
+
return post(logsUrl, {
|
|
210
|
+
resourceLogs: [
|
|
211
|
+
{
|
|
212
|
+
resource,
|
|
213
|
+
scopeLogs: [{ scope: { name: "fonoster" }, logRecords: records }]
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
// Metrics
|
|
219
|
+
const metricsUrl = signalUrl(env, "metrics");
|
|
220
|
+
const startNs = (BigInt(Date.now()) * BigInt(1000000)).toString();
|
|
221
|
+
const counters = new Map();
|
|
222
|
+
const gauges = [];
|
|
223
|
+
const flushMetrics = () => {
|
|
224
|
+
const now = (BigInt(Date.now()) * BigInt(1000000)).toString();
|
|
225
|
+
const metrics = [];
|
|
226
|
+
for (const [name, series] of counters) {
|
|
227
|
+
metrics.push({
|
|
228
|
+
name,
|
|
229
|
+
sum: {
|
|
230
|
+
aggregationTemporality: 2,
|
|
231
|
+
isMonotonic: true,
|
|
232
|
+
dataPoints: series.map((s) => ({
|
|
233
|
+
asInt: String(s.value),
|
|
234
|
+
startTimeUnixNano: startNs,
|
|
235
|
+
timeUnixNano: now,
|
|
236
|
+
attributes: toAttrs(s.attrs)
|
|
237
|
+
}))
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
for (const g of gauges) {
|
|
242
|
+
let v = 0;
|
|
243
|
+
try {
|
|
244
|
+
v = g.fn();
|
|
245
|
+
}
|
|
246
|
+
catch (_a) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
metrics.push({
|
|
250
|
+
name: g.name,
|
|
251
|
+
gauge: {
|
|
252
|
+
dataPoints: [
|
|
253
|
+
{ asDouble: v, timeUnixNano: now, attributes: toAttrs(g.attrs) }
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (!metrics.length)
|
|
259
|
+
return Promise.resolve();
|
|
260
|
+
return post(metricsUrl, {
|
|
261
|
+
resourceMetrics: [
|
|
262
|
+
{
|
|
263
|
+
resource,
|
|
264
|
+
scopeMetrics: [{ scope: { name: "fonoster" }, metrics }]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
const timer = setInterval(() => {
|
|
270
|
+
void flushLogs();
|
|
271
|
+
void flushMetrics();
|
|
272
|
+
}, Number((_c = env.OTEL_METRIC_EXPORT_INTERVAL) !== null && _c !== void 0 ? _c : 15000));
|
|
273
|
+
timer.unref();
|
|
274
|
+
const spanOf = new Map();
|
|
275
|
+
const contextOf = (parent) => parent
|
|
276
|
+
? api.propagation.extract(api.context.active(), {
|
|
277
|
+
[exports.TRACEPARENT_HEADER]: parent
|
|
278
|
+
})
|
|
279
|
+
: api.context.active();
|
|
280
|
+
const traceparentOf = (span) => {
|
|
281
|
+
var _a;
|
|
282
|
+
const carrier = {};
|
|
283
|
+
api.propagation.inject(api.trace.setSpan(api.context.active(), span), carrier);
|
|
284
|
+
return (_a = carrier[exports.TRACEPARENT_HEADER]) !== null && _a !== void 0 ? _a : "";
|
|
285
|
+
};
|
|
286
|
+
return {
|
|
287
|
+
enabled: true,
|
|
288
|
+
startSpan(name, attrs, parent) {
|
|
289
|
+
const span = tracer.startSpan(name, { attributes: attrs }, contextOf(parent));
|
|
290
|
+
return {
|
|
291
|
+
traceparent: traceparentOf(span),
|
|
292
|
+
event: (n, a) => span.addEvent(n, a),
|
|
293
|
+
end: (a, error) => {
|
|
294
|
+
if (a)
|
|
295
|
+
span.setAttributes(a);
|
|
296
|
+
if (error)
|
|
297
|
+
span.setStatus({ code: 2, message: error });
|
|
298
|
+
span.end();
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
traceparent(callRef) {
|
|
303
|
+
const span = spanOf.get(callRef);
|
|
304
|
+
return span ? traceparentOf(span) : undefined;
|
|
305
|
+
},
|
|
306
|
+
startCall(callRef, name, attrs, parent) {
|
|
307
|
+
const span = tracer.startSpan(name, { attributes: Object.assign({ [exports.CALL_REF_ATTR]: callRef }, attrs) }, contextOf(parent));
|
|
308
|
+
spanOf.set(callRef, span);
|
|
309
|
+
return {
|
|
310
|
+
event: (n, a) => span.addEvent(n, Object.assign({ [exports.CALL_REF_ATTR]: callRef }, a)),
|
|
311
|
+
end: (a, error) => {
|
|
312
|
+
if (a)
|
|
313
|
+
span.setAttributes(a);
|
|
314
|
+
if (error)
|
|
315
|
+
span.setStatus({ code: 2, message: error });
|
|
316
|
+
span.end();
|
|
317
|
+
spanOf.delete(callRef);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
log(level, message, attrs = {}) {
|
|
322
|
+
var _a, _b, _c;
|
|
323
|
+
const { callRef } = attrs, rest = __rest(attrs, ["callRef"]);
|
|
324
|
+
const span = callRef ? spanOf.get(callRef) : undefined;
|
|
325
|
+
const ctx = (_b = (_a = span === null || span === void 0 ? void 0 : span.spanContext) === null || _a === void 0 ? void 0 : _a.call(span)) !== null && _b !== void 0 ? _b : (_c = api.trace.getActiveSpan()) === null || _c === void 0 ? void 0 : _c.spanContext();
|
|
326
|
+
logQueue.push({
|
|
327
|
+
timeUnixNano: (BigInt(Date.now()) * BigInt(1000000)).toString(),
|
|
328
|
+
severityNumber: severity[level],
|
|
329
|
+
severityText: level.toUpperCase(),
|
|
330
|
+
body: { stringValue: message },
|
|
331
|
+
attributes: toAttrs(callRef ? Object.assign({ [exports.CALL_REF_ATTR]: callRef }, rest) : rest),
|
|
332
|
+
traceId: ctx === null || ctx === void 0 ? void 0 : ctx.traceId,
|
|
333
|
+
spanId: ctx === null || ctx === void 0 ? void 0 : ctx.spanId
|
|
334
|
+
});
|
|
335
|
+
if (logQueue.length >= 100)
|
|
336
|
+
void flushLogs();
|
|
337
|
+
},
|
|
338
|
+
count(name, value = 1, attrs = {}) {
|
|
339
|
+
var _a;
|
|
340
|
+
const series = (_a = counters.get(name)) !== null && _a !== void 0 ? _a : [];
|
|
341
|
+
const key = JSON.stringify(attrs);
|
|
342
|
+
const hit = series.find((s) => JSON.stringify(s.attrs) === key);
|
|
343
|
+
if (hit)
|
|
344
|
+
hit.value += value;
|
|
345
|
+
else
|
|
346
|
+
series.push({ attrs, value });
|
|
347
|
+
counters.set(name, series);
|
|
348
|
+
},
|
|
349
|
+
gauge(name, fn, attrs) {
|
|
350
|
+
gauges.push({ name, fn, attrs });
|
|
351
|
+
},
|
|
352
|
+
shutdown() {
|
|
353
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
354
|
+
clearInterval(timer);
|
|
355
|
+
yield provider.shutdown().catch(() => undefined);
|
|
356
|
+
yield Promise.all([flushLogs(), flushMetrics()]);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
type NumberPreconditionsCheck = (request: {
|
|
20
20
|
appRef?: string;
|
|
21
21
|
agentAor?: string;
|
|
22
|
+
/** The caller's workspace: an appRef must belong to it (RV-B4). */
|
|
23
|
+
accessKeyId?: string;
|
|
22
24
|
}) => Promise<void>;
|
|
23
|
-
|
|
24
|
-
productRef: string;
|
|
25
|
-
credentials: Record<string, unknown>;
|
|
26
|
-
};
|
|
27
|
-
export { NumberPreconditionsCheck, IntegrationConfig };
|
|
25
|
+
export { NumberPreconditionsCheck };
|
|
@@ -16,22 +16,23 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
finishOnKey?: string;
|
|
27
|
-
maxDigits?: number;
|
|
28
|
-
timeout?: number;
|
|
29
|
-
source?: GatherSource;
|
|
30
|
-
};
|
|
31
|
-
type GatherRequest = VerbRequest & GatherOptions;
|
|
32
|
-
type GatherResponse = VerbResponse & {
|
|
33
|
-
speech?: string;
|
|
34
|
-
digits?: string;
|
|
35
|
-
responseTime: number;
|
|
19
|
+
import { MeterName } from "./meters";
|
|
20
|
+
import { KeySource, UsageLine } from "./types";
|
|
21
|
+
type Key = {
|
|
22
|
+
meter: MeterName;
|
|
23
|
+
provider?: string;
|
|
24
|
+
model?: string;
|
|
25
|
+
keySource?: KeySource;
|
|
36
26
|
};
|
|
37
|
-
|
|
27
|
+
/**
|
|
28
|
+
* A call's usage, accumulated in memory while it runs (design D1). One entry per meter, provider,
|
|
29
|
+
* model and key source; seconds are kept exact and rounded up only when lines are taken.
|
|
30
|
+
*/
|
|
31
|
+
export declare class CallUsage {
|
|
32
|
+
private readonly entries;
|
|
33
|
+
add(line: UsageLine): void;
|
|
34
|
+
/** Adds seconds of a meter measured as a duration in milliseconds. */
|
|
35
|
+
addMillis(key: Key, ms: number): void;
|
|
36
|
+
lines(): UsageLine[];
|
|
37
|
+
}
|
|
38
|
+
export {};
|