Compare commits

..

7 Commits

Author SHA1 Message Date
Dave Horton
4f373d2fbc bump version 2026-03-31 07:43:27 -04:00
Sam Machin
24d9740618 add x-reason to sip-decline (#1518)
* add x-ver to sip-decline

* lint

* Update sip_decline.js

---------

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2026-03-29 16:19:15 -04:00
rhondahollis
39746598b5 add null check for eventHook (#1534)
* add null check for eventHook

* move guard to superclass, remove logging that adds no value

---------

Co-authored-by: rhonda hollis <rhonda@jambonz.org>
Co-authored-by: Dave Horton <daveh@beachdognet.com>
2026-03-29 16:13:35 -04:00
Sam Machin
315eb98d86 add sp_sid to alerts (#1533)
* add sp_sid to alerts

* bump time-series

---------

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2026-03-29 16:07:08 -04:00
Dave Horton
df30496dac fix uncaught exception referencing this.ep in freeswitch hangup scenario (#1532) 2026-03-27 08:31:32 -04:00
Sam Machin
5d6751782a Fix/hangup call (#1530)
* Update error.js

* Update error.js
2026-03-26 08:20:28 -04:00
rhondahollis
6147ec3f6a ensure sbcCallId is added to callInfo (#1529)
Co-authored-by: rhonda hollis <rhonda@jambonz.org>
2026-03-25 17:00:05 -04:00
21 changed files with 249 additions and 185 deletions

View File

@@ -246,6 +246,7 @@ router.post('/',
if ('WS' === app.call_hook?.method || /^wss?:/.test(app.call_hook.url)) {
logger.debug({call_hook: app.call_hook}, 'creating websocket for call hook');
app.requestor = new WsRequestor(logger, account.account_sid, app.call_hook, account.webhook_secret) ;
app.requestor.service_provider_sid = account.service_provider_sid;
if (app.call_hook.url === app.call_status_hook?.url || !app.call_status_hook?.url) {
logger.debug('reusing websocket for call status hook');
app.notifier = app.requestor;
@@ -255,9 +256,11 @@ router.post('/',
else {
logger.debug({call_hook: app.call_hook}, 'creating http client for call hook');
app.requestor = new HttpRequestor(logger, account.account_sid, app.call_hook, account.webhook_secret);
app.requestor.service_provider_sid = account.service_provider_sid;
}
if (!app.notifier && app.call_status_hook) {
app.notifier = new HttpRequestor(logger, account.account_sid, app.call_status_hook, account.webhook_secret);
app.notifier.service_provider_sid = account.service_provider_sid;
logger.debug({call_status_hook: app.call_status_hook}, 'creating http client for call status hook');
}
else if (!app.notifier) {
@@ -340,6 +343,12 @@ router.post('/',
}
});
connectStream(dlg.remote.sdp);
/* ensure sbcCallid is set even if no provisional response was received */
if (!cs.callInfo.sbcCallid && dlg.res.has('X-CID')) {
cs.callInfo.sbcCallid = dlg.res.get('X-CID');
}
cs.emit('callStatusChange', {
callStatus: CallStatus.InProgress,
sipStatus: 200,

View File

@@ -6,8 +6,8 @@ function sysError(logger, res, err) {
return res.status(400).json({msg: err.message});
}
if (err instanceof DbErrorUnprocessableRequest) {
logger.info(err, 'unprocessable request');
return res.status(422).json({msg: err.message});
logger.info({message: err.message}, 'unprocessable request');
return res.status(422).send(err.message);
}
if (err.code === 'ER_DUP_ENTRY') {
logger.info(err, 'duplicate entry on insert');

View File

@@ -23,10 +23,12 @@ router.post('/:partner', async(req, res) => {
if ('WS' === hook?.method) {
app.requestor = new WsRequestor(logger, account.account_sid, hook, account.webhook_secret) ;
app.requestor.service_provider_sid = account.service_provider_sid;
app.notifier = app.requestor;
}
else {
app.requestor = new HttpRequestor(logger, account.account_sid, hook, account.webhook_secret);
app.requestor.service_provider_sid = account.service_provider_sid;
app.notifier = {request: () => {}};
}

View File

@@ -331,14 +331,19 @@ module.exports = function(srf, logger) {
if ('WS' === app.call_hook?.method ||
app.call_hook?.url.startsWith('ws://') || app.call_hook?.url.startsWith('wss://')) {
const requestor = new WsRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret) ;
requestor.service_provider_sid = accountInfo.account.service_provider_sid;
app2.requestor = requestor;
app2.notifier = requestor;
app2.call_hook.method = 'WS';
}
else {
app2.requestor = new HttpRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret);
if (app.call_status_hook) app2.notifier = new HttpRequestor(logger, account_sid, app.call_status_hook,
accountInfo.account.webhook_secret);
app2.requestor.service_provider_sid = accountInfo.account.service_provider_sid;
if (app.call_status_hook) {
app2.notifier = new HttpRequestor(logger, account_sid, app.call_status_hook,
accountInfo.account.webhook_secret);
app2.notifier.service_provider_sid = accountInfo.account.service_provider_sid;
}
else app2.notifier = {request: () => {}, close: () => {}};
}
@@ -478,6 +483,7 @@ module.exports = function(srf, logger) {
span?.end();
writeAlerts({
account_sid: req.locals.account_sid,
service_provider_sid: req.locals.service_provider_sid,
target_sid: req.locals.callSid,
alert_type: AlertType.INVALID_APP_PAYLOAD,
message: `${err?.message}`.trim()

View File

@@ -452,6 +452,10 @@ class CallSession extends Emitter {
return this.callInfo.accountSid;
}
get serviceProviderSid() {
return this.accountInfo?.account?.service_provider_sid;
}
/**
* returns true if this session was transferred from another server
*/
@@ -637,6 +641,7 @@ class CallSession extends Emitter {
writeAlerts({
alert_type: 'bot-action-delay-giveup',
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
message: 'Call terminated due to bot action delay timeout',
target_sid: this.callSid
});
@@ -1094,6 +1099,7 @@ class CallSession extends Emitter {
writeAlerts({
alert_type: AlertType.TTS_FAILURE,
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
vendor,
target_sid: this.callSid
}).catch((err) => this.logger.error({err}, 'Error writing tts alert'));
@@ -1293,6 +1299,7 @@ class CallSession extends Emitter {
writeAlerts({
alert_type: type === 'tts' ? AlertType.TTS_NOT_PROVISIONED : AlertType.STT_NOT_PROVISIONED,
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
vendor,
label,
target_sid: this.callSid
@@ -2056,6 +2063,7 @@ Duration=${duration} `
writeAlerts({
alert_type: 'error-updating-call',
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
message: err.message,
target_sid: callSid
});
@@ -2253,6 +2261,7 @@ Duration=${duration} `
await writeAlerts({
alert_type: AlertType.WEBHOOK_CONNECTION_FAILURE,
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
detail: `Session:reconnect error ${err}`,
url: this.application.call_hook.url,
});
@@ -2476,7 +2485,7 @@ Duration=${duration} `
this.logger.info(`allocated endpoint ${ep.uuid}`);
this.ep.on('destroy', () => {
this.logger.debug(`endpoint was destroyed!! ${this.ep.uuid}`);
this.logger.debug(`endpoint was destroyed!! ${this.ep?.uuid}`);
});
if (this.direction === CallDirection.Inbound || this.application?.transferredCall) {
@@ -2885,6 +2894,7 @@ Duration=${duration} `
this.logger.debug({accountSid: this.accountSid, webhook: r[0]}, 'performQueueWebhook: webhook found');
this.queueEventHookRequestor = new HttpRequestor(this.logger, this.accountSid,
r[0], this.webhook_secret);
this.queueEventHookRequestor.service_provider_sid = this.serviceProviderSid;
this.queueEventHook = r[0];
}
} catch (err) {
@@ -3221,6 +3231,7 @@ Duration=${duration} `
await writeAlerts({
alert_type: AlertType.TTS_STREAMING_CONNECTION_FAILURE,
account_sid: this.accountSid,
service_provider_sid: this.serviceProviderSid,
vendor
});
} catch (error) {

View File

@@ -15,6 +15,7 @@ class TaskAlert extends Task {
await super.exec(cs);
writeAlerts({
account_sid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.APPLICATION,
detail: `Application SID ${application_sid}`,
message: this.message,

View File

@@ -726,6 +726,7 @@ class TaskGather extends SttTask {
this.logger.error(err, 'TaskGather:_startTranscribing error');
writeAlerts({
account_sid: this.cs.accountSid,
service_provider_sid: this.cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
vendor: this.vendor,
detail: err.message,
@@ -1205,6 +1206,7 @@ class TaskGather extends SttTask {
const errMessage = evt.error || evt.Message;
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
message: `Custom speech vendor ${this.vendor} error: ${errMessage}`,
vendor: this.vendor,
@@ -1430,6 +1432,7 @@ class TaskGather extends SttTask {
const {writeAlerts, AlertType} = this.cs.srf.locals;
writeAlerts({
account_sid: this.cs.accountSid,
service_provider_sid: this.cs.serviceProviderSid,
alert_type: AlertType.INVALID_APP_PAYLOAD,
target_sid: this.cs.callSid,
message: `actionHook returned invalid verb syntax: ${err.message}`

View File

@@ -105,6 +105,7 @@ class TaskLlm extends Task {
}
async sendEventHook(data) {
if (!this.eventHook) return;
await this.cs?.requestor.request('llm:event', this.eventHook, data);
}

View File

@@ -105,6 +105,7 @@ class TaskPlay extends Task {
this.emit('playDone');
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.PLAY_FILENOTFOUND,
url: this.url,
target_sid: cs.callSid

View File

@@ -26,6 +26,7 @@ class TaskRedirect extends Task {
try {
const requestor = new WsRequestor(this.logger, cs.accountSid, {url: this.actionHook},
cs.accountInfo.account.webhook_secret) ;
requestor.service_provider_sid = cs.serviceProviderSid;
cs.requestor.emit('handover', requestor);
} catch (err) {
this.logger.info(err, `TaskRedirect error redirecting to ${this.actionHook}`);
@@ -40,6 +41,7 @@ class TaskRedirect extends Task {
this.logger.info(`Task:redirect updating base url to ${newBaseUrl}`);
const newRequestor = new HttpRequestor(this.logger, cs.accountSid, {url: this.actionHook},
cs.accountInfo.account.webhook_secret);
newRequestor.service_provider_sid = cs.serviceProviderSid;
cs.requestor.emit('handover', newRequestor);
} catch (err) {
this.logger.info(err, `TaskRedirect error updating base url to ${this.actionHook}`);
@@ -56,11 +58,15 @@ class TaskRedirect extends Task {
const isStatusHookAbsolute = cs.notifier?._isAbsoluteUrl(this.statusHook);
if (isStatusHookAbsolute) {
if (cs.notifier instanceof WsRequestor) {
cs.application.notifier = new WsRequestor(this.logger, cs.accountSid, {url: this.statusHook},
const notifier = new WsRequestor(this.logger, cs.accountSid, {url: this.statusHook},
cs.accountInfo.account.webhook_secret);
notifier.service_provider_sid = cs.serviceProviderSid;
cs.application.notifier = notifier;
} else {
cs.application.notifier = new HttpRequestor(this.logger, cs.accountSid, {url: this.statusHook},
const notifier = new HttpRequestor(this.logger, cs.accountSid, {url: this.statusHook},
cs.accountInfo.account.webhook_secret);
notifier.service_provider_sid = cs.serviceProviderSid;
cs.application.notifier = notifier;
}
if (oldNotifier?.close) oldNotifier.close();
}

View File

@@ -326,6 +326,7 @@ class TaskSay extends TtsTask {
response_code <= 199 || response_code >= 300) {
writeAlerts({
account_sid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.TTS_FAILURE,
vendor,
detail: evt.variable_tts_error || `TTS playback failed with response code ${response_code}`,

View File

@@ -17,7 +17,7 @@ class TaskSipDecline extends Task {
async exec(cs, {res}) {
super.exec(cs);
res.send(this.data.status, this.data.reason, {
headers: this.headers
headers: {'X-Reason': 'SIP Decline Verb', ...this.headers}
}, (err) => {
if (!err) {
// Call was successfully declined

View File

@@ -274,6 +274,7 @@ class SttTask extends Task {
this.logger.info(`ERROR stt using ${vendor} requested but creds not supplied`);
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_NOT_PROVISIONED,
vendor,
label,
@@ -473,6 +474,7 @@ class SttTask extends Task {
const {writeAlerts, AlertType} = cs.srf.locals;
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
message: 'STT failure reported by vendor',
detail: evt.error,
@@ -488,6 +490,7 @@ class SttTask extends Task {
this.logger.info({evt}, `${this.name}:_on${this.vendor}ConnectFailure`);
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
message: `Failed connecting to ${this.vendor} speech recognizer: ${reason}`,
vendor: this.vendor,

View File

@@ -843,6 +843,7 @@ class TaskTranscribe extends SttTask {
this.logger.info({evt}, 'TaskTranscribe:_onJambonzError');
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
message: `Custom speech vendor ${this.vendor} error: ${evt.error}`,
vendor: this.vendor,

View File

@@ -282,6 +282,7 @@ class TtsTask extends Task {
if (!credentials) {
writeAlerts({
account_sid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.TTS_NOT_PROVISIONED,
vendor,
label,
@@ -369,6 +370,7 @@ class TtsTask extends Task {
if (this.otelSpan) this.otelSpan.end();
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.TTS_FAILURE,
vendor,
label,

View File

@@ -219,6 +219,7 @@ module.exports = (logger) => {
logger.error(err, 'amd:_startTranscribing error');
writeAlerts({
account_sid: cs.accountSid,
service_provider_sid: cs.serviceProviderSid,
alert_type: AlertType.STT_FAILURE,
vendor: vendor,
detail: err.message,

View File

@@ -128,6 +128,7 @@ class HttpRequestor extends BaseRequestor {
this.logger.debug({hook}, 'HttpRequestor: switching to websocket connection');
const h = typeof hook === 'object' ? hook : {url: hook};
const requestor = new WsRequestor(this.logger, this.account_sid, h, this.secret);
requestor.service_provider_sid = this.service_provider_sid;
if (type === 'session:redirect') {
this.close();
this.emit('handover', requestor);
@@ -248,7 +249,7 @@ class HttpRequestor extends BaseRequestor {
this.logger.error({err, baseUrl: this.baseUrl, url},
'web callback returned unexpected error');
}
let opts = {account_sid: this.account_sid};
let opts = {account_sid: this.account_sid, service_provider_sid: this.service_provider_sid};
if (err.code === 'ECONNREFUSED') {
opts = {...opts, alert_type: this.Alerter.AlertType.WEBHOOK_CONNECTION_FAILURE, url};
}

View File

@@ -234,6 +234,11 @@ class SingleDialer extends Emitter {
await connectStream(this.dlg.remote.sdp, opts.isVideoCall);
this.dlg.callSid = this.callSid;
this.inviteInProgress = null;
/* ensure sbcCallid is set even if no provisional response was received */
if (!this.callInfo.sbcCallid && this.dlg.res.has('X-CID')) {
this.callInfo.sbcCallid = this.dlg.res.get('X-CID');
}
this.emit('callStatusChange', {
sipStatus: 200,
sipReason: 'OK',
@@ -450,6 +455,7 @@ class SingleDialer extends Emitter {
if (app.call_hook?.url) app.call_hook.url += '/adulting';
const requestor = new WsRequestor(logger, this.accountInfo.account.account_sid,
app.call_hook, this.accountInfo.account.webhook_secret);
requestor.service_provider_sid = this.accountInfo.account.service_provider_sid;
app.requestor = requestor;
app.notifier = requestor;
app.call_hook.method = 'WS';
@@ -457,9 +463,13 @@ class SingleDialer extends Emitter {
else {
app.requestor = new HttpRequestor(logger, this.accountInfo.account.account_sid,
app.call_hook, this.accountInfo.account.webhook_secret);
if (app.call_status_hook) app.notifier = new HttpRequestor(logger,
this.accountInfo.account.account_sid, app.call_status_hook,
this.accountInfo.account.webhook_secret);
app.requestor.service_provider_sid = this.accountInfo.account.service_provider_sid;
if (app.call_status_hook) {
app.notifier = new HttpRequestor(logger,
this.accountInfo.account.account_sid, app.call_status_hook,
this.accountInfo.account.webhook_secret);
app.notifier.service_provider_sid = this.accountInfo.account.service_provider_sid;
}
else app.notifier = {request: () => {}, close: () => {}};
}
// Replace old application with new application.

View File

@@ -97,6 +97,7 @@ class WsRequestor extends BaseRequestor {
this.logger.debug({hook}, 'WsRequestor: sending a webhook (HTTP)');
const h = typeof hook === 'object' ? hook : {url: hook};
const requestor = new HttpRequestor(this.logger, this.account_sid, h, this.secret);
requestor.service_provider_sid = this.service_provider_sid;
if (type === 'session:redirect') {
this.close();
this.emit('handover', requestor);
@@ -522,6 +523,7 @@ class WsRequestor extends BaseRequestor {
const {writeAlerts, AlertType} = this.Alerter;
writeAlerts({
account_sid: this.account_sid,
service_provider_sid: this.service_provider_sid,
alert_type: AlertType.INVALID_APP_PAYLOAD,
target_sid: this.call_sid,
message: err.message,

345
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "jambonz-feature-server",
"version": "0.9.5",
"version": "0.9.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "jambonz-feature-server",
"version": "0.9.5",
"version": "0.9.6",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-auto-scaling": "^3.549.0",
@@ -17,7 +17,7 @@
"@jambonz/realtimedb-helpers": "^0.8.15",
"@jambonz/speech-utils": "^0.2.30",
"@jambonz/stats-collector": "^0.1.10",
"@jambonz/time-series": "^0.2.15",
"@jambonz/time-series": "^0.2.17",
"@jambonz/verb-specifications": "^0.0.125",
"@modelcontextprotocol/sdk": "^1.9.0",
"@opentelemetry/api": "^1.8.0",
@@ -847,13 +847,13 @@
}
},
"node_modules/@aws-sdk/xml-builder": {
"version": "3.972.9",
"resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.9.tgz",
"integrity": "sha512-ItnlMgSqkPrUfJs7EsvU/01zw5UeIb2tNPhD09LBLHbg+g+HDiKibSLwpkuz/ZIlz4F2IMn+5XgE4AK/pfPuog==",
"version": "3.972.16",
"resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.16.tgz",
"integrity": "sha512-iu2pyvaqmeatIJLURLqx9D+4jKAdTH20ntzB6BFwjyN7V960r4jK32mx0Zf7YbtOYAbmbtQfDNuL60ONinyw7A==",
"license": "Apache-2.0",
"dependencies": {
"@smithy/types": "^4.13.0",
"fast-xml-parser": "5.4.1",
"@smithy/types": "^4.13.1",
"fast-xml-parser": "5.5.8",
"tslib": "^2.6.2"
},
"engines": {
@@ -1270,6 +1270,16 @@
"node": ">=6.9.0"
}
},
"node_modules/@borewit/text-codec": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz",
"integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/@cartesia/cartesia-js": {
"version": "2.2.9",
"resolved": "https://registry.npmjs.org/@cartesia/cartesia-js/-/cartesia-js-2.2.9.tgz",
@@ -1627,9 +1637,9 @@
}
},
"node_modules/@jambonz/time-series": {
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.16.tgz",
"integrity": "sha512-+WRXZRkLHMEmXjtxGCZta7XVJXOd98+Yz5WsTnXxd3Aa7hg+wJBjmDrVuj8JvTV4nUIBFZ5TuYpIQDVyYJuwlQ==",
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.17.tgz",
"integrity": "sha512-bqglB1INDo+jo4XgHHq3twomZc2sTz9eR14t+4tck4TEvHH51ywvsPQqUQ/CqH0PR9rNTQn+yn7+Hq0X88kbtA==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.1",
@@ -3110,9 +3120,9 @@
}
},
"node_modules/@smithy/types": {
"version": "4.13.0",
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.0.tgz",
"integrity": "sha512-COuLsZILbbQsdrwKQpkkpyep7lCsByxwj7m0Mg5v66/ZTyenlfBc40/QFQ5chO0YN/PNEH1Bi3fGtfXPnYNeDw==",
"version": "4.13.1",
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.13.1.tgz",
"integrity": "sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.6.2"
@@ -3354,21 +3364,29 @@
"node": ">=18.0.0"
}
},
"node_modules/@tokenizer/inflate": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
"integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.3",
"token-types": "^6.1.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
"license": "MIT"
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
"license": "MIT",
"engines": {
"node": ">= 10"
}
},
"node_modules/@types/async": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.25.tgz",
@@ -3927,9 +3945,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5479,12 +5497,12 @@
}
},
"node_modules/express-rate-limit": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz",
"integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==",
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz",
"integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==",
"license": "MIT",
"dependencies": {
"ip-address": "10.0.1"
"ip-address": "10.1.0"
},
"engines": {
"node": ">= 16"
@@ -5594,21 +5612,9 @@
"license": "BSD-3-Clause"
},
"node_modules/fast-xml-builder": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz",
"integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT"
},
"node_modules/fast-xml-parser": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz",
"integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz",
"integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==",
"funding": [
{
"type": "github",
@@ -5617,8 +5623,24 @@
],
"license": "MIT",
"dependencies": {
"fast-xml-builder": "^1.0.0",
"strnum": "^2.1.2"
"path-expression-matcher": "^1.1.3"
}
},
"node_modules/fast-xml-parser": {
"version": "5.5.8",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz",
"integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT",
"dependencies": {
"fast-xml-builder": "^1.1.4",
"path-expression-matcher": "^1.2.0",
"strnum": "^2.2.0"
},
"bin": {
"fxparser": "src/cli/cli.js"
@@ -5670,17 +5692,18 @@
}
},
"node_modules/file-type": {
"version": "16.5.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"version": "21.3.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz",
"integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==",
"license": "MIT",
"dependencies": {
"readable-web-to-node-stream": "^3.0.0",
"strtok3": "^6.2.4",
"token-types": "^4.1.1"
"@tokenizer/inflate": "^0.4.1",
"strtok3": "^10.3.4",
"token-types": "^6.1.1",
"uint8array-extras": "^1.4.0"
},
"engines": {
"node": ">=10"
"node": ">=20"
},
"funding": {
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
@@ -5788,9 +5811,9 @@
}
},
"node_modules/flatted": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"dev": true,
"license": "ISC"
},
@@ -6005,9 +6028,9 @@
}
},
"node_modules/gaxios/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
"integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -6335,9 +6358,9 @@
}
},
"node_modules/google-gax/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
"integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -6647,9 +6670,9 @@
}
},
"node_modules/hono": {
"version": "4.12.5",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.5.tgz",
"integrity": "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg==",
"version": "4.12.9",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz",
"integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==",
"license": "MIT",
"engines": {
"node": ">=16.9.0"
@@ -6695,29 +6718,16 @@
}
},
"node_modules/http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"license": "MIT",
"dependencies": {
"@tootallnate/once": "2",
"agent-base": "6",
"debug": "4"
"agent-base": "^7.1.0",
"debug": "^4.3.4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/http-proxy-agent/node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
"node": ">= 14"
}
},
"node_modules/https-proxy-agent": {
@@ -6752,23 +6762,24 @@
}
},
"node_modules/ibm-cloud-sdk-core": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.5.tgz",
"integrity": "sha512-7ClYtr/Xob83hypKUa1D9N8/ViH71giKQ0kqjHcoyKum6yvwsWAeFA6zf6WTWb+DdZ1XSBrMPhgCCoy0bqReLg==",
"version": "5.4.9",
"resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.9.tgz",
"integrity": "sha512-340fGcZEwUBdxBOPmn8V8fIiFRWF92yFqSFRNLwPQz4h+PS4jcAyd3JGqU6CpFqzUTt+PatVX/jHFwzUTVdmxQ==",
"license": "Apache-2.0",
"dependencies": {
"@types/debug": "^4.1.12",
"@types/node": "^18.19.80",
"@types/tough-cookie": "^4.0.0",
"axios": "^1.12.2",
"axios": "^1.13.5",
"camelcase": "^6.3.0",
"debug": "^4.3.4",
"dotenv": "^16.4.5",
"extend": "3.0.2",
"file-type": "16.5.4",
"file-type": "^21.3.2",
"form-data": "^4.0.4",
"isstream": "0.1.2",
"jsonwebtoken": "^9.0.3",
"load-esm": "^1.0.3",
"mime-types": "2.1.35",
"retry-axios": "^2.6.0",
"tough-cookie": "^4.1.3"
@@ -7008,9 +7019,9 @@
}
},
"node_modules/ip-address": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
"integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
"integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
"license": "MIT",
"engines": {
"node": ">= 12"
@@ -7854,6 +7865,25 @@
"node": ">= 0.8.0"
}
},
"node_modules/load-esm": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz",
"integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/Borewit"
},
{
"type": "buymeacoffee",
"url": "https://buymeacoffee.com/borewit"
}
],
"license": "MIT",
"engines": {
"node": ">=13.2.0"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -8941,6 +8971,21 @@
"node": ">=8"
}
},
"node_modules/path-expression-matcher": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz",
"integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -8989,24 +9034,11 @@
"license": "ISC"
},
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
"integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
"license": "MIT"
},
"node_modules/peek-readable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -9333,22 +9365,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/readable-web-to-node-stream": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz",
"integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==",
"license": "MIT",
"dependencies": {
"readable-stream": "^4.7.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/real-require": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
@@ -9583,9 +9599,9 @@
}
},
"node_modules/router/node_modules/path-to-regexp": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz",
"integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==",
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -10375,9 +10391,9 @@
}
},
"node_modules/strnum": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz",
"integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz",
"integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==",
"funding": [
{
"type": "github",
@@ -10387,16 +10403,15 @@
"license": "MIT"
},
"node_modules/strtok3": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"version": "10.3.5",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz",
"integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==",
"license": "MIT",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^4.1.0"
"@tokenizer/token": "^0.3.0"
},
"engines": {
"node": ">=10"
"node": ">=18"
},
"funding": {
"type": "github",
@@ -10506,13 +10521,13 @@
}
},
"node_modules/teeny-request": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.0.tgz",
"integrity": "sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==",
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.2.tgz",
"integrity": "sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==",
"license": "Apache-2.0",
"dependencies": {
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.1",
"node-fetch": "^3.3.2",
"stream-events": "^1.0.5"
},
@@ -10520,31 +10535,6 @@
"node": ">=18"
}
},
"node_modules/teeny-request/node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"license": "MIT",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/teeny-request/node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"license": "MIT",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/teeny-request/node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
@@ -10656,16 +10646,17 @@
}
},
"node_modules/token-types": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz",
"integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
"license": "MIT",
"dependencies": {
"@borewit/text-codec": "^0.2.1",
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
},
"engines": {
"node": ">=10"
"node": ">=14.16"
},
"funding": {
"type": "github",
@@ -10840,6 +10831,18 @@
"is-typedarray": "^1.0.0"
}
},
"node_modules/uint8array-extras": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
"integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "jambonz-feature-server",
"version": "0.9.5",
"version": "0.9.6",
"main": "app.js",
"engines": {
"node": ">= 20.x"
@@ -33,7 +33,7 @@
"@jambonz/realtimedb-helpers": "^0.8.15",
"@jambonz/speech-utils": "^0.2.30",
"@jambonz/stats-collector": "^0.1.10",
"@jambonz/time-series": "^0.2.15",
"@jambonz/time-series": "^0.2.17",
"@jambonz/verb-specifications": "^0.0.125",
"@modelcontextprotocol/sdk": "^1.9.0",
"@opentelemetry/api": "^1.8.0",