diff --git a/README.md b/README.md index 398b0ab..a6c4949 100644 --- a/README.md +++ b/README.md @@ -1 +1,29 @@ -pm2 start --name admin-banban-new-nest npm -- run start:prod \ No newline at end of file +pm2 start --name admin-banban-new-nest npm -- run start:prod + +// { +// roleId: '6704bd0ef48326fe51ddb751', +// roleName: '甘宁', +// url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E4%BB%A3%E5%8F%B7%E9%B8%A2%E5%AF%86%E6%8E%A2%E7%94%98%E5%AE%81.mp3', +// taskId: '674d85d7467ce26d974f97e9' +// } +// 开始处理任务 [第1次尝试]: 甘宁 +// { +// SpeakerID: 'S*FC60x0Gb1', +// InstanceNO: 'Model_storage_BpVrslAkhpaKVod*', +// IsActivatable: false, +// State: 'Unknown', +// DemoAudio: null, +// Version: null, +// CreateTime: 0, +// ExpireTime: 1764691199000, +// Alias: '', +// AvailableTrainingTimes: 10 +// } +// S_FC60x0Gb1 + +开始克隆声音,参数: { speaker_id: 'S_FC60x0Gb1', appid: '8167092294', audio_format: 'wav' } + + diff --git a/package.json b/package.json index ca44b1e..391822e 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", + "dev": "nest start", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", @@ -21,15 +22,22 @@ "gen": "prisma generate" }, "dependencies": { + "@nestjs/bull": "^10.2.3", "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@prisma/client": "^5.19.1", + "@volcengine/openapi": "^1.25.0", + "ali-oss": "^6.21.0", + "axios": "^1.7.8", + "bull": "^4.16.4", "class-validator": "^0.14.1", + "ioredis": "^5.4.1", "lodash": "^4.17.21", "prisma": "^5.19.1", "reflect-metadata": "^0.2.0", - "rxjs": "^7.8.1" + "rxjs": "^7.8.1", + "uuid": "^11.0.3" }, "devDependencies": { "@nestjs/cli": "^10.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78bb618..62c0aea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@nestjs/bull': + specifier: ^10.2.3 + version: 10.2.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bull@4.16.4) '@nestjs/common': specifier: ^10.0.0 version: 10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -20,9 +23,24 @@ importers: '@prisma/client': specifier: ^5.19.1 version: 5.19.1(prisma@5.19.1) + '@volcengine/openapi': + specifier: ^1.25.0 + version: 1.25.0 + ali-oss: + specifier: ^6.21.0 + version: 6.21.0 + axios: + specifier: ^1.7.8 + version: 1.7.8 + bull: + specifier: ^4.16.4 + version: 4.16.4 class-validator: specifier: ^0.14.1 version: 0.14.1 + ioredis: + specifier: ^5.4.1 + version: 5.4.1 lodash: specifier: ^4.17.21 version: 4.17.21 @@ -35,6 +53,9 @@ importers: rxjs: specifier: ^7.8.1 version: 7.8.1 + uuid: + specifier: ^11.0.3 + version: 11.0.3 devDependencies: '@nestjs/cli': specifier: ^10.0.0 @@ -332,6 +353,9 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@ioredis/commands@1.2.0': + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -442,6 +466,49 @@ packages: resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} + cpu: [x64] + os: [win32] + + '@nestjs/bull-shared@10.2.3': + resolution: {integrity: sha512-XcgAjNOgq6b5DVCytxhR5BKiwWo7hsusVeyE7sfFnlXRHeEtIuC2hYWBr/ZAtvL/RH0/O0tqtq0rVl972nbhJw==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 + + '@nestjs/bull@10.2.3': + resolution: {integrity: sha512-Gy90JjFCfYhWFBeoBSidc7rEEf2BNhkJ3RfK8ym589POOldwAra2xcnFBi0ZuhhOV60GcrCJBBkdrUbAMM670w==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 + bull: ^3.3 || ^4.0.0 + '@nestjs/cli@10.4.5': resolution: {integrity: sha512-FP7Rh13u8aJbHe+zZ7hM0CC4785g9Pw4lz4r2TTgRtf0zTxSWMkJaPEwyjX8SK9oWK2GsYxl+fKpwVZNbmnj9A==} engines: {node: '>= 16.14'} @@ -558,6 +625,36 @@ packages: '@prisma/get-platform@5.19.1': resolution: {integrity: sha512-sCeoJ+7yt0UjnR+AXZL7vXlg5eNxaFOwC23h0KvW1YIXUoa7+W2ZcAUhoEQBmJTW4GrFqCuZ8YSP0mkDa4k3Zg==} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -729,6 +826,10 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@volcengine/openapi@1.25.0': + resolution: {integrity: sha512-aPQ2TTS+DB9slWf2IKE+rg+gY/MvgO5VvDPQZlk6+B4ZjPex0F39/eRJpY/KyT0bZGuc620VVqYQO1nNofTIKg==} + engines: {node: '>=12'} + '@webassemblyjs/ast@1.12.1': resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} @@ -803,6 +904,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + agentkeepalive@3.5.3: + resolution: {integrity: sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==} + engines: {node: '>= 4.0.0'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -822,6 +931,10 @@ packages: ajv@8.12.0: resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + ali-oss@6.21.0: + resolution: {integrity: sha512-dRvKWO/GJEa6dlsCnvmgHIbU5+yE/SmZsE4kZRGNU7Uotr9uIkQWGqv4szLTxRSxWv3YgL+BZgt+swIgitYGjA==} + engines: {node: '>=8'} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -854,6 +967,9 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} @@ -885,6 +1001,12 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + + axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -927,6 +1049,9 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + bowser@1.9.4: + resolution: {integrity: sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -955,6 +1080,13 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + + bull@4.16.4: + resolution: {integrity: sha512-CF+nGsJyfsCC9MJL8hFxqXzbwq+jGBXhaz1j15G+5N/XtKIPFUUy5O1mfWWKbKunfuH/x+UV4NYRQDHSkjCOgA==} + engines: {node: '>=12'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -1047,6 +1179,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -1116,6 +1252,9 @@ packages: cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + copy-to@2.0.1: + resolution: {integrity: sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -1132,6 +1271,15 @@ packages: typescript: optional: true + crc@4.3.2: + resolution: {integrity: sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==} + engines: {node: '>=12'} + peerDependencies: + buffer: '>=6.0.3' + peerDependenciesMeta: + buffer: + optional: true + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1140,10 +1288,23 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + dateformat@2.2.0: + resolution: {integrity: sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -1176,6 +1337,10 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-user-agent@1.0.0: + resolution: {integrity: sha512-bDF7bg6OSNcSwFWPu4zYKpVkJZQYVrAANMYB8bc9Szem1D0yKdm4sa/rOCs2aC9+2GMqQ7KnwtZRvDhmLF0dXw==} + engines: {node: '>= 0.10.0'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -1187,6 +1352,10 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1195,6 +1364,10 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -1210,6 +1383,10 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + digest-header@1.1.0: + resolution: {integrity: sha512-glXVh42vz40yZb9Cq2oMOt70FIoWiv+vxNvdKdU8CwjLad25qHM3trLxhl9bVjdr6WaslIXhWpn0NO8T/67Qjg==} + engines: {node: '>= 8.0.0'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -1246,6 +1423,13 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + end-or-error@1.0.1: + resolution: {integrity: sha512-OclLMSug+k2A0JKuf494im25ANRBVW8qsjmwbgX7lQ8P82H21PQ1PWkoYwb9y5yMBS69BPlwtzdIFClo3+7kOQ==} + engines: {node: '>= 0.11.14'} + enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} @@ -1373,6 +1557,10 @@ packages: resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} engines: {node: '>= 0.10.0'} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -1436,6 +1624,15 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} @@ -1447,6 +1644,10 @@ packages: typescript: '>3.6.0' webpack: ^5.11.0 + form-data@3.0.2: + resolution: {integrity: sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==} + engines: {node: '>= 6'} + form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -1454,6 +1655,9 @@ packages: formidable@3.5.1: resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} + formstream@1.5.1: + resolution: {integrity: sha512-q7ORzFqotpwn3Y/GBK2lK7PjtZZwJHz9QE9Phv8zb5IrL9ftGLyi2zjGURON3voK8TaZ+mqJKERYN4lrHYTkUQ==} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -1496,6 +1700,13 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + + get-ready@1.0.0: + resolution: {integrity: sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1579,10 +1790,17 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1618,6 +1836,10 @@ packages: resolution: {integrity: sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==} engines: {node: '>=18'} + ioredis@5.4.1: + resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==} + engines: {node: '>=12.22.0'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -1629,10 +1851,17 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} + is-class-hotfix@0.0.6: + resolution: {integrity: sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ==} + is-core-module@2.15.1: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1665,6 +1894,9 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-type-of@1.4.0: + resolution: {integrity: sha512-EddYllaovi5ysMLMEN7yzHEKh8A850cZ7pykrY1aNRQGn/CDjRDE9qEWbIdt7xGEVJmjBXzU/fNnC4ABTm8tEQ==} + is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -1675,6 +1907,9 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -1844,6 +2079,9 @@ packages: node-notifier: optional: true + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1889,6 +2127,9 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jstoxml@2.2.9: + resolution: {integrity: sha512-OYWlK0j+roh+eyaMROlNbS5cd5R25Y+IUpdl7cNdB8HNrkgwQzIS7L9MegxOiWNBj9dQhA/yAxiMwCC5mwNoBw==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1922,6 +2163,15 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + lodash.memoize@4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} @@ -1935,12 +2185,19 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + luxon@3.5.0: + resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + engines: {node: '>=12'} + magic-string@0.30.8: resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} engines: {node: '>=12'} @@ -2031,6 +2288,13 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msgpackr-extract@3.0.3: + resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} + hasBin: true + + msgpackr@1.11.2: + resolution: {integrity: sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==} + multer@1.4.4-lts.1: resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} engines: {node: '>= 6.0.0'} @@ -2042,6 +2306,9 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2067,6 +2334,14 @@ packages: encoding: optional: true + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + + node-hex@1.0.1: + resolution: {integrity: sha512-iwpZdvW6Umz12ICmu9IYPRxg0tOLGmU3Tq2tKetejCj3oZd7b2nUXwP3a7QA5M9glWy8wlPS1G3RwM/CdsUbdQ==} + engines: {node: '>=8.0.0'} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -2108,10 +2383,20 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + os-name@1.0.3: + resolution: {integrity: sha512-f5estLO2KN8vgtTRaILIgEGBoBrMnZ3JQ7W9TMZCnOIGwHe8TRGSpcagnWDo+Dfhd/z08k9Xe75hvciJJ8Qaew==} + engines: {node: '>=0.10.0'} + hasBin: true + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + osx-release@1.1.0: + resolution: {integrity: sha512-ixCMMwnVxyHFQLQnINhmIpWqXIfS2YOXchwQrk+OFzmo6nDjQ0E4KXAyyUh0T0MZgV4bUhkRrAbVqlE4yLVq4A==} + engines: {node: '>=0.10.0'} + hasBin: true + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -2176,6 +2461,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} @@ -2195,6 +2483,9 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + platform@1.3.6: + resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -2228,10 +2519,20 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + protobufjs@7.2.4: + resolution: {integrity: sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==} + engines: {node: '>=12.0.0'} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2271,6 +2572,14 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -2342,10 +2651,20 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + sdk-base@2.0.1: + resolution: {integrity: sha512-eeG26wRwhtwYuKGCDM3LixCaxY27Pa/5lK4rLKhQa7HBjJ3U3Y+f81MMZQRsDw/8SC2Dao/83yJTXJ8aULuN8Q==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2420,10 +2739,24 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + stream-http@2.8.2: + resolution: {integrity: sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==} + + stream-wormhole@1.1.0: + resolution: {integrity: sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==} + engines: {node: '>=4.0.0'} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -2534,6 +2867,13 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -2544,6 +2884,9 @@ packages: tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -2625,6 +2968,9 @@ packages: tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -2665,6 +3011,10 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + unescape@1.0.1: + resolution: {integrity: sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==} + engines: {node: '>=0.10.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -2682,13 +3032,34 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urllib@2.44.0: + resolution: {integrity: sha512-zRCJqdfYllRDA9bXUtx+vccyRqtJPKsw85f44zH7zPD28PIvjMqIgw9VwoTLV7xTBWZsbebUFVHU5ghQcWku2A==} + engines: {node: '>= 0.10.0'} + peerDependencies: + proxy-agent: ^5.0.0 + peerDependenciesMeta: + proxy-agent: + optional: true + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utility@1.18.0: + resolution: {integrity: sha512-PYxZDA+6QtvRvm//++aGdmKG/cI07jNwbROz0Ql+VzFV1+Z0Dy55NI4zZ7RHc9KKpBePNFwoErqIuqQv/cjiTA==} + engines: {node: '>= 0.12.0'} + utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@11.0.3: + resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -2743,6 +3114,10 @@ packages: engines: {node: '>= 8'} hasBin: true + win-release@1.1.1: + resolution: {integrity: sha512-iCRnKVvGxOQdsKhcQId2PXV1vV3J/sDPXKA4Oe9+Eti2nb2ESEsYHRYls/UjoUW3bIc5ZDO8dTH50A/5iVN+bw==} + engines: {node: '>=0.10.0'} + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -2766,6 +3141,14 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -3075,6 +3458,8 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@ioredis/commands@1.2.0': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -3289,6 +3674,38 @@ snapshots: '@lukeed/csprng@1.1.0': {} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': + optional: true + + '@nestjs/bull-shared@10.2.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1))': + dependencies: + '@nestjs/common': 10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1) + tslib: 2.8.1 + + '@nestjs/bull@10.2.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bull@4.16.4)': + dependencies: + '@nestjs/bull-shared': 10.2.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1)) + '@nestjs/common': 10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.3(@nestjs/common@10.4.3(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.3)(reflect-metadata@0.2.2)(rxjs@7.8.1) + bull: 4.16.4 + tslib: 2.8.1 + '@nestjs/cli@10.4.5': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) @@ -3433,6 +3850,29 @@ snapshots: dependencies: '@prisma/debug': 5.19.1 + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@3.0.1': @@ -3650,6 +4090,22 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@volcengine/openapi@1.25.0': + dependencies: + axios: 0.21.4(debug@4.3.7) + crc: 4.3.2 + crypto-js: 4.2.0 + dayjs: 1.11.13 + debug: 4.3.7 + form-data: 3.0.2 + lodash.get: 4.4.2 + p-limit: 3.1.0 + protobufjs: 7.2.4 + uuid: 8.3.2 + transitivePeerDependencies: + - buffer + - supports-color + '@webassemblyjs/ast@1.12.1': dependencies: '@webassemblyjs/helper-numbers': 1.11.6 @@ -3749,6 +4205,12 @@ snapshots: acorn@8.12.1: {} + address@1.2.2: {} + + agentkeepalive@3.5.3: + dependencies: + humanize-ms: 1.2.1 + ajv-formats@2.1.1(ajv@8.12.0): optionalDependencies: ajv: 8.12.0 @@ -3771,6 +4233,37 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 + ali-oss@6.21.0: + dependencies: + address: 1.2.2 + agentkeepalive: 3.5.3 + bowser: 1.9.4 + copy-to: 2.0.1 + dateformat: 2.2.0 + debug: 4.3.7 + destroy: 1.2.0 + end-or-error: 1.0.1 + get-ready: 1.0.0 + humanize-ms: 1.2.1 + is-type-of: 1.4.0 + js-base64: 2.6.4 + jstoxml: 2.2.9 + lodash: 4.17.21 + merge-descriptors: 1.0.3 + mime: 2.6.0 + platform: 1.3.6 + pump: 3.0.2 + qs: 6.13.0 + sdk-base: 2.0.1 + stream-http: 2.8.2 + stream-wormhole: 1.1.0 + urllib: 2.44.0 + utility: 1.18.0 + xml2js: 0.6.2 + transitivePeerDependencies: + - proxy-agent + - supports-color + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: @@ -3793,6 +4286,8 @@ snapshots: ansi-styles@6.2.1: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -3818,6 +4313,20 @@ snapshots: asynckit@0.4.0: {} + axios@0.21.4(debug@4.3.7): + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + transitivePeerDependencies: + - debug + + axios@1.7.8: + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + babel-jest@29.7.0(@babel/core@7.25.2): dependencies: '@babel/core': 7.25.2 @@ -3902,6 +4411,8 @@ snapshots: transitivePeerDependencies: - supports-color + bowser@1.9.4: {} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -3937,6 +4448,20 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + builtin-status-codes@3.0.0: {} + + bull@4.16.4: + dependencies: + cron-parser: 4.9.0 + get-port: 5.1.1 + ioredis: 5.4.1 + lodash: 4.17.21 + msgpackr: 1.11.2 + semver: 7.6.3 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -4024,6 +4549,8 @@ snapshots: clone@1.0.4: {} + cluster-key-slot@1.1.2: {} + co@4.6.0: {} collect-v8-coverage@1.0.2: {} @@ -4083,6 +4610,8 @@ snapshots: cookiejar@2.1.4: {} + copy-to@2.0.1: {} + core-util-is@1.0.3: {} cors@2.8.5: @@ -4099,6 +4628,8 @@ snapshots: optionalDependencies: typescript: 5.3.3 + crc@4.3.2: {} + create-jest@29.7.0(@types/node@20.16.5)(ts-node@10.9.2(@types/node@20.16.5)(typescript@5.6.2)): dependencies: '@jest/types': 29.6.3 @@ -4116,12 +4647,22 @@ snapshots: create-require@1.1.1: {} + cron-parser@4.9.0: + dependencies: + luxon: 3.5.0 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + + dateformat@2.2.0: {} + + dayjs@1.11.13: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -4136,6 +4677,10 @@ snapshots: deepmerge@4.3.1: {} + default-user-agent@1.0.0: + dependencies: + os-name: 1.0.3 + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -4148,10 +4693,15 @@ snapshots: delayed-stream@1.0.0: {} + denque@2.1.0: {} + depd@2.0.0: {} destroy@1.2.0: {} + detect-libc@2.0.3: + optional: true + detect-newline@3.1.0: {} dezalgo@1.0.4: @@ -4163,6 +4713,8 @@ snapshots: diff@4.0.2: {} + digest-header@1.1.0: {} + doctrine@3.0.0: dependencies: esutils: 2.0.3 @@ -4187,6 +4739,12 @@ snapshots: encodeurl@2.0.0: {} + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + end-or-error@1.0.1: {} + enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 @@ -4366,6 +4924,10 @@ snapshots: transitivePeerDependencies: - supports-color + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -4444,6 +5006,10 @@ snapshots: flatted@3.3.1: {} + follow-redirects@1.15.9(debug@4.3.7): + optionalDependencies: + debug: 4.3.7 + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 @@ -4466,6 +5032,12 @@ snapshots: typescript: 5.3.3 webpack: 5.94.0 + form-data@3.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + form-data@4.0.0: dependencies: asynckit: 0.4.0 @@ -4478,6 +5050,13 @@ snapshots: hexoid: 1.0.0 once: 1.4.0 + formstream@1.5.1: + dependencies: + destroy: 1.2.0 + mime: 2.6.0 + node-hex: 1.0.1 + pause-stream: 0.0.11 + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -4511,6 +5090,10 @@ snapshots: get-package-type@0.1.0: {} + get-port@5.1.1: {} + + get-ready@1.0.0: {} + get-stream@6.0.1: {} glob-parent@5.1.2: @@ -4587,10 +5170,18 @@ snapshots: human-signals@2.1.0: {} + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -4650,6 +5241,20 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 6.2.0 + ioredis@5.4.1: + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.3.7 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + ipaddr.js@1.9.1: {} is-arrayish@0.2.1: {} @@ -4658,10 +5263,14 @@ snapshots: dependencies: binary-extensions: 2.3.0 + is-class-hotfix@0.0.6: {} + is-core-module@2.15.1: dependencies: hasown: 2.0.2 + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -4680,12 +5289,20 @@ snapshots: is-stream@2.0.1: {} + is-type-of@1.4.0: + dependencies: + core-util-is: 1.0.3 + is-class-hotfix: 0.0.6 + isstream: 0.1.2 + is-unicode-supported@0.1.0: {} isarray@1.0.0: {} isexe@2.0.0: {} + isstream@0.1.2: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@5.2.1: @@ -5057,6 +5674,8 @@ snapshots: - supports-color - ts-node + js-base64@2.6.4: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -5092,6 +5711,8 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jstoxml@2.2.9: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -5119,6 +5740,12 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash.defaults@4.2.0: {} + + lodash.get@4.4.2: {} + + lodash.isarguments@3.1.0: {} + lodash.memoize@4.1.2: {} lodash.merge@4.6.2: {} @@ -5130,12 +5757,16 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + long@5.2.3: {} + lru-cache@10.4.3: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 + luxon@3.5.0: {} + magic-string@0.30.8: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -5205,6 +5836,22 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.3: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 + optional: true + + msgpackr@1.11.2: + optionalDependencies: + msgpackr-extract: 3.0.3 + multer@1.4.4-lts.1: dependencies: append-field: 1.0.0 @@ -5219,6 +5866,12 @@ snapshots: mute-stream@1.0.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + natural-compare@1.4.0: {} negotiator@0.6.3: {} @@ -5235,6 +5888,13 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.0.3 + optional: true + + node-hex@1.0.1: {} + node-int64@0.4.0: {} node-releases@2.0.18: {} @@ -5282,8 +5942,17 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + os-name@1.0.3: + dependencies: + osx-release: 1.1.0 + win-release: 1.1.1 + os-tmpdir@1.0.2: {} + osx-release@1.1.0: + dependencies: + minimist: 1.2.8 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -5336,6 +6005,10 @@ snapshots: path-type@4.0.0: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + picocolors@1.1.0: {} picomatch@2.3.1: {} @@ -5348,6 +6021,8 @@ snapshots: dependencies: find-up: 4.1.0 + platform@1.3.6: {} + pluralize@8.0.0: {} prelude-ls@1.2.1: {} @@ -5377,11 +6052,33 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + protobufjs@7.2.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 20.16.5 + long: 5.2.3 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@1.1.0: {} + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -5427,6 +6124,12 @@ snapshots: dependencies: picomatch: 2.3.1 + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + reflect-metadata@0.2.2: {} repeat-string@1.6.1: {} @@ -5480,12 +6183,20 @@ snapshots: safer-buffer@2.1.2: {} + sax@1.4.1: {} + schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + sdk-base@2.0.1: + dependencies: + get-ready: 1.0.0 + + semver@5.7.2: {} + semver@6.3.1: {} semver@7.6.3: {} @@ -5573,8 +6284,22 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + standard-as-callback@2.1.0: {} + + statuses@1.5.0: {} + statuses@2.0.1: {} + stream-http@2.8.2: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.8 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + + stream-wormhole@1.1.0: {} + streamsearch@1.1.0: {} string-length@4.0.2: @@ -5686,6 +6411,14 @@ snapshots: text-table@0.2.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + through@2.3.8: {} tmp@0.0.33: @@ -5694,6 +6427,8 @@ snapshots: tmpl@1.0.5: {} + to-arraybuffer@1.0.1: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -5771,6 +6506,8 @@ snapshots: tslib@2.7.0: {} + tslib@2.8.1: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -5798,6 +6535,10 @@ snapshots: undici-types@6.19.8: {} + unescape@1.0.1: + dependencies: + extend-shallow: 2.0.1 + universalify@2.0.1: {} unpipe@1.0.0: {} @@ -5812,10 +6553,37 @@ snapshots: dependencies: punycode: 2.3.1 + urllib@2.44.0: + dependencies: + any-promise: 1.3.0 + content-type: 1.0.5 + default-user-agent: 1.0.0 + digest-header: 1.1.0 + ee-first: 1.1.1 + formstream: 1.5.1 + humanize-ms: 1.2.1 + iconv-lite: 0.6.3 + pump: 3.0.2 + qs: 6.13.0 + statuses: 1.5.0 + utility: 1.18.0 + util-deprecate@1.0.2: {} + utility@1.18.0: + dependencies: + copy-to: 2.0.1 + escape-html: 1.0.3 + mkdirp: 0.5.6 + mz: 2.7.0 + unescape: 1.0.1 + utils-merge@1.0.1: {} + uuid@11.0.3: {} + + uuid@8.3.2: {} + v8-compile-cache-lib@3.0.1: {} v8-to-istanbul@9.3.0: @@ -5886,6 +6654,10 @@ snapshots: dependencies: isexe: 2.0.0 + win-release@1.1.1: + dependencies: + semver: 5.7.2 + word-wrap@1.2.5: {} wrap-ansi@6.2.0: @@ -5913,6 +6685,13 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + xml2js@0.6.2: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + xtend@4.0.2: {} y18n@5.0.8: {} diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c54046b..ad7bfca 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -26,4 +26,35 @@ model SystemCharter { bg String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + + // 音色id + voiceId String? + // 音色名称 + voiceName String? + + // 原始音频 + originAudioUrl String? + // 克隆音频 + cloneAfterAudioUrl String? + // 是否激活 + activate Boolean @default(false) +} + +// 任务队列 +model TaskQueue { + id String @id @default(auto()) @map("_id") @db.ObjectId + // 任务类型 + type String + // 任务数据 + data String + // 任务状态: pending/processing/completed/failed + status String + // 失败原因 + error String? + // 重试次数 + attempts Int @default(0) + // 最大重试次数 + maxAttempts Int @default(3) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt } diff --git a/src/app.module.ts b/src/app.module.ts index 1a85134..1291c6d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -3,11 +3,11 @@ import { AppController } from './app.controller'; import { AppService } from './app.service'; import { SystemCharterModule } from './modules/index'; import { DBModule } from './utils/db/DB.module'; - +import { RedisTask } from './common/RedisTask/redisTask.module'; @Module({ - imports: [DBModule, SystemCharterModule], + imports: [DBModule, SystemCharterModule, RedisTask], controllers: [AppController], providers: [AppService], }) -export class AppModule { } +export class AppModule {} diff --git a/src/common/RedisTask/RedisTask.module.ts b/src/common/RedisTask/RedisTask.module.ts new file mode 100644 index 0000000..b74a520 --- /dev/null +++ b/src/common/RedisTask/RedisTask.module.ts @@ -0,0 +1,34 @@ +import { Global, Module } from '@nestjs/common'; +import { BullModule } from '@nestjs/bull'; +import { RedisTaskProcessor } from './RedisTaskProcessor.service'; +import { RedisTaskService } from './RedisTask.service'; + +@Global() +@Module({ + imports: [ + BullModule.forRoot({ + redis: { + host: '47.101.147.173', + port: 6379, + password: 'SAe7HmZhkF8uev', + }, + defaultJobOptions: { + removeOnComplete: true, + attempts: 3, + }, + }), + BullModule.registerQueue({ + name: 'task_queue', + limiter: { + max: 1, + duration: 1000, + }, + }), + BullModule.registerQueue({ + name: 'dead_letter_queue', + }), + ], + providers: [RedisTaskService, RedisTaskProcessor], + exports: [RedisTaskService], +}) +export class RedisTask {} diff --git a/src/common/RedisTask/RedisTask.service.ts b/src/common/RedisTask/RedisTask.service.ts new file mode 100644 index 0000000..8ba388f --- /dev/null +++ b/src/common/RedisTask/RedisTask.service.ts @@ -0,0 +1,94 @@ +import { InjectQueue } from '@nestjs/bull'; +import { Injectable } from '@nestjs/common'; +import { Queue } from 'bull'; +import { DBService } from 'src/utils/db/DB.service'; + +@Injectable() +export class RedisTaskService { + constructor( + @InjectQueue('task_queue') private readonly taskQueue: Queue, + private readonly dbService: DBService, + ) {} + + // 添加任务 + async addTask(data: any) { + // 先记录到数据库 + const taskRecord = await this.dbService.taskQueue.create({ + data: { + type: 'BATCH_CLONE_AUDIO', + data: JSON.stringify(data), + status: 'pending', + }, + }); + + // 添加到Redis队列 + await this.taskQueue.add( + 'BATCH_CLONE_AUDIO', + { + ...data, + taskId: taskRecord.id, + }, + { + removeOnComplete: true, + attempts: 3, + }, + ); + } + + // 获取所有任务 + async getTasks(status?: string) { + const where = status ? { status } : {}; + return await this.dbService.taskQueue.findMany({ + where, + orderBy: { + createdAt: 'desc', + }, + }); + } + + // 更新任务状态 + async updateTaskStatus(taskId: string, status: string, error?: string) { + return await this.dbService.taskQueue.update({ + where: { id: taskId }, + data: { + status, + error, + attempts: { increment: 1 }, + }, + }); + } + + // 重试失败的任务 + async retryTask(taskId: string) { + const task = await this.dbService.taskQueue.findUnique({ + where: { id: taskId }, + }); + + if (task && task.status === 'failed') { + // 重置任务状态 + await this.dbService.taskQueue.update({ + where: { id: taskId }, + data: { + status: 'pending', + attempts: 0, + error: null, + }, + }); + + // 重新加入队列 + await this.taskQueue.add( + 'BATCH_CLONE_AUDIO', + { + ...JSON.parse(task.data), + taskId: task.id, + }, + { + removeOnComplete: true, + attempts: 3, + }, + ); + return true; + } + return false; + } +} diff --git a/src/common/RedisTask/RedisTaskProcessor.service.ts b/src/common/RedisTask/RedisTaskProcessor.service.ts new file mode 100644 index 0000000..034a171 --- /dev/null +++ b/src/common/RedisTask/RedisTaskProcessor.service.ts @@ -0,0 +1,69 @@ +import { Process, Processor } from '@nestjs/bull'; +import { Job } from 'bull'; +import { RedisTaskService } from './RedisTask.service'; +import { VolcenAudioSpeakService } from 'src/services/VolcenAudioSpeakService'; +import { CloneSpeakDto } from 'src/modules/SystemCharter/dto/CloneSpeakDto.dto'; +import { DBService } from 'src/utils/db/DB.service'; + +@Processor('task_queue') +export class RedisTaskProcessor { + constructor( + private readonly redisTaskService: RedisTaskService, + private readonly dbService: DBService, + ) {} + + @Process('BATCH_CLONE_AUDIO') + async handleSpecificTask(job: Job) { + let voiceId; + try { + const charterInfo = job.data as CloneSpeakDto; + const { taskId, url: ossUrl } = charterInfo; + if (taskId) { + await this.redisTaskService.updateTaskStatus(taskId, 'processing'); + } + console.log(job.data); + console.log(`开始处理任务 [第${job.attemptsMade + 1}次尝试]: ${job.data.roleName}`); + + const volcenAudioSpeakService = new VolcenAudioSpeakService(); + // voiceId = await volcenAudioSpeakService.getVoiceId(); + // const voiceId = 'S_FC60x0Gb1'; + const voiceId = 'S_VK2Yw0Gb1'; + // 请求ossurl获取base64 + const base64 = await volcenAudioSpeakService.getAudioBase64(ossUrl); + // 克隆音频 + volcenAudioSpeakService.speakClone(voiceId, base64); + // // 5秒后激活 + setTimeout(async () => { + if (taskId) { + await this.redisTaskService.updateTaskStatus(taskId, 'completed'); + // 激活音频 (激活后就不能克隆了,所以要克隆后确定后再激活) + // await volcenAudioSpeakService.speakActivate(voiceId); + const textToSpeechResult = await volcenAudioSpeakService.textToSpeech( + '今天有什么新鲜事吗?快给我讲讲', + voiceId, + ); + // 修改系统角色的 voiceId + await this.dbService.systemCharter.update({ + where: { id: charterInfo.roleId }, + data: { + voiceId, + voiceName: charterInfo.roleName, + // 是否激活 + activate: true, + originAudioUrl: ossUrl, + cloneAfterAudioUrl: textToSpeechResult.url, + }, + }); + } + console.log(`任务处理完成: ${job.data.roleName}`); + }, 1000 * 5); + } catch (error) { + console.log(error.data); + console.log('voiceId=--------------', voiceId); + console.error(`任务处理失败 [第${job.attemptsMade + 1}次尝试]: ${error.message}`); + if (job.data.taskId) { + await this.redisTaskService.updateTaskStatus(job.data.taskId, 'failed', error.message); + } + } + } +} diff --git a/src/modules/SystemCharter/SystemCharter.controller.ts b/src/modules/SystemCharter/SystemCharter.controller.ts index d28f526..d977968 100644 --- a/src/modules/SystemCharter/SystemCharter.controller.ts +++ b/src/modules/SystemCharter/SystemCharter.controller.ts @@ -3,11 +3,16 @@ import { SystemCharterlDto } from './dto/SystemCharter.dto'; import { Pagination } from 'src/common/pagination'; import { DBService } from 'src/utils/db/DB.service'; import { ApiResponse } from 'src/utils/response/response'; +import { RedisTaskService } from 'src/common/RedisTask/RedisTask.service'; +import { CloneSpeakDto } from './dto/CloneSpeakDto.dto'; +import axios from 'axios'; @Controller('/system/charter') export class SystemCharterController { - constructor(private readonly dbService: DBService) { } - + constructor( + private readonly dbService: DBService, + private readonly redisTaskService: RedisTaskService, + ) {} @Get('/getList') async getList(@Query() query: SystemCharterlDto) { @@ -52,4 +57,53 @@ export class SystemCharterController { }); return newRecord; } + + @Get('cloneSpeaker') + async batchCloneAudio(@Body() object: CloneSpeakDto) { + // try { + // if (!object.roleId || !object.roleName || !object.url) { + // return ApiResponse.failToMessage('参数错误'); + // } + // // 验证音频URL是否可访问 + // const response = await axios.head(object.url); + // if (response.status !== 200) { + // return ApiResponse.failToMessage('音频文件无法访问'); + // } + // // 验证文件类型 + // const contentType = response.headers['content-type']; + // if (!contentType.includes('audio')) { + // return ApiResponse.failToMessage('文件类型必须是音频'); + // } + // this.redisTaskService.addTask(object); + // return ApiResponse.success(null, '任务添加成功'); + // } catch (error) { + // console.error('添加克隆任务失败:', error); + // return ApiResponse.failToMessage('添加任务失败:' + error.message); + // } + } + + @Get('test') + async batchCloneAudio1() { + const result = [ + { + roleId: '6704bd0ef48326fe51ddb751', + roleName: '甘宁', + // url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E4%BB%A3%E5%8F%B7%E9%B8%A2%E5%AF%86%E6%8E%A2%E5%91%A8%E7%91%9C.mp3', + // url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E4%BB%A3%E5%8F%B7%E9%B8%A2%E5%AF%86%E6%8E%A2%E7%94%98%E5%AE%81.mp3', + // url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E4%BB%A3%E5%8F%B7%E9%B8%A2%E5%AF%86%E6%8E%A2%E7%94%98%E5%AE%81%20-%20%E5%89%AF%E6%9C%AC.wav', + // 郭德纲 + // url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E9%83%AD%E5%BE%B7%E7%BA%B2-%E5%A3%B0%E9%9F%B3%E5%85%8B%E9%9A%86.mp3', + // 增以后的 + url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/WeChat_20241119150807_1.mp3', + + // 周瑜 + // url: 'https://banban-systemcharter-speak.os-cn-beijing.aliyuncs.com/test/%E4%BB%A3%E5%8F%B7%E9%B8%A2%E5%AF%86%E6%8E%A2%E5%91%A8%E7%91%9C.mp3', + // 周瑜 提高分贝后 + // url: 'https://banban-systemcharter-speak.oss-cn-beijing.aliyuncs.com/test/%E5%91%A8%E7%91%9C.mp3', + }, + ]; + result.forEach((item) => { + this.redisTaskService.addTask(item); + }); + } } diff --git a/src/modules/SystemCharter/SystemCharter.module.ts b/src/modules/SystemCharter/SystemCharter.module.ts index d472879..7a60f2c 100644 --- a/src/modules/SystemCharter/SystemCharter.module.ts +++ b/src/modules/SystemCharter/SystemCharter.module.ts @@ -1,10 +1,21 @@ import { Module } from '@nestjs/common'; +import { BullModule } from '@nestjs/bull'; import { SystemCharterController } from './SystemCharter.controller'; import { SystemCharterService } from './SystemCharter.servicer'; +import { RedisTaskService } from 'src/common/RedisTask/RedisTask.service'; @Module({ - imports: [], + imports: [ + BullModule.registerQueue( + { + name: 'task_queue', + }, + { + name: 'dead_letter_queue', + }, + ), + ], controllers: [SystemCharterController], - providers: [SystemCharterService], + providers: [SystemCharterService, RedisTaskService], }) export class SystemCharterModule {} diff --git a/src/modules/SystemCharter/dto/CloneSpeakDto.dto.ts b/src/modules/SystemCharter/dto/CloneSpeakDto.dto.ts new file mode 100644 index 0000000..d44e357 --- /dev/null +++ b/src/modules/SystemCharter/dto/CloneSpeakDto.dto.ts @@ -0,0 +1,20 @@ +import { IsOptional, IsString } from 'class-validator'; + +export class CloneSpeakDto { + // 任务id + @IsString() + @IsOptional() + taskId?: string; + + // 角色id + @IsString() + roleId: string; + + // 角色名称 + @IsString() + roleName: string; + + // 音频url + @IsString() + url: string; +} diff --git a/src/services/TTSTiktokService.ts b/src/services/TTSTiktokService.ts new file mode 100644 index 0000000..fad45cf --- /dev/null +++ b/src/services/TTSTiktokService.ts @@ -0,0 +1,63 @@ +import 'dotenv/config'; +import { v4 as uuid } from 'uuid'; +import axios from 'axios'; + +export const TTSTiktokService = + (isCustom = false, backupVoiceName?: string) => + async (text: string, onComplete: (audioData: Buffer) => Promise, voiceName: string) => { + const body = { + app: { + appid: process.env.TiktokAppId, + token: 'default_token', + // cluster: "volcano_tts", + cluster: isCustom ? 'volcano_mega' : 'volcano_tts', + }, + user: { + uid: 'volcano_user', + }, + audio: { + voice_type: voiceName, + encoding: 'pcm', + emotion: 'happy', + language: 'cn', + rate: 16000, + }, + request: { + reqid: uuid(), + text: text, + text_type: 'plain', + operation: 'query', + pure_english_opt: '1', + }, + }; + + return new Promise((resolve, reject) => { + axios + .post(`https://openspeech.bytedance.com/api/v1/tts`, body, { + headers: { + Authorization: `Bearer;${process.env.TiktokAccessToken}`, + 'Content-Type': 'application/json', + }, + method: 'POST', + }) + .then(async (res) => { + const base64Data = res.data.data; + const buffer = Buffer.from(base64Data, 'base64'); + await onComplete(buffer); + resolve(true); + }) + .catch(async (e) => { + // 若是自定义语音出现问题,比如超过并发,则使用备用语音 + if (isCustom) { + try { + await TTSTiktokService(false)(text, onComplete, backupVoiceName!); + resolve(true); + } catch (e) { + reject(e); + } + } + console.log(e); + reject(e); + }); + }); + }; diff --git a/src/services/VolcenAudioSpeakService.ts b/src/services/VolcenAudioSpeakService.ts new file mode 100644 index 0000000..0a0c22b --- /dev/null +++ b/src/services/VolcenAudioSpeakService.ts @@ -0,0 +1,242 @@ +import axios from 'axios'; +import { Signer } from '@volcengine/openapi'; +import { pcmToWavArrayBuffer } from 'src/utils/pcmToWav'; +import AliOss, { OSSRegionType } from 'src/utils/aliOss'; +import { v4 as uuid } from 'uuid'; + +export type ReturnBaseType = { + BaseResp: { + StatusCode: number; + StatusMessage: string; + }; +}; + +/** + * 火山引擎语音服务 + */ +export class VolcenAudioSpeakService { + // 火山引擎base api地址 + static ENGIN_BASE_URL_API = 'https://open.volcengineapi.com/'; + // 训练声音 + static SPEAK_CLONE_API = 'https://openspeech.bytedance.com/api/v1/mega_tts/audio/upload'; + // TTS API + static TTS_API = 'https://openspeech.bytedance.com/api/v1/tts'; + + static TiktokAccessKeyId = 'AKLTMWNlY2Q1YzZlMTUwNDY2N2E3NTAyMmIyOWNjNjlhYWM'; + static TiktokAccessToken = '6UwsXXQWnVBhYKgYjp5DoPedwU3XDecn'; + static TiktokSecretKeyId = 'TlRVd05UVXlOalkzT0RFMk5EVTFORGsyWXpjNU5UZzBOak5pT0RKbU9EUQ=='; + static TiktokAppId = '8167092294'; + + /** + * @description 文本转语音 + * @param text 文本内容 + * @param speakerId 说话人ID + */ + public async textToSpeech(text: string, speakerId: string) { + const randomUUID = uuid(); + const ttsBody = { + app: { + appid: VolcenAudioSpeakService.TiktokAppId, + token: 'default_token', + cluster: 'volcano_mega', + // cluster: 'volcano_mega' : 'volcano_tts', + }, + user: { + uid: 'volcano_user', + }, + audio: { + voice_type: speakerId, + encoding: 'pcm', + emotion: 'happy', + language: 'cn', + rate: 16000, + }, + request: { + reqid: randomUUID, + text: text, + text_type: 'plain', + operation: 'query', + pure_english_opt: '1', + }, + }; + + const volenResult = await axios.post(VolcenAudioSpeakService.TTS_API, ttsBody, { + headers: { + 'Resource-Id': 'volc.megatts.tts', + Authorization: `Bearer;${VolcenAudioSpeakService.TiktokAccessToken}`, + }, + }); + + const buffer = Buffer.from(volenResult.data.data, 'base64'); + const fileName = `${speakerId}_${randomUUID}.wav`; + await AliOss('stayby-static', OSSRegionType.SH).put( + `custom-training-voice-example/${fileName}`, + Buffer.from(pcmToWavArrayBuffer(buffer)), + ); + const ossUrl = `https://stayby-static.oss-cn-shanghai.aliyuncs.com/custom-training-voice-example/${fileName}`; + return { + url: ossUrl, + speakerId, + }; + } + + /** + * @description 训练声音 + * @param speakerId + * @param base64 + */ + public async speakClone( + speakerId: string, + base64: string | Buffer, + ): Promise { + return new Promise(async (resolve, reject) => { + const tiktokBody = { + speaker_id: speakerId, + appid: VolcenAudioSpeakService.TiktokAppId, + audios: [ + { + audio_bytes: base64, + audio_format: 'wav', + // 添加音频参数要求 + // sample_rate: 16000, // 采样率必须是16kHz + // channels: 1, // 单声道 + // bits: 16, // 16位深度 + }, + ], + source: 2, + }; + // 开始克隆声音,参数: { speaker_id: 'S_FC60x0Gb1', appid: '8167092294', audio_format: 'wav' } + + console.log('开始克隆声音,参数:', { + speaker_id: speakerId, + appid: VolcenAudioSpeakService.TiktokAppId, + audio_format: 'wav', + }); + axios + .post(VolcenAudioSpeakService.SPEAK_CLONE_API, tiktokBody, { + headers: { + 'Resource-Id': 'volc.megatts.voiceclone', + Authorization: `Bearer;${VolcenAudioSpeakService.TiktokAccessToken}`, + 'Content-Type': 'application/json', + }, + }) + .then((result) => { + // 检查业务状态码 + if (result.data?.BaseResp?.StatusCode !== 0) { + console.error('克隆声音业务错误:', result.data); + throw new Error(`训练声音业务错误: ${result.data?.BaseResp?.StatusMessage || '未知错误'}`); + } + resolve(result.data as T); + }) + .catch((error) => { + reject(error); + }); + }); + } + + /** + * @description 激活声音 + * @param voiceId + */ + public async speakActivate(voiceId: string) { + const activatePost = { + region: 'cn-north-1', + method: 'POST', + params: { + Action: 'ActivateMegaTTSTrainStatus', + Version: '2023-11-07', + }, + headers: { + 'Content-Type': 'application/json', + }, + body: { + AppId: VolcenAudioSpeakService.TiktokAppId, + SpeakerIDs: [voiceId], + }, + }; + const signer = new Signer(activatePost, 'speech_saas_prod'); + + signer.addAuthorization({ + accessKeyId: VolcenAudioSpeakService.TiktokAccessKeyId, + secretKey: VolcenAudioSpeakService.TiktokSecretKeyId, + }); + // 激活 + const activateVoiceResult = await axios.post( + VolcenAudioSpeakService.ENGIN_BASE_URL_API + '?Action=ActivateMegaTTSTrainStatus&Version=2023-11-07', + activatePost.body, + { + headers: activatePost.headers, + }, + ); + + const hasCurrentSpeakId = activateVoiceResult.data?.Result.Statuses.find((item: any) => item.SpeakerID === voiceId); + return hasCurrentSpeakId; + } + + /** + * 获取speakId + */ + public async getVoiceId() { + const query = { + region: 'cn-north-1', + method: 'POST', + params: { + Action: 'ListMegaTTSTrainStatus', + Version: '2023-11-07', + }, + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + body: { + AppId: VolcenAudioSpeakService.TiktokAppId, + }, + }; + + const signer = new Signer(query, 'speech_saas_prod'); + signer.addAuthorization({ + accessKeyId: VolcenAudioSpeakService.TiktokAccessKeyId, + secretKey: VolcenAudioSpeakService.TiktokSecretKeyId, + }); + const megaListResult = await axios.post( + VolcenAudioSpeakService.ENGIN_BASE_URL_API + `?Action=ListMegaTTSTrainStatus&Version=2023-11-07`, + query.body, + { + headers: query.headers, + }, + ); + // 获取未激活的音色 + const unknownStatusItem = megaListResult.data.Result.Statuses.find((item: any) => item.State === 'Unknown'); + return unknownStatusItem.SpeakerID; + } + + /** + * @description 获取音频base64 + * @param ossUrl OSS文件URL + */ + public async getAudioBase64(ossUrl: string): Promise { + try { + const response = await axios.get(ossUrl, { + responseType: 'arraybuffer', + }); + + // 确保音频数据符合要求:16kHz采样率,单声道,16位深度的WAV格式 + const audioBuffer = Buffer.from(response.data); + const wavBuffer = await this.convertToRequiredFormat(audioBuffer); + return wavBuffer.toString('base64'); + } catch (error) { + console.error('获取音频base64失败:', error); + throw new Error(`获取音频base64失败: ${error.message}`); + } + } + + /** + * 将音频转换为所需格式 + */ + private async convertToRequiredFormat(audioBuffer: Buffer): Promise { + // 使用pcmToWavArrayBuffer进行格式转换 + // 确保输出的WAV文件符合:16kHz采样率,单声道,16位深度 + const wavArrayBuffer = pcmToWavArrayBuffer(audioBuffer); + + return Buffer.from(wavArrayBuffer); + } +} diff --git a/src/utils/aliOss.ts b/src/utils/aliOss.ts new file mode 100644 index 0000000..ad20736 --- /dev/null +++ b/src/utils/aliOss.ts @@ -0,0 +1,20 @@ +import * as aliOss from 'ali-oss'; + +const defaultBucket = 'stayby-static-fast'; + +export enum OSSRegionType { + BJ = 'oss-cn-beijing', + SH = 'oss-cn-shanghai', +} + +const AliOss = (bucket = defaultBucket, region = OSSRegionType.SH) => { + return new aliOss({ + region, + bucket: bucket, + accessKeyId: 'LTAI5tEday8PJNaMTz5mp8g4', + accessKeySecret: 'ck84eTxx4aSTjornlYrCy8RkurCHfc', + secure: true, + }); +}; + +export default AliOss; diff --git a/src/utils/pcmToWav.ts b/src/utils/pcmToWav.ts new file mode 100644 index 0000000..fab9b2d --- /dev/null +++ b/src/utils/pcmToWav.ts @@ -0,0 +1,74 @@ +// const pcmToWavArrayBufferbu = (pcmData: ArrayBuffer) => { +// // 添加44字节的wav文件头 +// const pcmHeadString = "52 49 46 46 24 5C 02 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 01 00 80 3e 00 00 00 7d 00 00 02 00 10 00 64 61 74 61 00 5C 02 00"; +// const pcmHeadArray = pcmHeadString.split(" "); +// const pcmHead = new Uint8Array(pcmHeadArray.length); +// for (let i = 0; i < pcmHeadArray.length; i++) { +// pcmHead[i] = parseInt(pcmHeadArray[i]!, 16); +// } +// let wavData = new Uint8Array(pcmData.byteLength + pcmHead.byteLength); +// wavData.set(pcmHead, 0); +// wavData.set(new Uint8Array(pcmData), pcmHead.byteLength); +// return wavData.buffer; +// } + +const pcmToWavArrayBuffer = (pcmData: ArrayBuffer) => { + const sampleRate = 16000; + const numChannels = 1; + const bitdepth = 16; + // const numFrames = pcmData.byteLength / (bitdepth / 8); + const wavData = new ArrayBuffer(44 + pcmData.byteLength); + const view = new DataView(wavData); + const writeString = (view: DataView, offset: number, str: string) => { + for (let i = 0; i < str.length; i++) { + view.setUint8(offset + i, str.charCodeAt(i)); + } + }; + + const writeInt32 = (view: DataView, offset: number, value: number) => { + view.setUint32(offset, value, true); + }; + const writeInt16 = (view: DataView, offset: number, value: number) => { + view.setUint16(offset, value, true); + }; + /* RIFF identifier */ + writeString(view, 0, 'RIFF'); + /* file length */ + writeInt32(view, 4, 36 + pcmData.byteLength); + /* RIFF type */ + writeString(view, 8, 'WAVE'); + /* format chunk identifier */ + writeString(view, 12, 'fmt '); + /* format chunk length */ + writeInt32(view, 16, 16); + /* sample format (raw) */ + writeInt16(view, 20, 1); + /* channel count */ + writeInt16(view, 22, numChannels); + /* sample rate */ + writeInt32(view, 24, sampleRate); + /* byte rate (sample rate * block align) */ + writeInt32(view, 28, sampleRate * 4); + /* block align (channel count * bytes per sample) */ + writeInt16(view, 32, numChannels * 2); + /* bits per sample */ + writeInt16(view, 34, 16); + /* data chunk identifier */ + writeString(view, 36, 'data'); + /* data chunk length */ + writeInt32(view, 40, pcmData.byteLength); + + // 将wavData转成UInt8Array,然后将pcmData的内容拼接到wavData后面 + const finalData = new Uint8Array(44 + pcmData.byteLength); + finalData.set(new Uint8Array(view.buffer), 0); + finalData.set(new Uint8Array(pcmData), 44); + return finalData.buffer; +}; + +const wavToPcmArrayBuffer = (wavData: ArrayBuffer) => { + // 把wav文件头去掉即可成为pcm文件 + const pcmData = wavData.slice(44); + return pcmData; +}; + +export { pcmToWavArrayBuffer, wavToPcmArrayBuffer }; diff --git a/tmp/1733134286856.mp3 b/tmp/1733134286856.mp3 new file mode 100644 index 0000000..b1e136f Binary files /dev/null and b/tmp/1733134286856.mp3 differ diff --git a/tmp/1733134288350.mp3 b/tmp/1733134288350.mp3 new file mode 100644 index 0000000..b1e136f Binary files /dev/null and b/tmp/1733134288350.mp3 differ diff --git a/tmp/1733134289352.mp3 b/tmp/1733134289352.mp3 new file mode 100644 index 0000000..b1e136f Binary files /dev/null and b/tmp/1733134289352.mp3 differ