From 387c2eb874608f7c0cc9af3684b4f8fa977d033f Mon Sep 17 00:00:00 2001 From: Ben Allfree Date: Fri, 20 Oct 2023 17:44:15 -0700 Subject: [PATCH] enh: decouple version downloading into separate cli --- packages/daemon/package.json | 1 + packages/daemon/src/cli/download.ts | 26 ++++ packages/daemon/src/server.ts | 4 +- .../src/services/PocketBaseService/index.ts | 7 +- .../index.ts | 54 +++------ .../PocketbaseReleaseVersionService/index.ts | 77 ++++++++++++ .../src/services/RpcService/commands.ts | 10 +- yarn.lock | 111 +++++++++++++++--- 8 files changed, 220 insertions(+), 70 deletions(-) create mode 100644 packages/daemon/src/cli/download.ts rename packages/daemon/src/services/{UpdaterService => PocketbaseReleaseDownloadService}/index.ts (60%) create mode 100644 packages/daemon/src/services/PocketbaseReleaseVersionService/index.ts diff --git a/packages/daemon/package.json b/packages/daemon/package.json index 129609ab..b06dd719 100644 --- a/packages/daemon/package.json +++ b/packages/daemon/package.json @@ -34,6 +34,7 @@ "exit-hook": "^4.0.0", "ftp-srv": "^4.6.2", "get-port": "^6.1.2", + "glob": "^10.3.10", "http-proxy": "^1.18.1", "ip-cidr": "^3.1.0", "knex": "^2.3.0", diff --git a/packages/daemon/src/cli/download.ts b/packages/daemon/src/cli/download.ts new file mode 100644 index 00000000..23ca100b --- /dev/null +++ b/packages/daemon/src/cli/download.ts @@ -0,0 +1,26 @@ +import { PH_BIN_CACHE, PUBLIC_DEBUG, TRACE } from '$constants' +import { PocketbaseReleaseDownloadService } from '$services' +import { LoggerService } from '@pockethost/common' +// gen:import + +const [major, minor, patch] = process.versions.node.split('.').map(Number) + +if ((major || 0) < 18) { + throw new Error(`Node 18 or higher required.`) +} + +LoggerService({ debug: PUBLIC_DEBUG, trace: TRACE, errorTrace: !PUBLIC_DEBUG }) + +// npm install eventsource --save +// @ts-ignore +global.EventSource = require('eventsource') +;(async () => { + const logger = LoggerService().create(`mothership.ts`) + const { dbg, error, info, warn } = logger + info(`Starting`) + + const { check } = PocketbaseReleaseDownloadService({ + cachePath: PH_BIN_CACHE, + }) + await check() +})() diff --git a/packages/daemon/src/server.ts b/packages/daemon/src/server.ts index bc44f1e5..6244510a 100644 --- a/packages/daemon/src/server.ts +++ b/packages/daemon/src/server.ts @@ -9,6 +9,7 @@ import { TRACE, } from '$constants' import { + PocketbaseReleaseVersionService, centralDbService, clientService, ftpService, @@ -19,7 +20,6 @@ import { realtimeLog, rpcService, sqliteService, - updaterService, } from '$services' import { LoggerService } from '@pockethost/common' // gen:import @@ -40,7 +40,7 @@ global.EventSource = require('eventsource') const { dbg, error, info, warn } = logger info(`Starting`) - const udService = await updaterService({ + const udService = await PocketbaseReleaseVersionService({ cachePath: PH_BIN_CACHE, checkIntervalMs: 1000 * 5 * 60, }) diff --git a/packages/daemon/src/services/PocketBaseService/index.ts b/packages/daemon/src/services/PocketBaseService/index.ts index 0695ed9e..5e467293 100644 --- a/packages/daemon/src/services/PocketBaseService/index.ts +++ b/packages/daemon/src/services/PocketBaseService/index.ts @@ -4,7 +4,7 @@ import { mkInstanceDataPath, PUBLIC_DEBUG, } from '$constants' -import { port as getPort, InstanceLogger, updaterService } from '$services' +import { port as getPort, InstanceLogger } from '$services' import { assert, AsyncContext, @@ -27,6 +27,7 @@ import MemoryStream from 'memorystream' import { dirname } from 'path' import { gte } from 'semver' import { AsyncReturnType } from 'type-fest' +import { PocketbaseReleaseVersionService } from '../PocketbaseReleaseVersionService' export type PocketbaseCommand = 'serve' | 'migrate' export type Env = { [_: string]: string } @@ -60,7 +61,8 @@ export const createPocketbaseService = async ( const _serviceLogger = LoggerService().create('PocketbaseService') const { dbg, error, warn, abort } = _serviceLogger - const { getLatestVersion, getVersion } = await updaterService() + const { getLatestVersion, getVersion } = + await PocketbaseReleaseVersionService() const maxVersion = getLatestVersion() const tm = createTimerManager({}) @@ -231,7 +233,6 @@ export const createPocketbaseService = async ( if (command === 'serve') { await tryFetch(url, { preflight: async () => isRunning, - logger: _serviceLogger, }) } const unsub = asyncExitHook(async () => { diff --git a/packages/daemon/src/services/UpdaterService/index.ts b/packages/daemon/src/services/PocketbaseReleaseDownloadService/index.ts similarity index 60% rename from packages/daemon/src/services/UpdaterService/index.ts rename to packages/daemon/src/services/PocketbaseReleaseDownloadService/index.ts index 98090b44..6c3f238a 100644 --- a/packages/daemon/src/services/UpdaterService/index.ts +++ b/packages/daemon/src/services/PocketbaseReleaseDownloadService/index.ts @@ -2,16 +2,14 @@ import { downloadAndExtract, smartFetch } from '$util' import { LoggerService, SingletonBaseConfig, - createCleanupManager, - createTimerManager, mkSingleton, } from '@pockethost/common' import { keys } from '@s-libs/micro-dash' import { chmodSync, existsSync } from 'fs' import { join } from 'path' -import { maxSatisfying, rsort } from 'semver' +import { rsort } from 'semver' -export type Release = { +type Release = { tag_name: string prerelease: string assets: { @@ -19,24 +17,22 @@ export type Release = { browser_download_url: string }[] } -export type Releases = Release[] +type Releases = Release[] -export type UpdaterServiceConfig = SingletonBaseConfig & { +export type PocketbaseReleaseDownloadServiceConfig = SingletonBaseConfig & { cachePath: string - checkIntervalMs: number } -export const updaterService = mkSingleton( - async (config: UpdaterServiceConfig) => { - const _serviceLogger = LoggerService().create('UpdaterService') - const { dbg, error, warn, abort } = _serviceLogger +export const PocketbaseReleaseDownloadService = mkSingleton( + (config: PocketbaseReleaseDownloadServiceConfig) => { + const _serviceLogger = LoggerService().create( + 'PocketbaseReleaseDownloadService', + ) + const { dbg, info, error, warn, abort } = _serviceLogger - dbg(`Initializing UpdaterService`) + dbg(`Initializing`) - const { cachePath, checkIntervalMs } = config - - const cm = createCleanupManager() - const tm = createTimerManager({}) + const { cachePath } = config const osName = 'linux' // type().toLowerCase() const cpuArchitecture = process.arch === 'x64' ? 'amd64' : process.arch @@ -80,33 +76,11 @@ export const updaterService = mkSingleton( ) } maxVersion = `~${rsort(keys(binPaths))[0]}` - dbg({ maxVersion }) - return true - } - await check().catch(abort) - - tm.repeat(check, checkIntervalMs) - - const getLatestVersion = () => maxVersion - - const getVersion = async (semVer = maxVersion) => { - const version = maxSatisfying(keys(binPaths), semVer) - if (!version) - throw new Error( - `No version satisfies ${semVer} (${keys(binPaths).join(', ')})`, - ) - const binPath = binPaths[version] - if (!binPath) throw new Error(`binPath for ${version} not found`) - return { - version, - binPath, - } + info(`Highest PocketBase version is ${maxVersion}`) } return { - getLatestVersion, - getVersion, - shutdown: async () => {}, + check, } }, ) diff --git a/packages/daemon/src/services/PocketbaseReleaseVersionService/index.ts b/packages/daemon/src/services/PocketbaseReleaseVersionService/index.ts new file mode 100644 index 00000000..8ef6378f --- /dev/null +++ b/packages/daemon/src/services/PocketbaseReleaseVersionService/index.ts @@ -0,0 +1,77 @@ +import { + createTimerManager, + LoggerService, + mkSingleton, + SingletonBaseConfig, +} from '@pockethost/common' +import { keys } from '@s-libs/micro-dash' +import { chmodSync, existsSync } from 'fs' +import { glob } from 'glob' +import { basename, join } from 'path' +import { maxSatisfying, rsort } from 'semver' + +export type PocketbaseReleaseVersionService = SingletonBaseConfig & { + cachePath: string + checkIntervalMs: number +} + +export const PocketbaseReleaseVersionService = mkSingleton( + async (config: PocketbaseReleaseVersionService) => { + const _serviceLogger = LoggerService().create( + 'PocketbaseReleaseVersionService', + ) + const { dbg, error, warn, abort } = _serviceLogger + + dbg(`Initializing`) + + const { cachePath, checkIntervalMs } = config + + const binPaths: { [_: string]: string } = {} + let maxVersion = '' + + const tm = createTimerManager() + + const check = async () => { + const versions = await glob(join(cachePath, `v*/`)) + versions.forEach((path) => { + const version = basename(path) + const sanitizedTagName = version.slice(1) + dbg(`Found a version ${sanitizedTagName}`) + + const binPath = join(path, `pocketbase`) + dbg(`Checking ${binPath}`) + + if (existsSync(binPath)) { + chmodSync(binPath, 0o775) + } + binPaths[sanitizedTagName] = binPath + }) + maxVersion = `~${rsort(keys(binPaths))[0]}` + dbg({ maxVersion }) + return true + } + await check().catch(error) + tm.repeat(check, checkIntervalMs, false) + + const getLatestVersion = () => maxVersion + + const getVersion = (semVer = maxVersion) => { + const version = maxSatisfying(keys(binPaths), semVer) + if (!version) + throw new Error( + `No version satisfies ${semVer} (${keys(binPaths).join(', ')})`, + ) + const binPath = binPaths[version] + if (!binPath) throw new Error(`binPath for ${version} not found`) + return { + version, + binPath, + } + } + + return { + getLatestVersion, + getVersion, + } + }, +) diff --git a/packages/daemon/src/services/RpcService/commands.ts b/packages/daemon/src/services/RpcService/commands.ts index 39734b2a..3bdb9ac2 100644 --- a/packages/daemon/src/services/RpcService/commands.ts +++ b/packages/daemon/src/services/RpcService/commands.ts @@ -1,9 +1,4 @@ -import { - clientService, - instanceService, - rpcService, - updaterService, -} from '$services' +import { clientService, instanceService, rpcService } from '$services' import { CreateInstancePayload, CreateInstancePayloadSchema, @@ -26,6 +21,7 @@ import { type SetInstanceMaintenanceResult, } from '@pockethost/common' import { valid, validRange } from 'semver' +import { PocketbaseReleaseVersionService } from '../PocketbaseReleaseVersionService' export const registerRpcCommands = async (logger: Logger) => { const { client } = await clientService() @@ -43,7 +39,7 @@ export const registerRpcCommands = async (logger: Logger) => { const instance = await client.createInstance({ subdomain, uid: rpc.userId, - version: (await updaterService()).getLatestVersion(), + version: (await PocketbaseReleaseVersionService()).getLatestVersion(), status: InstanceStatus.Idle, secondsThisMonth: 0, secrets: {}, diff --git a/yarn.lock b/yarn.lock index 48c609cf..eadc5f4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -353,6 +353,18 @@ resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + 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" + "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" @@ -465,6 +477,11 @@ mkdirp "^1.0.4" rimraf "^3.0.2" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" @@ -1921,7 +1938,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2962,6 +2979,14 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + form-data-encoder@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" @@ -3201,6 +3226,17 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.3.10: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" @@ -3880,6 +3916,15 @@ iso-639-1@^2.1.15: resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.15.tgz#20cf78a4f691aeb802c16f17a6bad7d99271e85d" integrity sha512-7c7mBznZu2ktfvyT582E2msM+Udc1EjOyhVRE/0ZsjD9LBtWSm23h3PtiRh2a35XoUsTQQjJXaJzuLjXsOdFDg== +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -4189,6 +4234,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== + luxon@^3.3.0: version "3.4.3" resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.3.tgz#8ddf0358a9492267ffec6a13675fbaab5551315d" @@ -4383,6 +4433,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -4434,6 +4491,11 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: dependencies: yallist "^4.0.0" +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -5013,6 +5075,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" @@ -5875,6 +5945,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -6092,7 +6167,7 @@ streamx@^2.15.0: fast-fifo "^1.1.0" queue-tick "^1.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6142,6 +6217,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -6149,13 +6231,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -6916,6 +6991,15 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -6934,15 +7018,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"