From 0ea7082da25215912cb8ec2740e9b91010454650 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Sun, 11 Jan 2026 07:30:18 +0700 Subject: [PATCH 01/15] support gemini tts --- lib/synth-audio.js | 122 ++-- package-lock.json | 1376 ++++++++++++++++++++++++++++++++++---------- package.json | 2 +- 3 files changed, 1137 insertions(+), 363 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 243d10d..a67c479 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -204,7 +204,9 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc const startAt = process.hrtime(); switch (vendor) { case 'google': - audioData = await synthGoogle(logger, {credentials, stats, language, voice, gender, key, text}); + audioData = await synthGoogle(logger, { + credentials, stats, language, voice, gender, key, text, model, options, instructions + }); break; case 'aws': case 'polly': @@ -409,72 +411,86 @@ const synthPolly = async(createHash, retrieveHash, logger, } }; -const synthGoogle = async(logger, {credentials, stats, language, voice, gender, text}) => { + +const synthGoogle = async(logger, { + credentials, stats, language, voice, gender, text, model, options, instructions +}) => { const client = new ttsGoogle.TextToSpeechClient(credentials); - // If google custom voice cloning is used. - // At this time 31 Oct 2024, google node sdk has not support voice cloning yet. - if (typeof voice === 'object' && voice.voice_cloning_key) { - try { - const accessToken = await client.auth.getAccessToken(); - const projectId = await client.getProjectId(); - const post = bent('https://texttospeech.googleapis.com', 'POST', 'json', { - 'Authorization': `Bearer ${accessToken}`, - 'x-goog-user-project': projectId, - 'Content-Type': 'application/json; charset=utf-8' - }); + const isGemini = credentials.use_gemini_tts; + const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; - const payload = { - input: { - text - }, - voice: { - language_code: language, - voice_clone: { - voice_cloning_key: voice.voice_cloning_key - } - }, - audioConfig: { - // Cloning voice at this time still in v1 beta version, and it support LINEAR16 in Wav format, 24.000Hz - audioEncoding: 'LINEAR16', - sample_rate_hertz: 24000 - } - }; - - const wav = await post('/v1beta1/text:synthesize', payload); - return { - audioContent: Buffer.from(wav.audioContent, 'base64'), - extension: 'wav', - sampleRate: 24000 - }; - } catch (err) { - logger.info({err: await err.text()}, 'synthGoogle returned error'); - throw err; + // Build input based on voice type + let input; + if (isGemini) { + // Gemini TTS does not support SSML - strip tags if present + let inputText = text; + if (text.startsWith('')) { + inputText = text.replace(/<[^>]*>/g, '').trim(); + logger.info('synthGoogle: Gemini TTS does not support SSML, stripped tags from input'); } + // Use instructions as prompt for Gemini TTS style control, options.prompt can override + const prompt = options?.prompt || instructions; + input = { + text: inputText, + ...(prompt && { prompt }) + }; + } else { + input = text.startsWith('') ? { ssml: text } : { text }; } - const opts = { - voice: { - ...(typeof voice === 'string' && {name: voice}), - ...(typeof voice === 'object' && {customVoice: voice}), + // Build voice selection params based on voice type + let voiceParams; + if (isGemini) { + voiceParams = { + languageCode: language || 'en-US', + name: voice, + modelName: model + }; + } else if (isVoiceCloning) { + voiceParams = { + languageCode: language, + voiceClone: { + voiceCloningKey: voice.voice_cloning_key + } + }; + } else { + voiceParams = { + ...(typeof voice === 'string' && { name: voice }), + ...(typeof voice === 'object' && { customVoice: voice }), languageCode: language, ssmlGender: gender || 'SSML_VOICE_GENDER_UNSPECIFIED' - }, - audioConfig: {audioEncoding: 'MP3'} - }; - Object.assign(opts, {input: text.startsWith('') ? {ssml: text} : {text}}); + }; + } + + // Build audio config based on voice type + let audioConfig; + let extension; + let sampleRate; + if (isGemini || isVoiceCloning) { + audioConfig = { audioEncoding: 'LINEAR16', sampleRateHertz: 24000 }; + extension = 'r24'; + sampleRate = 24000; + } else { + audioConfig = { audioEncoding: 'MP3' }; + extension = 'mp3'; + sampleRate = 8000; + } + + const opts = { input, voice: voiceParams, audioConfig }; + try { - const responses = await client.synthesizeSpeech(opts); + logger.debug({ opts }, 'synthGoogle: request'); + const [response] = await client.synthesizeSpeech(opts); stats.increment('tts.count', ['vendor:google', 'accepted:yes']); client.close(); return { - audioContent: responses[0].audioContent, - extension: 'mp3', - sampleRate: 8000 + audioContent: response.audioContent, + extension, + sampleRate }; } catch (err) { - console.error(err); - logger.info({err, opts}, 'synthAudio: Error synthesizing speech using google'); + logger.info({ err, opts }, 'synthAudio: Error synthesizing speech using google'); stats.increment('tts.count', ['vendor:google', 'accepted:no']); client && client.close(); throw err; diff --git a/package-lock.json b/package-lock.json index 476e0dd..2a9db05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@aws-sdk/client-polly": "^3.496.0", "@aws-sdk/client-sts": "^3.496.0", "@cartesia/cartesia-js": "^2.2.7", - "@google-cloud/text-to-speech": "^5.5.0", + "@google-cloud/text-to-speech": "^6.4.0", "@grpc/grpc-js": "^1.9.14", "@jambonz/realtimedb-helpers": "^0.8.7", "bent": "^7.3.12", @@ -1167,37 +1167,39 @@ } }, "node_modules/@google-cloud/text-to-speech": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/text-to-speech/-/text-to-speech-5.5.0.tgz", - "integrity": "sha512-Cw/UK2Y3l31Vsuozu8cxsmVS/09fShimes0tRLgDbOY2ZMG1Dckb6Zf/Q3Nxg4X0feFep44pvwNmyHKrOnl9SQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/text-to-speech/-/text-to-speech-6.4.0.tgz", + "integrity": "sha512-KUnK+mBYz9aegxHrBbwEignOkGRqXvqOXs/EGY7CAJhMFKuNSieW02/PV/ipVRsJM11MP69qgTgEetoyAN0HAg==", "license": "Apache-2.0", "dependencies": { - "google-gax": "^4.0.3" + "google-gax": "^5.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, "node_modules/@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "license": "Apache-2.0", "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { - "node": "^8.13.0 || >=10.10.0" + "node": ">=12.10.0" } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.4", + "protobufjs": "^7.5.3", "yargs": "^17.7.2" }, "bin": { @@ -1258,6 +1260,102 @@ "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1432,6 +1530,16 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@ljharb/resumer": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.1.3.tgz", @@ -1492,30 +1600,45 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -1524,27 +1647,32 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" }, "node_modules/@smithy/abort-controller": { "version": "3.1.1", @@ -2119,6 +2247,7 @@ "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" } @@ -2128,11 +2257,6 @@ "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.24.tgz", "integrity": "sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==" }, - "node_modules/@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -2151,11 +2275,6 @@ "resolved": "https://registry.npmjs.org/@types/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-EE11Sn7gzHEF9FGkYHTkFpPuDEamLudLvaGnBciNgH55fTYboWZHINR6MP8+CfCOjPJX08l4teRrjCY11gz1CA==" }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -2191,17 +2310,6 @@ "node": ">= 6" } }, - "node_modules/@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -2466,8 +2574,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -2499,9 +2606,10 @@ } }, "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", "engines": { "node": "*" } @@ -2736,6 +2844,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2814,7 +2923,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2834,6 +2942,15 @@ "type": "^1.0.1" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3008,16 +3125,23 @@ } }, "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -3050,9 +3174,10 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -3558,6 +3683,29 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3679,19 +3827,6 @@ "node": ">=8.0.0" } }, - "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, "node_modules/form-data-encoder": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", @@ -3722,6 +3857,18 @@ "node": ">= 14" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -3784,29 +3931,137 @@ } }, "node_modules/gaxios": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", - "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9" + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/gaxios/node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gaxios/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gaxios/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/gaxios/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gaxios/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/gensync": { @@ -3946,38 +4201,155 @@ } }, "node_modules/google-auth-library": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.2.tgz", - "integrity": "sha512-rTLO4gjhqqo3WvYKL5IdtlCvRqeQ4hxUx/p4lObobY2xotFW3bCQC+Qf1N51CYOfiqfMecdMwW9RIo7dFWYjqw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", "jws": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/google-gax": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.1.0.tgz", - "integrity": "sha512-VP5MYsIXEoXmdeHZl1Qsjv89PvE+LT8fw/2jxpFQtFed22YYAHgiTUuMfj2RWlGJUmRaYEMxBRBDWj+q/hOGQg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-5.0.6.tgz", + "integrity": "sha512-1kGbqVQBZPAAu4+/R1XxPQKP0ydbNYoLAr4l0ZO2bMV0kLyLW4I1gAk++qBLWt7DPORTzmWRMsCZe86gDjShJA==", + "license": "Apache-2.0", "dependencies": { - "@grpc/grpc-js": "~1.9.6", - "@grpc/proto-loader": "^0.7.0", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.0.0", - "node-fetch": "^2.6.1", + "@grpc/grpc-js": "^1.12.6", + "@grpc/proto-loader": "^0.8.0", + "duplexify": "^4.1.3", + "google-auth-library": "^10.1.0", + "google-logging-utils": "^1.1.1", + "node-fetch": "^3.3.2", "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.0", - "protobufjs": "7.2.5", - "retry-request": "^7.0.0" + "proto3-json-serializer": "^3.0.0", + "protobufjs": "^7.5.3", + "retry-request": "^8.0.0", + "rimraf": "^5.0.1" }, + "engines": { + "node": ">=18" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/google-gax/node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-gax/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-gax/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-gax/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/google-gax/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-gax/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", "engines": { "node": ">=14" } @@ -4005,15 +4377,16 @@ "dev": true }, "node_modules/gtoken": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", - "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", + "license": "MIT", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", "jws": "^4.0.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, "node_modules/has-bigints": { @@ -4145,6 +4518,7 @@ "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==", + "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -4155,11 +4529,12 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -4167,12 +4542,10 @@ } }, "node_modules/https-proxy-agent/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dependencies": { - "debug": "^4.3.4" - }, + "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" } @@ -4716,8 +5089,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isstream": { "version": "0.1.2", @@ -4842,6 +5214,21 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4877,6 +5264,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -4952,21 +5340,23 @@ } }, "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", "dependencies": { - "jwa": "^2.0.0", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, @@ -5010,7 +5400,8 @@ "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" }, "node_modules/lodash.defaults": { "version": "4.2.0", @@ -5070,9 +5461,10 @@ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -5224,6 +5616,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mock-property": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/mock-property/-/mock-property-1.0.3.tgz", @@ -5506,6 +5907,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", "engines": { "node": ">= 6" } @@ -5703,6 +6105,12 @@ "node": ">=8" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5737,7 +6145,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -5748,6 +6155,28 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", @@ -5920,21 +6349,23 @@ "dev": true }, "node_modules/proto3-json-serializer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", - "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-3.0.4.tgz", + "integrity": "sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==", + "license": "Apache-2.0", "dependencies": { - "protobufjs": "^7.2.5" + "protobufjs": "^7.4.0" }, "engines": { - "node": ">=14.0.0" + "node": ">=18" } }, "node_modules/protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -6027,6 +6458,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6180,16 +6612,16 @@ } }, "node_modules/retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-8.0.2.tgz", + "integrity": "sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==", + "license": "MIT", "dependencies": { - "@types/request": "^2.48.8", "extend": "^3.0.2", - "teeny-request": "^9.0.0" + "teeny-request": "^10.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/reusify": { @@ -6355,7 +6787,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6367,7 +6798,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -6521,6 +6951,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", "dependencies": { "stubs": "^3.0.0" } @@ -6528,7 +6959,8 @@ "node_modules/stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", @@ -6551,6 +6983,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", @@ -6607,6 +7054,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -6653,7 +7113,8 @@ "node_modules/stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT" }, "node_modules/supports-color": { "version": "7.2.0", @@ -6716,24 +7177,25 @@ } }, "node_modules/teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.0.tgz", + "integrity": "sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==", + "license": "Apache-2.0", "dependencies": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" + "node-fetch": "^3.3.2", + "stream-events": "^1.0.5" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "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" @@ -6742,16 +7204,22 @@ "node": ">= 6" } }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" + "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", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/test-exclude": { @@ -7019,7 +7487,8 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/uuid": { "version": "8.3.2", @@ -7030,6 +7499,15 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -7077,7 +7555,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -7148,6 +7625,25 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -7202,6 +7698,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -7223,6 +7720,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -7240,6 +7738,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } @@ -8141,30 +8640,30 @@ "dev": true }, "@google-cloud/text-to-speech": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/text-to-speech/-/text-to-speech-5.5.0.tgz", - "integrity": "sha512-Cw/UK2Y3l31Vsuozu8cxsmVS/09fShimes0tRLgDbOY2ZMG1Dckb6Zf/Q3Nxg4X0feFep44pvwNmyHKrOnl9SQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/text-to-speech/-/text-to-speech-6.4.0.tgz", + "integrity": "sha512-KUnK+mBYz9aegxHrBbwEignOkGRqXvqOXs/EGY7CAJhMFKuNSieW02/PV/ipVRsJM11MP69qgTgEetoyAN0HAg==", "requires": { - "google-gax": "^4.0.3" + "google-gax": "^5.0.0" } }, "@grpc/grpc-js": { - "version": "1.9.15", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.15.tgz", - "integrity": "sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", "requires": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" } }, "@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", "requires": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.4", + "protobufjs": "^7.5.3", "yargs": "^17.7.2" } }, @@ -8202,6 +8701,64 @@ "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" + }, + "ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -8339,6 +8896,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==" + }, "@ljharb/resumer": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.1.3.tgz", @@ -8384,6 +8946,12 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -8867,11 +9435,6 @@ "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.24.tgz", "integrity": "sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==" }, - "@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" - }, "@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -8890,11 +9453,6 @@ "resolved": "https://registry.npmjs.org/@types/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-EE11Sn7gzHEF9FGkYHTkFpPuDEamLudLvaGnBciNgH55fTYboWZHINR6MP8+CfCOjPJX08l4teRrjCY11gz1CA==" }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, "@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -8929,17 +9487,6 @@ } } }, - "@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, "@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -9137,8 +9684,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base64-js": { "version": "1.5.1", @@ -9156,9 +9702,9 @@ } }, "bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==" }, "bowser": { "version": "2.11.0", @@ -9362,7 +9908,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -9378,6 +9923,11 @@ "type": "^1.0.1" } }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -9496,16 +10046,21 @@ } }, "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "requires": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -9531,9 +10086,9 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "requires": { "once": "^1.4.0" } @@ -9915,6 +10470,15 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -9995,16 +10559,6 @@ "signal-exit": "^3.0.2" } }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "form-data-encoder": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", @@ -10031,6 +10585,14 @@ } } }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -10067,22 +10629,86 @@ "dev": true }, "gaxios": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", - "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", "requires": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9" + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "requires": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + } + }, + "glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, + "rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "requires": { + "glob": "^10.3.7" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + } } }, "gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", "requires": { - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, @@ -10178,36 +10804,105 @@ } }, "google-auth-library": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.2.tgz", - "integrity": "sha512-rTLO4gjhqqo3WvYKL5IdtlCvRqeQ4hxUx/p4lObobY2xotFW3bCQC+Qf1N51CYOfiqfMecdMwW9RIo7dFWYjqw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", "requires": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "google-gax": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.1.0.tgz", - "integrity": "sha512-VP5MYsIXEoXmdeHZl1Qsjv89PvE+LT8fw/2jxpFQtFed22YYAHgiTUuMfj2RWlGJUmRaYEMxBRBDWj+q/hOGQg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-5.0.6.tgz", + "integrity": "sha512-1kGbqVQBZPAAu4+/R1XxPQKP0ydbNYoLAr4l0ZO2bMV0kLyLW4I1gAk++qBLWt7DPORTzmWRMsCZe86gDjShJA==", "requires": { - "@grpc/grpc-js": "~1.9.6", - "@grpc/proto-loader": "^0.7.0", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.0.0", - "node-fetch": "^2.6.1", + "@grpc/grpc-js": "^1.12.6", + "@grpc/proto-loader": "^0.8.0", + "duplexify": "^4.1.3", + "google-auth-library": "^10.1.0", + "google-logging-utils": "^1.1.1", + "node-fetch": "^3.3.2", "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.0", - "protobufjs": "7.2.5", - "retry-request": "^7.0.0" + "proto3-json-serializer": "^3.0.0", + "protobufjs": "^7.5.3", + "retry-request": "^8.0.0", + "rimraf": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "requires": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + } + }, + "glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, + "rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "requires": { + "glob": "^10.3.7" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + } } }, + "google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==" + }, "google-protobuf": { "version": "3.21.2", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", @@ -10225,11 +10920,11 @@ "dev": true }, "gtoken": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", - "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", "requires": { - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", "jws": "^4.0.0" } }, @@ -10326,21 +11021,18 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "requires": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "dependencies": { "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "requires": { - "debug": "^4.3.4" - } + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==" } } }, @@ -10718,8 +11410,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isstream": { "version": "0.1.2", @@ -10818,6 +11509,15 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10910,21 +11610,21 @@ } }, "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "requires": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "requires": { - "jwa": "^2.0.0", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, @@ -11019,9 +11719,9 @@ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==" }, "lru-cache": { "version": "6.0.0", @@ -11123,6 +11823,11 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" + }, "mock-property": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/mock-property/-/mock-property-1.0.3.tgz", @@ -11464,6 +12169,11 @@ "release-zalgo": "^1.0.0" } }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -11488,8 +12198,7 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -11497,6 +12206,22 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + } + } + }, "peek-readable": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", @@ -11633,17 +12358,17 @@ "dev": true }, "proto3-json-serializer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", - "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-3.0.4.tgz", + "integrity": "sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==", "requires": { - "protobufjs": "^7.2.5" + "protobufjs": "^7.4.0" } }, "protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -11813,13 +12538,12 @@ "requires": {} }, "retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-8.0.2.tgz", + "integrity": "sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==", "requires": { - "@types/request": "^2.48.8", "extend": "^3.0.2", - "teeny-request": "^9.0.0" + "teeny-request": "^10.0.0" } }, "reusify": { @@ -11923,7 +12647,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -11931,8 +12654,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "side-channel": { "version": "1.1.0", @@ -12070,6 +12792,16 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "string.prototype.trim": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", @@ -12111,6 +12843,14 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -12188,15 +12928,14 @@ } }, "teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.0.tgz", + "integrity": "sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==", "requires": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" + "node-fetch": "^3.3.2", + "stream-events": "^1.0.5" }, "dependencies": { "https-proxy-agent": { @@ -12208,10 +12947,15 @@ "debug": "4" } }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } } } }, @@ -12419,6 +13163,11 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -12465,7 +13214,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -12524,6 +13272,16 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 9ed8c4d..46a4746 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@aws-sdk/client-polly": "^3.496.0", "@aws-sdk/client-sts": "^3.496.0", "@cartesia/cartesia-js": "^2.2.7", - "@google-cloud/text-to-speech": "^5.5.0", + "@google-cloud/text-to-speech": "^6.4.0", "@grpc/grpc-js": "^1.9.14", "@jambonz/realtimedb-helpers": "^0.8.7", "bent": "^7.3.12", From 0fbbbb8053c1adbf0f25efc77ca6f06c23ce1aa1 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Mon, 12 Jan 2026 09:21:41 +0700 Subject: [PATCH 02/15] add testcases --- test/synth.js | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/test/synth.js b/test/synth.js index cf09b48..43f9da2 100644 --- a/test/synth.js +++ b/test/synth.js @@ -132,7 +132,7 @@ test('Google speech voice cloning synth tests', async(t) => { !process.env.GCP_CUSTOM_VOICE_JSON_KEY || !process.env.GCP_VOICE_CLONING_FILE && !process.env.GCP_VOICE_CLONING_JSON_KEY) { - t.pass(`skipping google speech synth tests since neither + t.pass(`skipping google speech synth tests since neither GCP_CUSTOM_VOICE_FILE nor GCP_CUSTOM_VOICE_JSON_KEY provided, GCP_VOICE_CLONING_FILE nor GCP_VOICE_CLONING_JSON_KEY is not provided`); return t.end(); @@ -166,6 +166,97 @@ GCP_VOICE_CLONING_FILE nor GCP_VOICE_CLONING_JSON_KEY is not provided`); client.quit(); }); +test('Google Gemini TTS synth tests', async(t) => { + const fn = require('..'); + const {synthAudio, client} = fn(opts, logger); + + if (!process.env.GCP_FILE && !process.env.GCP_JSON_KEY) { + t.pass('skipping Google Gemini TTS synth tests since neither GCP_FILE nor GCP_JSON_KEY provided'); + return t.end(); + } + try { + const str = process.env.GCP_JSON_KEY || fs.readFileSync(process.env.GCP_FILE); + const creds = JSON.parse(str); + const geminiModel = process.env.GCP_GEMINI_TTS_MODEL || 'gemini-2.5-flash-tts'; + + // Test basic Gemini TTS synthesis + let result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + use_gemini_tts: true + }, + language: 'en-US', + voice: 'Kore', + model: geminiModel, + text: 'Hello, this is a test of Google Gemini text to speech.', + }); + t.ok(!result.servedFromCache, `successfully synthesized Google Gemini TTS audio to ${result.filePath}`); + t.ok(result.filePath.endsWith('.r24'), 'Gemini TTS audio file has correct extension'); + + // Test Gemini TTS with instructions (prompt) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + use_gemini_tts: true + }, + language: 'en-US', + voice: 'Charon', + model: geminiModel, + text: 'Welcome to our service. How can I help you today?', + instructions: 'Speak in a warm, friendly and professional tone.', + }); + t.ok(!result.servedFromCache, `successfully synthesized Gemini TTS with instructions to ${result.filePath}`); + + // Test cache retrieval + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + use_gemini_tts: true + }, + language: 'en-US', + voice: 'Kore', + model: geminiModel, + text: 'Hello, this is a test of Google Gemini text to speech.', + }); + t.ok(result.servedFromCache, `successfully retrieved Gemini TTS audio from cache ${result.filePath}`); + + // Test SSML stripping (Gemini doesn't support SSML) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + use_gemini_tts: true + }, + language: 'en-US', + voice: 'Leda', + model: geminiModel, + text: 'This SSML should be stripped for Gemini TTS.', + disableTtsCache: true + }); + t.ok(!result.servedFromCache, `successfully synthesized Gemini TTS with SSML stripped to ${result.filePath}`); + + } catch (err) { + console.error(err); + t.end(err); + } + client.quit(); +}); + test('AWS speech synth tests', async(t) => { const fn = require('..'); const {synthAudio, client} = fn(opts, logger); From 460ca70ea77055b3a8e89055d376f480cea3f947 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Mon, 12 Jan 2026 12:55:43 +0700 Subject: [PATCH 03/15] wip --- lib/synth-audio.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index a67c479..f5e812e 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -469,7 +469,7 @@ const synthGoogle = async(logger, { let sampleRate; if (isGemini || isVoiceCloning) { audioConfig = { audioEncoding: 'LINEAR16', sampleRateHertz: 24000 }; - extension = 'r24'; + extension = 'wav'; sampleRate = 24000; } else { audioConfig = { audioEncoding: 'MP3' }; From ded60cb7aa154765c2a669fd55ceca4e149a2ccc Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Mon, 12 Jan 2026 17:18:11 +0700 Subject: [PATCH 04/15] wip --- lib/synth-audio.js | 2 +- test/synth.js | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index f5e812e..5cf8a19 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -417,7 +417,7 @@ const synthGoogle = async(logger, { }) => { const client = new ttsGoogle.TextToSpeechClient(credentials); - const isGemini = credentials.use_gemini_tts; + const isGemini = !!model; const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; // Build input based on voice type diff --git a/test/synth.js b/test/synth.js index 43f9da2..b62acc4 100644 --- a/test/synth.js +++ b/test/synth.js @@ -179,7 +179,7 @@ test('Google Gemini TTS synth tests', async(t) => { const creds = JSON.parse(str); const geminiModel = process.env.GCP_GEMINI_TTS_MODEL || 'gemini-2.5-flash-tts'; - // Test basic Gemini TTS synthesis + // Test Gemini TTS with model and instructions (both required for Gemini) let result = await synthAudio(stats, { vendor: 'google', credentials: { @@ -187,17 +187,17 @@ test('Google Gemini TTS synth tests', async(t) => { client_email: creds.client_email, private_key: creds.private_key, }, - use_gemini_tts: true }, language: 'en-US', voice: 'Kore', model: geminiModel, text: 'Hello, this is a test of Google Gemini text to speech.', + instructions: 'Speak clearly and naturally.', }); t.ok(!result.servedFromCache, `successfully synthesized Google Gemini TTS audio to ${result.filePath}`); - t.ok(result.filePath.endsWith('.r24'), 'Gemini TTS audio file has correct extension'); + t.ok(result.filePath.endsWith('.wav'), 'Gemini TTS audio file has correct extension'); - // Test Gemini TTS with instructions (prompt) + // Test Gemini TTS with different voice and instructions result = await synthAudio(stats, { vendor: 'google', credentials: { @@ -205,7 +205,6 @@ test('Google Gemini TTS synth tests', async(t) => { client_email: creds.client_email, private_key: creds.private_key, }, - use_gemini_tts: true }, language: 'en-US', voice: 'Charon', @@ -223,12 +222,12 @@ test('Google Gemini TTS synth tests', async(t) => { client_email: creds.client_email, private_key: creds.private_key, }, - use_gemini_tts: true }, language: 'en-US', voice: 'Kore', model: geminiModel, text: 'Hello, this is a test of Google Gemini text to speech.', + instructions: 'Speak clearly and naturally.', }); t.ok(result.servedFromCache, `successfully retrieved Gemini TTS audio from cache ${result.filePath}`); @@ -240,12 +239,12 @@ test('Google Gemini TTS synth tests', async(t) => { client_email: creds.client_email, private_key: creds.private_key, }, - use_gemini_tts: true }, language: 'en-US', voice: 'Leda', model: geminiModel, text: 'This SSML should be stripped for Gemini TTS.', + instructions: 'Speak naturally.', disableTtsCache: true }); t.ok(!result.servedFromCache, `successfully synthesized Gemini TTS with SSML stripped to ${result.filePath}`); From 6b2b35acfb80fd10a59e4d80a41e3fbc51b3ff2a Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Mon, 12 Jan 2026 18:26:47 +0700 Subject: [PATCH 05/15] wip --- lib/synth-audio.js | 2 +- test/synth.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 5cf8a19..17bf6c0 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -467,7 +467,7 @@ const synthGoogle = async(logger, { let audioConfig; let extension; let sampleRate; - if (isGemini || isVoiceCloning) { + if (isVoiceCloning) { audioConfig = { audioEncoding: 'LINEAR16', sampleRateHertz: 24000 }; extension = 'wav'; sampleRate = 24000; diff --git a/test/synth.js b/test/synth.js index b62acc4..250ab09 100644 --- a/test/synth.js +++ b/test/synth.js @@ -195,7 +195,7 @@ test('Google Gemini TTS synth tests', async(t) => { instructions: 'Speak clearly and naturally.', }); t.ok(!result.servedFromCache, `successfully synthesized Google Gemini TTS audio to ${result.filePath}`); - t.ok(result.filePath.endsWith('.wav'), 'Gemini TTS audio file has correct extension'); + t.ok(result.filePath.endsWith('.mp3'), 'Gemini TTS audio file has correct extension'); // Test Gemini TTS with different voice and instructions result = await synthAudio(stats, { From 0e333582542b2cbb9650fbe1ec53ab0e16bfb8b9 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 13:51:32 +0700 Subject: [PATCH 06/15] wip --- lib/synth-audio.js | 46 +++++++++- test/synth.js | 220 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 4 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 17bf6c0..1ae9244 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -205,7 +205,8 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc switch (vendor) { case 'google': audioData = await synthGoogle(logger, { - credentials, stats, language, voice, gender, key, text, model, options, instructions + credentials, stats, language, voice, gender, key, text, model, options, instructions, + renderForCaching, disableTtsStreaming, disableTtsCache }); break; case 'aws': @@ -413,12 +414,49 @@ const synthPolly = async(createHash, retrieveHash, logger, const synthGoogle = async(logger, { - credentials, stats, language, voice, gender, text, model, options, instructions + credentials, stats, language, voice, gender, key, text, model, options, instructions, + renderForCaching, disableTtsStreaming, disableTtsCache }) => { - const client = new ttsGoogle.TextToSpeechClient(credentials); - const isGemini = !!model; const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; + // HD voices have pattern like en-US-Chirp3-HD-Charon + const isHDVoice = typeof voice === 'string' && voice.includes('-HD-'); + // Live API is used for Gemini TTS and HD voices + const useLiveApi = isGemini || isHDVoice; + + // Streaming support for Google TTS (Gemini, HD voices, and standard voices) + // Voice cloning does not support streaming + if (!isVoiceCloning && !JAMBONES_DISABLE_TTS_STREAMING && !renderForCaching && !disableTtsStreaming) { + // Strip SSML tags for Gemini TTS (it doesn't support SSML) + let inputText = text; + if (isGemini && text.startsWith('')) { + inputText = text.replace(/<[^>]*>/g, '').trim(); + logger.info('synthGoogle: Gemini TTS does not support SSML, stripped tags from input'); + } + + let params = '{'; + params += `credentials=${JSON.stringify(credentials)}`; + params += `,playback_id=${key}`; + params += ',vendor=google'; + params += `,voice=${voice}`; + params += `,language_code=${language || 'en-US'}`; + params += `,write_cache_file=${disableTtsCache ? 0 : 1}`; + params += `,use_live_api=${useLiveApi ? 1 : 0}`; + if (model) params += `,model_name=${model}`; + if (gender) params += `,gender=${gender}`; + // comma is used to separate parameters in freeswitch tts module + const prompt = options?.prompt || instructions; + if (prompt) params += `,prompt=${prompt.replace(/\n/g, ' ').replace(/,/g, ';')}`; + params += '}'; + + return { + filePath: `say:${params}${(isGemini ? inputText : text).replace(/\n/g, ' ')}`, + servedFromCache: false, + rtt: 0 + }; + } + + const client = new ttsGoogle.TextToSpeechClient(credentials); // Build input based on voice type let input; diff --git a/test/synth.js b/test/synth.js index 250ab09..9d6fbf9 100644 --- a/test/synth.js +++ b/test/synth.js @@ -256,6 +256,226 @@ test('Google Gemini TTS synth tests', async(t) => { client.quit(); }); +test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => { + // Ensure streaming is enabled (default behavior) + delete process.env.JAMBONES_DISABLE_TTS_STREAMING; + + // Clear require cache to reload config with new env var + delete require.cache[require.resolve('../lib/config')]; + delete require.cache[require.resolve('../lib/synth-audio')]; + delete require.cache[require.resolve('..')]; + + const fn = require('..'); + const {synthAudio, client} = fn(opts, logger); + + if (!process.env.GCP_FILE && !process.env.GCP_JSON_KEY) { + t.pass('skipping Google TTS streaming tests since neither GCP_FILE nor GCP_JSON_KEY provided'); + return t.end(); + } + + try { + const str = process.env.GCP_JSON_KEY || fs.readFileSync(process.env.GCP_FILE); + const creds = JSON.parse(str); + const geminiModel = process.env.GCP_GEMINI_TTS_MODEL || 'gemini-2.5-flash-tts'; + + // Test 1: Standard voice streaming (use_live_api=0) + let result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Wavenet-D', + gender: 'MALE', + text: 'This is a test of standard voice streaming.', + disableTtsCache: true + }); + t.ok(result.filePath.startsWith('say:'), 'Standard voice returns streaming say: path'); + t.ok(result.filePath.includes('vendor=google'), 'Standard voice streaming path contains vendor=google'); + t.ok(result.filePath.includes('use_live_api=0'), 'Standard voice uses use_live_api=0'); + t.ok(result.filePath.includes('voice=en-US-Wavenet-D'), 'Standard voice streaming path contains voice'); + + // Test 2: HD voice streaming (use_live_api=1) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Chirp3-HD-Charon', + text: 'This is a test of HD voice streaming.', + disableTtsCache: true + }); + t.ok(result.filePath.startsWith('say:'), 'HD voice returns streaming say: path'); + t.ok(result.filePath.includes('vendor=google'), 'HD voice streaming path contains vendor=google'); + t.ok(result.filePath.includes('use_live_api=1'), 'HD voice uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes('voice=en-US-Chirp3-HD-Charon'), 'HD voice streaming path contains voice'); + + // Test 3: Gemini TTS streaming (use_live_api=1) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'Kore', + model: geminiModel, + text: 'This is a test of Gemini TTS streaming.', + instructions: 'Speak naturally.', + disableTtsCache: true + }); + t.ok(result.filePath.startsWith('say:'), 'Gemini TTS returns streaming say: path'); + t.ok(result.filePath.includes('vendor=google'), 'Gemini TTS streaming path contains vendor=google'); + t.ok(result.filePath.includes('use_live_api=1'), 'Gemini TTS uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes(`model_name=${geminiModel}`), 'Gemini TTS streaming path contains model_name'); + t.ok(result.filePath.includes('prompt=Speak naturally.'), 'Gemini TTS streaming path contains prompt'); + + // Test 4: Gemini TTS with SSML stripping in streaming mode + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'Leda', + model: geminiModel, + text: 'This SSML should be stripped.', + instructions: 'Speak naturally.', + disableTtsCache: true + }); + t.ok(result.filePath.startsWith('say:'), 'Gemini TTS with SSML returns streaming say: path'); + t.ok(!result.filePath.includes(''), 'SSML tags are stripped from streaming path'); + t.ok(result.filePath.includes('This SSML should be stripped.'), 'Text content is preserved after SSML stripping'); + + // Test 5: Gemini TTS with prompt containing special characters + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'Kore', + model: geminiModel, + text: 'Testing special characters in prompt.', + options: { prompt: 'Speak in a warm, friendly tone' }, + disableTtsCache: true + }); + t.ok(result.filePath.startsWith('say:'), 'Gemini TTS with special chars returns streaming say: path'); + // Commas in prompt should be replaced with semicolons + t.ok(result.filePath.includes('prompt=Speak in a warm; friendly tone'), 'Commas in prompt are escaped to semicolons'); + + } catch (err) { + console.error(err); + t.end(err); + } + client.quit(); +}); + +test('Google TTS non-streaming tests (JAMBONES_DISABLE_TTS_STREAMING=true)', async(t) => { + // Enable streaming disable flag + process.env.JAMBONES_DISABLE_TTS_STREAMING = 'true'; + + // Clear require cache to reload config with new env var + delete require.cache[require.resolve('../lib/config')]; + delete require.cache[require.resolve('../lib/synth-audio')]; + delete require.cache[require.resolve('..')]; + + const fn = require('..'); + const {synthAudio, client} = fn(opts, logger); + + if (!process.env.GCP_FILE && !process.env.GCP_JSON_KEY) { + t.pass('skipping Google TTS non-streaming tests since neither GCP_FILE nor GCP_JSON_KEY provided'); + delete process.env.JAMBONES_DISABLE_TTS_STREAMING; + return t.end(); + } + + try { + const str = process.env.GCP_JSON_KEY || fs.readFileSync(process.env.GCP_FILE); + const creds = JSON.parse(str); + const geminiModel = process.env.GCP_GEMINI_TTS_MODEL || 'gemini-2.5-flash-tts'; + + // Test 1: Standard voice falls back to non-streaming API + let result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Wavenet-D', + gender: 'MALE', + text: 'This is a test with streaming disabled.', + disableTtsCache: true + }); + t.ok(!result.filePath.startsWith('say:'), 'Standard voice does NOT return streaming say: path when disabled'); + t.ok(result.filePath.endsWith('.mp3'), 'Standard voice returns mp3 file path'); + + // Test 2: HD voice falls back to non-streaming API + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Chirp3-HD-Charon', + text: 'This is a test of HD voice with streaming disabled.', + disableTtsCache: true + }); + t.ok(!result.filePath.startsWith('say:'), 'HD voice does NOT return streaming say: path when disabled'); + t.ok(result.filePath.endsWith('.mp3'), 'HD voice returns mp3 file path'); + + // Test 3: Gemini TTS falls back to non-streaming API + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'Kore', + model: geminiModel, + text: 'This is a test of Gemini TTS with streaming disabled.', + instructions: 'Speak naturally.', + disableTtsCache: true + }); + t.ok(!result.filePath.startsWith('say:'), 'Gemini TTS does NOT return streaming say: path when disabled'); + t.ok(result.filePath.endsWith('.mp3'), 'Gemini TTS returns mp3 file path'); + + } catch (err) { + console.error(err); + t.end(err); + } finally { + // Clean up: restore default behavior + delete process.env.JAMBONES_DISABLE_TTS_STREAMING; + delete require.cache[require.resolve('../lib/config')]; + delete require.cache[require.resolve('../lib/synth-audio')]; + delete require.cache[require.resolve('..')]; + } + client.quit(); +}); + test('AWS speech synth tests', async(t) => { const fn = require('..'); const {synthAudio, client} = fn(opts, logger); From b91e6cc1458a5b99f692f8a6aa1e9b404bd0333c Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 13:58:38 +0700 Subject: [PATCH 07/15] wip --- test/synth.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test/synth.js b/test/synth.js index 9d6fbf9..e6723cb 100644 --- a/test/synth.js +++ b/test/synth.js @@ -41,6 +41,7 @@ test('Google speech synth tests', async(t) => { gender: 'FEMALE', text: 'This is a test. This is only a test', salt: 'foo.bar', + renderForCaching: true, }); t.ok(!opts.servedFromCache, `successfully synthesized google audio to ${opts.filePath}`); @@ -55,6 +56,7 @@ test('Google speech synth tests', async(t) => { language: 'en-GB', gender: 'FEMALE', text: 'This is a test. This is only a test', + renderForCaching: true, }); t.ok(opts.servedFromCache, `successfully retrieved cached google audio from ${opts.filePath}`); @@ -78,6 +80,7 @@ test('Google speech synth tests', async(t) => { language: 'en-GB', gender: 'FEMALE', text: 'This is a test. This is only a test', + renderForCaching: true, }); t.ok(!opts.servedFromCache, `successfully synthesized google audio regardless of current cache to ${opts.filePath}`); } catch (err) { @@ -114,7 +117,8 @@ GCP_CUSTOM_VOICE_FILE nor GCP_CUSTOM_VOICE_JSON_KEY provided, GCP_CUSTOM_VOICE_M voice: { reportedUsage: 'REALTIME', model: process.env.GCP_CUSTOM_VOICE_MODEL - } + }, + renderForCaching: true, }); t.ok(!opts.servedFromCache, `successfully synthesized google custom voice audio to ${opts.filePath}`); } catch (err) { @@ -156,7 +160,8 @@ GCP_VOICE_CLONING_FILE nor GCP_VOICE_CLONING_JSON_KEY is not provided`); text: 'This is a test. This is only a test. This is a test. This is only a test. This is a test. This is only a test', voice: { voice_cloning_key - } + }, + renderForCaching: true, }); t.ok(!opts.servedFromCache, `successfully synthesized google voice cloning audio to ${opts.filePath}`); } catch (err) { @@ -193,6 +198,7 @@ test('Google Gemini TTS synth tests', async(t) => { model: geminiModel, text: 'Hello, this is a test of Google Gemini text to speech.', instructions: 'Speak clearly and naturally.', + renderForCaching: true, }); t.ok(!result.servedFromCache, `successfully synthesized Google Gemini TTS audio to ${result.filePath}`); t.ok(result.filePath.endsWith('.mp3'), 'Gemini TTS audio file has correct extension'); @@ -211,6 +217,7 @@ test('Google Gemini TTS synth tests', async(t) => { model: geminiModel, text: 'Welcome to our service. How can I help you today?', instructions: 'Speak in a warm, friendly and professional tone.', + renderForCaching: true, }); t.ok(!result.servedFromCache, `successfully synthesized Gemini TTS with instructions to ${result.filePath}`); @@ -228,6 +235,7 @@ test('Google Gemini TTS synth tests', async(t) => { model: geminiModel, text: 'Hello, this is a test of Google Gemini text to speech.', instructions: 'Speak clearly and naturally.', + renderForCaching: true, }); t.ok(result.servedFromCache, `successfully retrieved Gemini TTS audio from cache ${result.filePath}`); @@ -245,7 +253,8 @@ test('Google Gemini TTS synth tests', async(t) => { model: geminiModel, text: 'This SSML should be stripped for Gemini TTS.', instructions: 'Speak naturally.', - disableTtsCache: true + disableTtsCache: true, + renderForCaching: true, }); t.ok(!result.servedFromCache, `successfully synthesized Gemini TTS with SSML stripped to ${result.filePath}`); From 490d23a703c536d8f27943b687b21550ced0224a Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 15:46:29 +0700 Subject: [PATCH 08/15] wip --- lib/synth-audio.js | 2 +- test/synth.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 1ae9244..8597b51 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -435,7 +435,7 @@ const synthGoogle = async(logger, { } let params = '{'; - params += `credentials=${JSON.stringify(credentials)}`; + params += `credentials=${Buffer.from(JSON.stringify(credentials)).toString('base64')}`; params += `,playback_id=${key}`; params += ',vendor=google'; params += `,voice=${voice}`; diff --git a/test/synth.js b/test/synth.js index e6723cb..7b2cc12 100644 --- a/test/synth.js +++ b/test/synth.js @@ -306,6 +306,9 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => t.ok(result.filePath.includes('vendor=google'), 'Standard voice streaming path contains vendor=google'); t.ok(result.filePath.includes('use_live_api=0'), 'Standard voice uses use_live_api=0'); t.ok(result.filePath.includes('voice=en-US-Wavenet-D'), 'Standard voice streaming path contains voice'); + // Verify credentials are base64 encoded (no raw JSON braces that would break FreeSWitch parsing) + t.ok(result.filePath.includes('credentials='), 'Standard voice streaming path contains credentials'); + t.ok(!result.filePath.includes('credentials={'), 'Credentials are not raw JSON (base64 encoded)'); // Test 2: HD voice streaming (use_live_api=1) result = await synthAudio(stats, { From 62fec6f5e487a8f625ac9f49938194039d3d71e8 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 16:00:43 +0700 Subject: [PATCH 09/15] wip --- lib/synth-audio.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 8597b51..e1b8b92 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -435,7 +435,7 @@ const synthGoogle = async(logger, { } let params = '{'; - params += `credentials=${Buffer.from(JSON.stringify(credentials)).toString('base64')}`; + params += `credentials=${Buffer.from(JSON.stringify(credentials.credentials)).toString('base64')}`; params += `,playback_id=${key}`; params += ',vendor=google'; params += `,voice=${voice}`; From 417d58080ecda1a587d22278fa0462934118fbe7 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 17:34:07 +0700 Subject: [PATCH 10/15] wip --- lib/synth-audio.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index e1b8b92..4ba01b8 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -421,8 +421,8 @@ const synthGoogle = async(logger, { const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; // HD voices have pattern like en-US-Chirp3-HD-Charon const isHDVoice = typeof voice === 'string' && voice.includes('-HD-'); - // Live API is used for Gemini TTS and HD voices - const useLiveApi = isGemini || isHDVoice; + // Live API is used for HD voices + const useLiveApi = isHDVoice; // Streaming support for Google TTS (Gemini, HD voices, and standard voices) // Voice cloning does not support streaming From ca9538030f55aa74c73b14d99241daebbe397897 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Wed, 14 Jan 2026 17:37:38 +0700 Subject: [PATCH 11/15] wip --- test/synth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/synth.js b/test/synth.js index 7b2cc12..b571f16 100644 --- a/test/synth.js +++ b/test/synth.js @@ -347,7 +347,7 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => }); t.ok(result.filePath.startsWith('say:'), 'Gemini TTS returns streaming say: path'); t.ok(result.filePath.includes('vendor=google'), 'Gemini TTS streaming path contains vendor=google'); - t.ok(result.filePath.includes('use_live_api=1'), 'Gemini TTS uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes('use_live_api=0'), 'Gemini TTS uses use_live_api=1 (Live API)'); t.ok(result.filePath.includes(`model_name=${geminiModel}`), 'Gemini TTS streaming path contains model_name'); t.ok(result.filePath.includes('prompt=Speak naturally.'), 'Gemini TTS streaming path contains prompt'); From 29edccd5bfb8ecb745826c935836438d21d1ed2c Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Sat, 17 Jan 2026 15:10:17 +0700 Subject: [PATCH 12/15] wip --- lib/synth-audio.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 4ba01b8..25162d9 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -421,8 +421,8 @@ const synthGoogle = async(logger, { const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; // HD voices have pattern like en-US-Chirp3-HD-Charon const isHDVoice = typeof voice === 'string' && voice.includes('-HD-'); - // Live API is used for HD voices - const useLiveApi = isHDVoice; + // Live API is used for HD voices and Gemini voices + const useLiveApi = isGemini || isHDVoice; // Streaming support for Google TTS (Gemini, HD voices, and standard voices) // Voice cloning does not support streaming From 89007ba7ccdbc8ac4f23f7a2fbdeec8f8aab03a6 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Sat, 17 Jan 2026 15:13:47 +0700 Subject: [PATCH 13/15] wip --- test/synth.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/synth.js b/test/synth.js index b571f16..7b2cc12 100644 --- a/test/synth.js +++ b/test/synth.js @@ -347,7 +347,7 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => }); t.ok(result.filePath.startsWith('say:'), 'Gemini TTS returns streaming say: path'); t.ok(result.filePath.includes('vendor=google'), 'Gemini TTS streaming path contains vendor=google'); - t.ok(result.filePath.includes('use_live_api=0'), 'Gemini TTS uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes('use_live_api=1'), 'Gemini TTS uses use_live_api=1 (Live API)'); t.ok(result.filePath.includes(`model_name=${geminiModel}`), 'Gemini TTS streaming path contains model_name'); t.ok(result.filePath.includes('prompt=Speak naturally.'), 'Gemini TTS streaming path contains prompt'); From 10095de25da237d48236093b5cfed9313a6c1d0c Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Sat, 17 Jan 2026 16:16:11 +0700 Subject: [PATCH 14/15] wip --- lib/synth-audio.js | 5 ++--- test/synth.js | 5 ++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index 25162d9..a4f6fa1 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -421,8 +421,6 @@ const synthGoogle = async(logger, { const isVoiceCloning = typeof voice === 'object' && voice.voice_cloning_key; // HD voices have pattern like en-US-Chirp3-HD-Charon const isHDVoice = typeof voice === 'string' && voice.includes('-HD-'); - // Live API is used for HD voices and Gemini voices - const useLiveApi = isGemini || isHDVoice; // Streaming support for Google TTS (Gemini, HD voices, and standard voices) // Voice cloning does not support streaming @@ -441,7 +439,8 @@ const synthGoogle = async(logger, { params += `,voice=${voice}`; params += `,language_code=${language || 'en-US'}`; params += `,write_cache_file=${disableTtsCache ? 0 : 1}`; - params += `,use_live_api=${useLiveApi ? 1 : 0}`; + params += `,use_live_api=${isHDVoice ? 1 : 0}`; + params += `,use_gemini_tts=${isGemini ? 1 : 0}`; if (model) params += `,model_name=${model}`; if (gender) params += `,gender=${gender}`; // comma is used to separate parameters in freeswitch tts module diff --git a/test/synth.js b/test/synth.js index 7b2cc12..5e96648 100644 --- a/test/synth.js +++ b/test/synth.js @@ -305,6 +305,7 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => t.ok(result.filePath.startsWith('say:'), 'Standard voice returns streaming say: path'); t.ok(result.filePath.includes('vendor=google'), 'Standard voice streaming path contains vendor=google'); t.ok(result.filePath.includes('use_live_api=0'), 'Standard voice uses use_live_api=0'); + t.ok(result.filePath.includes('use_gemini_tts=0'), 'Standard voice uses use_gemini_tts=0'); t.ok(result.filePath.includes('voice=en-US-Wavenet-D'), 'Standard voice streaming path contains voice'); // Verify credentials are base64 encoded (no raw JSON braces that would break FreeSWitch parsing) t.ok(result.filePath.includes('credentials='), 'Standard voice streaming path contains credentials'); @@ -327,6 +328,7 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => t.ok(result.filePath.startsWith('say:'), 'HD voice returns streaming say: path'); t.ok(result.filePath.includes('vendor=google'), 'HD voice streaming path contains vendor=google'); t.ok(result.filePath.includes('use_live_api=1'), 'HD voice uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes('use_gemini_tts=0'), 'HD voice uses use_gemini_tts=0'); t.ok(result.filePath.includes('voice=en-US-Chirp3-HD-Charon'), 'HD voice streaming path contains voice'); // Test 3: Gemini TTS streaming (use_live_api=1) @@ -347,7 +349,8 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => }); t.ok(result.filePath.startsWith('say:'), 'Gemini TTS returns streaming say: path'); t.ok(result.filePath.includes('vendor=google'), 'Gemini TTS streaming path contains vendor=google'); - t.ok(result.filePath.includes('use_live_api=1'), 'Gemini TTS uses use_live_api=1 (Live API)'); + t.ok(result.filePath.includes('use_live_api=0'), 'Gemini TTS uses use_live_api=0'); + t.ok(result.filePath.includes('use_gemini_tts=1'), 'Gemini TTS uses use_gemini_tts=1'); t.ok(result.filePath.includes(`model_name=${geminiModel}`), 'Gemini TTS streaming path contains model_name'); t.ok(result.filePath.includes('prompt=Speak naturally.'), 'Gemini TTS streaming path contains prompt'); From a7e391fcb216507903f0612056c2eed732a493d2 Mon Sep 17 00:00:00 2001 From: Hoan HL Date: Sun, 18 Jan 2026 08:45:14 +0700 Subject: [PATCH 15/15] wip --- lib/synth-audio.js | 6 ++++-- test/synth.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/lib/synth-audio.js b/lib/synth-audio.js index a4f6fa1..a7699ce 100644 --- a/lib/synth-audio.js +++ b/lib/synth-audio.js @@ -439,8 +439,10 @@ const synthGoogle = async(logger, { params += `,voice=${voice}`; params += `,language_code=${language || 'en-US'}`; params += `,write_cache_file=${disableTtsCache ? 0 : 1}`; - params += `,use_live_api=${isHDVoice ? 1 : 0}`; - params += `,use_gemini_tts=${isGemini ? 1 : 0}`; + const useLiveApi = options?.useLiveApi ?? isHDVoice; + const useGeminiTts = options?.useGeminiTts ?? isGemini; + params += `,use_live_api=${useLiveApi ? 1 : 0}`; + params += `,use_gemini_tts=${useGeminiTts ? 1 : 0}`; if (model) params += `,model_name=${model}`; if (gender) params += `,gender=${gender}`; // comma is used to separate parameters in freeswitch tts module diff --git a/test/synth.js b/test/synth.js index 5e96648..49f9b7e 100644 --- a/test/synth.js +++ b/test/synth.js @@ -394,6 +394,60 @@ test('Google TTS streaming tests (!JAMBONES_DISABLE_TTS_STREAMING)', async(t) => // Commas in prompt should be replaced with semicolons t.ok(result.filePath.includes('prompt=Speak in a warm; friendly tone'), 'Commas in prompt are escaped to semicolons'); + // Test 6: options.useLiveApi override (force live api on standard voice) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Wavenet-D', + text: 'Testing useLiveApi option override.', + options: { useLiveApi: true }, + disableTtsCache: true + }); + t.ok(result.filePath.includes('use_live_api=1'), 'options.useLiveApi=true overrides default for standard voice'); + t.ok(result.filePath.includes('use_gemini_tts=0'), 'use_gemini_tts remains 0 for standard voice'); + + // Test 7: options.useGeminiTts override (force gemini tts without model) + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'Kore', + text: 'Testing useGeminiTts option override.', + options: { useGeminiTts: true }, + disableTtsCache: true + }); + t.ok(result.filePath.includes('use_gemini_tts=1'), 'options.useGeminiTts=true overrides default'); + t.ok(result.filePath.includes('use_live_api=0'), 'use_live_api remains 0 without HD voice'); + + // Test 8: Both options override together + result = await synthAudio(stats, { + vendor: 'google', + credentials: { + credentials: { + client_email: creds.client_email, + private_key: creds.private_key, + }, + }, + language: 'en-US', + voice: 'en-US-Wavenet-D', + text: 'Testing both options override.', + options: { useLiveApi: true, useGeminiTts: true }, + disableTtsCache: true + }); + t.ok(result.filePath.includes('use_live_api=1'), 'options.useLiveApi=true works with useGeminiTts'); + t.ok(result.filePath.includes('use_gemini_tts=1'), 'options.useGeminiTts=true works with useLiveApi'); + } catch (err) { console.error(err); t.end(err);