From 4c6ad12a7f832e391cde49a3481c223e35e20201 Mon Sep 17 00:00:00 2001 From: Sam Machin Date: Mon, 30 Mar 2026 15:25:45 +0100 Subject: [PATCH] fix query sp alerts & bump time-series (#547) * fix query sp alerts & bump time-series * add package-lock.json back * fix: use shared parseAccountSid/parseServiceProviderSid from utils in alerts and recent-calls routes * fix/update tests * fix tests --------- Co-authored-by: Dave Horton --- .github/workflows/ci.yml | 5 - lib/routes/api/alerts.js | 11 +- lib/routes/api/recent-calls.js | 14 +- package-lock.json | 513 ++++++++++++++++++++----------- package.json | 4 +- test/create-test-db.js | 10 +- test/docker-compose-testbed.yaml | 6 +- test/docker_start.js | 22 +- test/docker_stop.js | 2 +- test/remove-test-db.js | 3 +- test/serve-integration.js | 10 +- test/speech-credentials.js | 90 +----- test/users-view-only.js | 2 +- test/users.js | 2 +- test/webapp_tests.js | 6 +- 15 files changed, 373 insertions(+), 327 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35762f6..43dedda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,11 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Install Docker Compose - run: | - sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - docker-compose --version - uses: actions/setup-node@v4 with: node-version: lts/* diff --git a/lib/routes/api/alerts.js b/lib/routes/api/alerts.js index 3d44092..f8bb42d 100644 --- a/lib/routes/api/alerts.js +++ b/lib/routes/api/alerts.js @@ -1,19 +1,14 @@ const router = require('express').Router(); const sysError = require('../error'); const {DbErrorBadRequest} = require('../../utils/errors'); -const { parseServiceProviderSid } = require('./utils'); - -const parseAccountSid = (url) => { - const arr = /Accounts\/([^\/]*)/.exec(url); - if (arr) return arr[1]; -}; +const { parseServiceProviderSid, parseAccountSid } = require('./utils'); router.get('/', async(req, res) => { const {logger, queryAlerts, queryAlertsSP} = req.app.locals; try { logger.debug({opts: req.query}, 'GET /Alerts'); - const account_sid = parseAccountSid(req.originalUrl); - const service_provider_sid = account_sid ? null : parseServiceProviderSid(req.originalUrl); + const account_sid = parseAccountSid(req); + const service_provider_sid = account_sid ? null : parseServiceProviderSid(req); const {page, count, alert_type, days, start, end} = req.query || {}; if (!page || page < 1) throw new DbErrorBadRequest('missing or invalid "page" query arg'); if (!count || count > 500) throw new DbErrorBadRequest('missing or invalid "count" query arg'); diff --git a/lib/routes/api/recent-calls.js b/lib/routes/api/recent-calls.js index 97e8133..15a60a0 100644 --- a/lib/routes/api/recent-calls.js +++ b/lib/routes/api/recent-calls.js @@ -14,22 +14,14 @@ const { deleteAzureStorageObject } = require('../../utils/storage-utils'); -const parseAccountSid = (url) => { - const arr = /Accounts\/([^\/]*)/.exec(url); - if (arr) return arr[1]; -}; - -const parseServiceProviderSid = (url) => { - const arr = /ServiceProviders\/([^\/]*)/.exec(url); - if (arr) return arr[1]; -}; +const { parseServiceProviderSid, parseAccountSid } = require('./utils'); router.get('/', async(req, res) => { const {logger, queryCdrs, queryCdrsSP} = req.app.locals; try { logger.debug({opts: req.query}, 'GET /RecentCalls'); - const account_sid = parseAccountSid(req.originalUrl); - const service_provider_sid = account_sid ? null : parseServiceProviderSid(req.originalUrl); + const account_sid = parseAccountSid(req); + const service_provider_sid = account_sid ? null : parseServiceProviderSid(req); const {page, count, trunk, direction, days, answered, start, end, filter} = req.query || {}; if (!page || page < 1) throw new DbErrorBadRequest('missing or invalid "page" query arg'); if (!count || count > 500) throw new DbErrorBadRequest('missing or invalid "count" query arg'); diff --git a/package-lock.json b/package-lock.json index d46dc9a..8fd9089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jambonz-api-server", - "version": "0.9.5", + "version": "0.9.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jambonz-api-server", - "version": "0.9.5", + "version": "0.9.6", "license": "MIT", "dependencies": { "@aws-sdk/client-cloudwatch-logs": "^3.750.0", @@ -22,7 +22,7 @@ "@jambonz/mw-registrar": "^0.2.7", "@jambonz/realtimedb-helpers": "^0.8.15", "@jambonz/speech-utils": "^0.2.30", - "@jambonz/time-series": "^0.2.8", + "@jambonz/time-series": "^0.2.17", "@jambonz/verb-specifications": "^0.0.123", "@soniox/soniox-node": "^1.2.2", "ajv": "^8.17.1", @@ -1414,13 +1414,13 @@ } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.4.tgz", - "integrity": "sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q==", + "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.12.0", - "fast-xml-parser": "5.3.4", + "@smithy/types": "^4.13.1", + "fast-xml-parser": "5.5.8", "tslib": "^2.6.2" }, "engines": { @@ -1924,6 +1924,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", @@ -2053,9 +2063,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -2108,17 +2118,18 @@ } }, "node_modules/@google-cloud/common": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.1.tgz", - "integrity": "sha512-7NBC5vD0au75nkctVs2vEGpdUPFs1BaHTMpeI+RVEgQSMe5/wEU6dx9p0fmZA0bj4HgdpobMKeegOcLUiEoxng==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz", + "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==", + "license": "Apache-2.0", "dependencies": { "@google-cloud/projectify": "^4.0.0", "@google-cloud/promisify": "^4.0.0", "arrify": "^2.0.1", "duplexify": "^4.1.1", - "ent": "^2.2.0", "extend": "^3.0.2", "google-auth-library": "^9.0.0", + "html-entities": "^2.5.2", "retry-request": "^7.0.0", "teeny-request": "^9.0.0" }, @@ -2155,9 +2166,10 @@ } }, "node_modules/@google-cloud/speech": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/speech/-/speech-6.5.0.tgz", - "integrity": "sha512-KwT/Ioejgeu9LE2TZswYDG3Ip2MXh4NsmhkpBhuhJwP1f8vBLzWDibgPWf1v0V+Rwp5Mj2T4B7HxaJ0nTY5SNA==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/@google-cloud/speech/-/speech-6.7.1.tgz", + "integrity": "sha512-KgI2xmO8jHStYyoblj5FQ1G1Lk9JuvsR3wUpNSjxJP89yKA+Y/TBgGFvvu+mwm/f5x2ldLLY4So1VGNXZ+yzKg==", + "license": "Apache-2.0", "dependencies": { "@google-cloud/common": "^5.0.0", "@types/pumpify": "^1.4.1", @@ -2171,23 +2183,22 @@ } }, "node_modules/@google-cloud/storage": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.9.0.tgz", - "integrity": "sha512-PlFl7g3r91NmXtZHXsSEfTZES5ysD3SSBWmX4iBdQ2TFH7tN/Vn/IhnVELCHtgh1vc+uYPZ7XvRYaqtDCdghIA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz", + "integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==", + "license": "Apache-2.0", "dependencies": { "@google-cloud/paginator": "^5.0.0", "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "^4.0.0", + "@google-cloud/promisify": "<4.1.0", "abort-controller": "^3.0.0", "async-retry": "^1.3.3", - "compressible": "^2.0.12", "duplexify": "^4.1.3", - "ent": "^2.2.0", - "fast-xml-parser": "^4.3.0", + "fast-xml-parser": "^5.3.4", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", "mime": "^3.0.0", - "mime-types": "^2.0.8", "p-limit": "^3.0.1", "retry-request": "^7.0.0", "teeny-request": "^9.0.0", @@ -2197,27 +2208,6 @@ "node": ">=14" } }, - "node_modules/@google-cloud/storage/node_modules/fast-xml-parser": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", - "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/@google-cloud/storage/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -2269,10 +2259,19 @@ "node": ">=6" } }, + "node_modules/@google-cloud/text-to-speech/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/@google-cloud/text-to-speech/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" @@ -2396,13 +2395,26 @@ "node": ">=18" } }, + "node_modules/@google-cloud/text-to-speech/node_modules/http-proxy-agent": { + "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": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@google-cloud/text-to-speech/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -2506,13 +2518,13 @@ } }, "node_modules/@google-cloud/text-to-speech/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" }, @@ -2520,19 +2532,6 @@ "node": ">=18" } }, - "node_modules/@google-cloud/text-to-speech/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/@grpc/grpc-js": { "version": "1.10.11", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.11.tgz", @@ -2888,6 +2887,24 @@ "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "license": "MIT" }, + "node_modules/@jambonz/speech-utils/node_modules/file-type": { + "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": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/@jambonz/speech-utils/node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -2927,29 +2944,30 @@ } }, "node_modules/@jambonz/speech-utils/node_modules/ibm-cloud-sdk-core": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.3.tgz", - "integrity": "sha512-D0lvClcoCp/HXyaFlCbOT4aTYgGyeIb4ncxZpxRuiuw7Eo79C6c49W53+8WJRD9nxzT5vrIdaky3NBcTdBtaEg==", + "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.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" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/@jambonz/speech-utils/node_modules/ibm-cloud-sdk-core/node_modules/@types/node": { @@ -2997,6 +3015,40 @@ "ws": "^7.5.6" } }, + "node_modules/@jambonz/speech-utils/node_modules/strtok3": { + "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" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jambonz/speech-utils/node_modules/token-types": { + "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": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/@jambonz/speech-utils/node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", @@ -3019,9 +3071,10 @@ } }, "node_modules/@jambonz/time-series": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.8.tgz", - "integrity": "sha512-iFSKPAEElb3NXVAKYlr+2Q08zNhv8SlsS4I1Bwg4gFIj4Tku0vHzoXk6WTCzMRY1hE4YbBPbImNYLW9BfzMJjw==", + "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", "influx": "^5.9.3" @@ -3884,9 +3937,10 @@ } }, "node_modules/@smithy/types": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", - "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", + "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" }, @@ -4192,6 +4246,41 @@ "@grpc/proto-loader": "^0.7.2" } }, + "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/inflate/node_modules/token-types": { + "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": ">=14.16" + }, + "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", @@ -4462,9 +4551,9 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -4687,20 +4776,20 @@ } }, "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" } }, "node_modules/axios/node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -4829,9 +4918,10 @@ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" }, "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==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5175,17 +5265,6 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5700,11 +5779,6 @@ "once": "^1.4.0" } }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" - }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -6025,9 +6099,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -6359,10 +6433,10 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fast-xml-parser": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz", - "integrity": "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==", + "node_modules/fast-xml-builder": { + "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", @@ -6371,23 +6445,28 @@ ], "license": "MIT", "dependencies": { - "strnum": "^2.1.0" - }, - "bin": { - "fxparser": "src/cli/cli.js" + "path-expression-matcher": "^1.1.3" } }, - "node_modules/fast-xml-parser/node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "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" + "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" + } }, "node_modules/fastq": { "version": "1.17.1", @@ -6547,21 +6626,23 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -7263,6 +7344,22 @@ } } }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -7385,9 +7482,10 @@ "integrity": "sha512-9taxKC944BqoTVjE+UT3pQH0nHZlTvITwfsOZqyc+R3sfJuxaTtxWjfn1K2UlxyPcKHf0rnaXcVFrS9F9vf0bw==" }, "node_modules/ibm-watson": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ibm-watson/-/ibm-watson-9.0.1.tgz", - "integrity": "sha512-Z8BP+AnWA0KAzD+5/sVZrLXTrstNbKMNWEgKfOC+gGaVAO0y8iOtrmk2fXOOQ+1anvABgsT1FMbJZQ3gQUoWPg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/ibm-watson/-/ibm-watson-9.1.0.tgz", + "integrity": "sha512-17XYV/zsoZv1lp5C1MOjeyh1OJ1i4mzVuDbyU5Vi4196QA+sbbD2FdI02qoqQy4fr8LdeI//ijdn/WQ6CcMVAQ==", + "license": "Apache-2.0", "dependencies": { "@types/async": "^3.2.5", "@types/extend": "^3.0.1", @@ -8203,11 +8301,12 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", "dependencies": { - "jws": "^3.2.2", + "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -8223,25 +8322,6 @@ "npm": ">=6" } }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", - "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", - "dependencies": { - "jwa": "^1.4.2", - "safe-buffer": "^5.0.1" - } - }, "node_modules/jsprim": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", @@ -8297,6 +8377,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": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -8567,9 +8666,10 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9291,6 +9391,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", @@ -9336,9 +9451,9 @@ "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/pause": { @@ -9364,9 +9479,10 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -9607,9 +9723,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/psl": { "version": "1.9.0", @@ -9644,9 +9764,10 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" }, @@ -10641,9 +10762,16 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", + "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" }, "node_modules/strtok3": { "version": "6.3.0", @@ -11008,6 +11136,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.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11024,9 +11164,10 @@ } }, "node_modules/undici": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", - "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", + "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", + "license": "MIT", "engines": { "node": ">=20.18.1" } diff --git a/package.json b/package.json index f8fac84..3bf9015 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jambonz-api-server", - "version": "0.9.5", + "version": "0.9.6", "description": "", "main": "app.js", "scripts": { @@ -33,7 +33,7 @@ "@jambonz/mw-registrar": "^0.2.7", "@jambonz/realtimedb-helpers": "^0.8.15", "@jambonz/speech-utils": "^0.2.30", - "@jambonz/time-series": "^0.2.8", + "@jambonz/time-series": "^0.2.17", "@jambonz/verb-specifications": "^0.0.123", "@soniox/soniox-node": "^1.2.2", "ajv": "^8.17.1", diff --git a/test/create-test-db.js b/test/create-test-db.js index d998e92..171790c 100644 --- a/test/create-test-db.js +++ b/test/create-test-db.js @@ -2,7 +2,7 @@ const test = require('tape') ; const exec = require('child_process').exec ; test('creating jambones_test database', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 < ${__dirname}/../db/create_test_db.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root < ${__dirname}/../db/create_test_db.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('database successfully created'); t.end(); @@ -10,7 +10,7 @@ test('creating jambones_test database', (t) => { }); test('creating schema', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('schema successfully created'); t.end(); @@ -18,7 +18,7 @@ test('creating schema', (t) => { }); test('creating auth token', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/create-admin-token.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/create-admin-token.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('auth token successfully created'); t.end(); @@ -26,7 +26,7 @@ test('creating auth token', (t) => { }); test('add predefined carriers', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/add-predefined-carriers.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/add-predefined-carriers.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('predefined carriers added'); t.end(); @@ -34,7 +34,7 @@ test('add predefined carriers', (t) => { }); test('prepare permissions', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('permissions prepared'); t.end(); diff --git a/test/docker-compose-testbed.yaml b/test/docker-compose-testbed.yaml index 8f9a381..6d0f001 100644 --- a/test/docker-compose-testbed.yaml +++ b/test/docker-compose-testbed.yaml @@ -1,5 +1,3 @@ -version: '3' - networks: jambonz-api: driver: bridge @@ -10,11 +8,11 @@ networks: services: mysql: - # platform: linux/x86_64 + container_name: mysql-jambonz-test image: mysql:5.7 ports: - "3360:3306" - environment: + environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "127.0.0.1", "--protocol", "tcp"] diff --git a/test/docker_start.js b/test/docker_start.js index 48c584b..edf4510 100644 --- a/test/docker_start.js +++ b/test/docker_start.js @@ -1,11 +1,25 @@ const test = require('tape'); const exec = require('child_process').exec ; +const waitForMySQL = (attempts = 0, maxAttempts = 30) => { + return new Promise((resolve, reject) => { + const check = () => { + exec('docker exec mysql-jambonz-test mysqladmin ping -u root --silent', (err) => { + if (!err) return resolve(); + if (++attempts >= maxAttempts) return reject(new Error('MySQL did not become ready in time')); + setTimeout(check, 2000); + }); + }; + check(); + }); +}; + test('starting docker network..', (t) => { t.plan(1); - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { - setTimeout(() => { - t.pass('docker started'); - }, 15000); + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err, stdout, stderr) => { + if (err) return t.fail(err.message); + waitForMySQL() + .then(() => t.pass('docker started')) + .catch((err) => t.fail(err.message)); }); }); diff --git a/test/docker_stop.js b/test/docker_stop.js index 11db6ec..8fe3d4c 100644 --- a/test/docker_stop.js +++ b/test/docker_stop.js @@ -3,7 +3,7 @@ const exec = require('child_process').exec ; test('stopping docker network..', (t) => { t.timeoutAfter(10000); - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err, stdout, stderr) => { //console.log(`stderr: ${stderr}`); process.exit(0); }); diff --git a/test/remove-test-db.js b/test/remove-test-db.js index 2642e0b..ca3314d 100644 --- a/test/remove-test-db.js +++ b/test/remove-test-db.js @@ -1,9 +1,8 @@ const test = require('tape').test ; const exec = require('child_process').exec ; -const pwd = process.env.CI ? '' : '-p$MYSQL_ROOT_PASSWORD'; test('dropping jambones_test database', (t) => { - exec(`mysql -h 127.0.0.1 -u root ${pwd} --protocol=tcp < ${__dirname}/../db/remove_test_db.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root < ${__dirname}/../db/remove_test_db.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('database successfully dropped'); t.end(); diff --git a/test/serve-integration.js b/test/serve-integration.js index f3d828d..2c8f92d 100644 --- a/test/serve-integration.js +++ b/test/serve-integration.js @@ -13,7 +13,7 @@ process.on('SIGINT', async() => { const startDocker = () => { return new Promise((resolve, reject) => { console.log('starting dockerized mysql and redis..') - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err) => { + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml up -d`, (err) => { if (err) return reject(err); setTimeout(() => { console.log('mysql is running'); @@ -26,7 +26,7 @@ const startDocker = () => { const createDb = () => { return new Promise((resolve, reject) => { console.log('creating database..') - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 < ${__dirname}/../db/create_test_db.sql`, (err) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root < ${__dirname}/../db/create_test_db.sql`, (err) => { if (err) return reject(err); resolve(); }); @@ -36,7 +36,7 @@ const createDb = () => { const createSchema = () => { return new Promise((resolve, reject) => { console.log('creating schema..') - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { if (err) return reject(err); resolve(); }); @@ -46,7 +46,7 @@ const createSchema = () => { const seedDb = () => { return new Promise((resolve, reject) => { console.log('seeding database..') - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/seed-integration-test.sql`, (err) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/seed-integration-test.sql`, (err) => { if (err) return reject(err); resolve(); }); @@ -78,7 +78,7 @@ const generateSipTrace = async() => { const stopDocker = () => { return new Promise((resolve, reject) => { console.log('stopping docker network..') - exec(`docker-compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err) => { + exec(`docker compose -f ${__dirname}/docker-compose-testbed.yaml down`, (err) => { if (err) return reject(err); resolve(); }); diff --git a/test/speech-credentials.js b/test/speech-credentials.js index 7b80bb5..cbf1c53 100644 --- a/test/speech-credentials.js +++ b/test/speech-credentials.js @@ -422,85 +422,7 @@ test('speech credentials tests', async(t) => { }); t.ok(result.statusCode === 204, 'successfully deleted speech credential for deepgram onprem'); - /* add a credential for ibm tts */ - if (process.env.IBM_TTS_API_KEY && process.env.IBM_TTS_REGION) { - result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, { - resolveWithFullResponse: true, - auth: authUser, - json: true, - body: { - vendor: 'ibm', - use_for_tts: true, - tts_api_key: process.env.IBM_TTS_API_KEY, - tts_region: process.env.IBM_TTS_REGION - } - }); - t.ok(result.statusCode === 201, 'successfully added speech credential for ibm'); - const ms_sid = result.body.sid; - /* test the speech credential */ - result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}/test`, { - resolveWithFullResponse: true, - auth: authUser, - json: true, - }); - //console.log(JSON.stringify(result)); - t.ok(result.statusCode === 200 && result.body.tts.status === 'ok', 'successfully tested speech credential for ibm tts'); - - /* delete the credential */ - result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}`, { - auth: authUser, - resolveWithFullResponse: true, - }); - t.ok(result.statusCode === 204, 'successfully deleted speech credential'); - } - - /* add a credential for ibm stt */ - if (process.env.IBM_STT_API_KEY && process.env.IBM_STT_REGION) { - result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, { - resolveWithFullResponse: true, - auth: authUser, - json: true, - body: { - vendor: 'ibm', - use_for_stt: true, - stt_api_key: process.env.IBM_STT_API_KEY, - stt_region: process.env.IBM_STT_REGION - } - }); - t.ok(result.statusCode === 201, 'successfully added speech credential for ibm'); - const ms_sid = result.body.sid; - - /* test the speech credential */ - result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}/test`, { - resolveWithFullResponse: true, - auth: authUser, - json: true, - }); - //console.log(JSON.stringify(result)); - t.ok(result.statusCode === 200 && result.body.stt.status === 'ok', 'successfully tested speech credential for ibm stt'); - - result = await request.post(`/Accounts/${account_sid}/TtsCache/Synthesize`, { - resolveWithFullResponse: true, - auth: authUser, - json: true, - body: { - speech_credential_sid: ms_sid, - text: "Hello How are you", - language: "en-US", - voice: "en-US_MichaelExpressive" - } - }); - - t.ok(result.statusCode === 200, 'successfully IBM tested synthesize'); - - /* delete the credential */ - result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${ms_sid}`, { - auth: authUser, - resolveWithFullResponse: true, - }); - t.ok(result.statusCode === 204, 'successfully deleted speech credential'); - } /* add a credential for Siniox */ if (process.env.SONIOX_API_KEY) { @@ -1051,17 +973,7 @@ test('speech credentials tests', async(t) => { t.ok(result.body.stt.length !== 0, 'successfully get deepgram supported languages and voices'); t.ok(result.body.models.length !== 0, 'successfully get deepgram supported languages and voices'); - /* Check ibm supportedLanguagesAndVoices */ - result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/speech/supportedLanguagesAndVoices?vendor=ibm`, { - resolveWithFullResponse: true, - simple: false, - auth: authAdmin, - json: true, - }); - t.ok(result.body.tts.length !== 0, 'successfully get ibm supported languages and voices'); - t.ok(result.body.stt.length !== 0, 'successfully get ibm supported languages and voices'); - - /* Check ibm supportedLanguagesAndVoices */ + /* Check nvidia supportedLanguagesAndVoices */ result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/speech/supportedLanguagesAndVoices?vendor=nvidia`, { resolveWithFullResponse: true, simple: false, diff --git a/test/users-view-only.js b/test/users-view-only.js index 157dbc9..f18ae75 100644 --- a/test/users-view-only.js +++ b/test/users-view-only.js @@ -22,7 +22,7 @@ test('add an admin user', (t) => { test('prepare permissions', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('permissions prepared'); t.end(); diff --git a/test/users.js b/test/users.js index 26eff2d..cc1f2c5 100644 --- a/test/users.js +++ b/test/users.js @@ -22,7 +22,7 @@ test('add an admin user', (t) => { }); }); test('prepare permissions', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('permissions prepared'); t.end(); diff --git a/test/webapp_tests.js b/test/webapp_tests.js index e9ed319..3980526 100644 --- a/test/webapp_tests.js +++ b/test/webapp_tests.js @@ -11,7 +11,7 @@ const {createApiKey} = require('./utils'); const sleepFor = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); test('re-creating schema', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/jambones-sql.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('schema successfully created'); t.end(); @@ -19,14 +19,14 @@ test('re-creating schema', (t) => { }); test('seeding database for webapp tests', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/webapp-tests.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/webapp-tests.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('successfully re-seeded database'); t.end(); }); }); test('prepare permissions', (t) => { - exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { + exec(`docker exec -i mysql-jambonz-test mysql -u root -D jambones_test < ${__dirname}/../db/prepare-permissions-test.sql`, (err, stdout, stderr) => { if (err) return t.end(err); t.pass('permissions prepared'); t.end();