diff --git a/packages/api/README.md b/packages/api/README.md index 288ba1ef85..accb716833 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -136,3 +136,55 @@ We use [pickup](https://github.com/web3-storage/pickup) to fetch DAGs from IPFS - `PICKUP_BASIC_AUTH_TOKEN` must be set as a secret in the env. For local dev, we use a local ipfs-cluster container for the same service. + +## w3up + +Some uploads sent to nft.storage/api will be sent to up.web3.storage (aka 'w3up') for storage, serving on IPFS, and persistence to filecoin. + +All uploads sent to w3up will be stored in the same web3.storage space configured by env var `W3_NFTSTORAGE_SPACE`. + +### using console.web3.storage to browse uploads to w3up + +You can use console.web3.storage to browse uploads in the W3_NFTSTORAGE_SPACE. + +The DID used by your console.web3.storage session will need to be authorized to access the space. + +The credentials used in staging/production are in the usual vault of secrets under 'w3up credentials'. + +Run the cli command `w3up console ucan generate` + +```shell +( + cd packages/api + node scripts/cli.js w3up console ucan generate +) +``` + +If you see a prompt like "ID of subject that should be authorized": + +- you need to enter the ID of your console.web3.storage session. To get this, visit https://console.web3.storage/space/import. Look for "Send your DID to your friend". After that is a URI starting with `did:`. Copy that and enter it in the prompt. + +If you see a prompt like "space recovery key mnemonic": + +- look in the secrets vault for the mnemonic phrase labeled "Space Recovery Key". Copy that value into the prompt. + +If you see a prompt like "What name do you want to appear in console.web3.storage when this space is +imported?": + +- enter whatever name you want that will help you distinguish this space from other spaces listed in console.web3.storage. + +If you see a prompt like "output ucan car to file /tmp/nftstorage-w3up-1712101390513.ucan.car?" + +- hit enter or type 'Y' to confirm + +Now a UCAN delegation has been written to a CAR file at a path like `/tmp/nftstorage-w3up-1712101390513.ucan.car`. + +To add this delegation to console.web3.storage: + +1. use a web browser to access https://console.web3.storage/space/import +2. Click 'Import UCAN'. This should open a file picker +3. Select the file generated from the last script, e.g. `/tmp/nftstorage-w3up-1712101390513.ucan.car` + +You should see 'Added' and a list containing the space with the name you chose when generating the UCAN CAR. Click 'View' to view the contents of the Space. + +After importing the space, it will also be listed in the space listing at https://console.web3.storage/. diff --git a/packages/api/package.json b/packages/api/package.json index 402d75653c..6f346ffffa 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -11,6 +11,7 @@ "dev": "miniflare dist/worker.js --watch --debug --env ../../.env", "dev:persist": "PERSIST_VOLUMES=true npm run dev", "build": "scripts/cli.js build", + "w3up:console:ucan:generate": "scripts/cli.js w3up console ucan generate", "pretest": "tsc", "test": "./docker/run-with-dependencies.sh ./scripts/run-test.sh", "db-types": "./scripts/cli.js db-types" @@ -50,6 +51,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^3.17.0", + "@inquirer/prompts": "^4.3.1", "@miniflare/core": "^2.10.0", "@sentry/cli": "^1.71.0", "@sentry/webpack-plugin": "^1.16.0", diff --git a/packages/api/scripts/cli.js b/packages/api/scripts/cli.js index 045fc204e4..d8927d3410 100755 --- a/packages/api/scripts/cli.js +++ b/packages/api/scripts/cli.js @@ -17,6 +17,7 @@ import { import { dbSqlCmd } from './cmds/db-sql.js' import { dbTypesCmd } from './cmds/db-types.js' import { minioBucketCreateCmd, minioBucketRemoveCmd } from './cmds/minio.js' +import { requestW3upConsoleUcan } from './cmds/w3up-console-ucan-request.js' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const require = createRequire(__dirname) @@ -136,4 +137,10 @@ prog .describe('Remove a bucket, automatically removing all contents') .action(minioBucketRemoveCmd) + .command('w3up console ucan generate') + .describe( + 'request info to build and output a UCAN that can be imported into console.web3.storage to browse data nft.storage stores with w3up' + ) + .action(requestW3upConsoleUcan) + prog.parse(process.argv) diff --git a/packages/api/scripts/cmds/w3up-console-ucan-request.js b/packages/api/scripts/cmds/w3up-console-ucan-request.js new file mode 100644 index 0000000000..cf963c776c --- /dev/null +++ b/packages/api/scripts/cmds/w3up-console-ucan-request.js @@ -0,0 +1,150 @@ +import { input, confirm } from '@inquirer/prompts' +import { DID } from '@ucanto/core/schema' +import * as Space from '@web3-storage/access/space' +import * as fsp from 'node:fs/promises' +import { CarWriter } from '@ipld/car/writer' + +export async function requestW3upConsoleUcan() { + console.log('requestW3upConsoleUcan') + + /* + We're going to get everything we need to build a UCAN + that authorizes a session (e.g. a console.web3.storage agent) to + do w3up stuff in some space. + */ + + // subject of the authorization, + // e.g. a DID of a console.web3.storage session + /** @type {`did:${string}:${string}` | undefined} */ + let subjectId + { + // if env var W3UP_UCAN_SUBJECT is set, + // parse as DID and use as subjectId + let subjectIdFromEnv + if ((subjectIdFromEnv = process.env.W3UP_UCAN_SUBJECT)) { + const did = DID.read(subjectIdFromEnv).ok + if (!did) + throw new Error( + `failed to parse W3UP_UCAN_SUBJECT env var as DID: ${subjectIdFromEnv}` + ) + if ( + await confirm({ + message: `use W3UP_UCAN_SUBJECT env var value as authorization subject? ${did}`, + }) + ) { + subjectId = did + } else { + console.warn('will not use value of W3UP_UCAN_SUBJECT env var') + } + } else { + const subjectIdFromPrompt = await input({ + message: + 'ID of subject that should be authorized. e.g. you can copy the DID of your console session from https://console.web3.storage/space/import', + }) + const subjectIdDid = DID.read(subjectIdFromPrompt).ok + if (subjectIdDid) { + subjectId = subjectIdDid + } else { + throw new Error(`Failed to parse as DID: ${subjectIdFromPrompt}`) + } + } + } + // now we should have a subjectId + const subjectPrincipal = { + did() { + if (!subjectId) throw new Error(`failed to determine subject of ucan`) + return subjectId + }, + } + + /** + * Issuer of the authorization. + * e.g. ultimately the issuer must have authority rooted in the space itself, + * so this issuer may be the space ID. + * @type {Space.OwnedSpace | undefined} + */ + let space + + // if W3UP_SPACE_RECOVERY is set and user confirms, build issuer of UCANs from it + let spaceRecoveryMnemonic + if (process.env.W3UP_SPACE_RECOVERY) { + if ( + await confirm({ + message: `issue ucan using space from env var W3UP_SPACE_RECOVERY?`, + }) + ) { + spaceRecoveryMnemonic = process.env.W3UP_SPACE_RECOVERY + } else { + console.warn(`will not use env var W3UP_SPACE_RECOVERY`) + } + } + // if no spaceRecoveryKey from env var, prompt for a recovery key + if (!spaceRecoveryMnemonic) { + spaceRecoveryMnemonic = await input({ + message: 'space recovery key mnemonic', + }) + } + + /** + * name that should appear for this space in console.web3.storage. + * @type {string} + */ + let nameForSpaceInConsole = await input({ + message: `What name do you want to appear in console.web3.storage when this space is imported? (e.g. 'staging.nft.storage NFTs')`, + default: `nftstorage-${Date.now()}`, + }) + + space = await Space.fromMnemonic(spaceRecoveryMnemonic, { + name: nameForSpaceInConsole, + }) + + // We now have a space object + if (!space) + throw new Error(`unable to build a space object from inputs: ${space}`) + console.warn('space', space.did()) + + // now let's have the space sign a UCAN that authorizes the subject + // to access the space + const authorizationForSubjectToAccessSpace = await space.createAuthorization( + subjectPrincipal + ) + + const exportedUcan = await toCarBlob(authorizationForSubjectToAccessSpace) + + // we want to save to a file + const outputPath = `/tmp/nftstorage-w3up-${Date.now()}.ucan.car` + if (await confirm({ message: `output ucan car to file ${outputPath}?` })) { + await fsp.writeFile(outputPath, exportedUcan.stream()) + console.warn(`wrote`, outputPath) + console.warn( + `When this delegation is imported into console.web3.storage, the space will be shown with the name "${nameForSpaceInConsole}"` + ) + } else { + console.warn(`did not output ucan to file because no confirmation`) + } +} + +/** + * given a UCAN delegation, return a Blob of the serialized delegation. + * It's serialized to a CAR file in a way where console.web3.storage import will accept it + * when imported via https://github.com/web3-storage/console/blob/main/src/share.tsx#L138 + * @param {import('@ucanto/interface').Delegation} delegation + * @returns {Promise} + */ +export async function toCarBlob(delegation) { + const { writer, out } = CarWriter.create() + for (const block of delegation.export()) { + // @ts-expect-error slight Block type mismatch + void writer.put(block) + } + void writer.close() + + const carParts = [] + for await (const chunk of out) { + carParts.push(chunk) + } + const car = new Blob(carParts, { + type: 'application/vnd.ipld.car', + }) + return car +} diff --git a/yarn.lock b/yarn.lock index 28972d644f..576992b0dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2397,6 +2397,119 @@ resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== +"@inquirer/checkbox@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-2.2.1.tgz#100fcade0209a9b5eaef80403e06130401a0b438" + integrity sha512-eYdhZWZMOaliMBPOL/AO3uId58lp+zMyrJdoZ2xw9hfUY4IYJlIMvgW80RJdvCY3q9fGMUyZI5GwguH2tO51ew== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + figures "^3.2.0" + +"@inquirer/confirm@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.1.1.tgz#e17c9eafa3d8f494fad3f848ba1e4c61d0a7ddcf" + integrity sha512-epf2RVHJJxX5qF85U41PBq9qq2KTJW9sKNLx6+bb2/i2rjXgeoHVGUm8kJxZHavrESgXgBLKCABcfOJYIso8cQ== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + +"@inquirer/core@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-7.1.1.tgz#9339095720c00cfd1f85943977ae15d2f66f336a" + integrity sha512-rD1UI3eARN9qJBcLRXPOaZu++Bg+xsk0Tuz1EUOXEW+UbYif1sGjr0Tw7lKejHzKD9IbXE1CEtZ+xR/DrNlQGQ== + dependencies: + "@inquirer/type" "^1.2.1" + "@types/mute-stream" "^0.0.4" + "@types/node" "^20.11.30" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + cli-spinners "^2.9.2" + cli-width "^4.1.0" + figures "^3.2.0" + mute-stream "^1.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + +"@inquirer/editor@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-2.1.1.tgz#e2d50246fd7dd4b4c2f20b86c969912be4c36899" + integrity sha512-SGVAmSKY2tt62+5KUySYFeMwJEXX866Ws5MyjwbrbB+WqC8iZAtPcK0pz8KVsO0ak/DB3/vCZw0k2nl7TifV5g== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + external-editor "^3.1.0" + +"@inquirer/expand@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-2.1.1.tgz#5364c5ddf0fb6358c5610103efde6a4aa366c2fe" + integrity sha512-FTHf56CgE24CtweB+3sF4mOFa6Q7H8NfTO+SvYio3CgQwhIWylSNueEeJ7sYBnWaXHNUfiX883akgvSbWqSBoQ== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + chalk "^4.1.2" + +"@inquirer/input@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-2.1.1.tgz#a293a1d1bef103a1f4176d5b41df6d3272b7b48f" + integrity sha512-Ag5PDh3/V3B68WGD/5LKXDqbdWKlF7zyfPAlstzu0NoZcZGBbZFjfgXlZIcb6Gs+AfdSi7wNf7soVAaMGH7moQ== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + +"@inquirer/password@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-2.1.1.tgz#9465dc1afa28bc75de2ee5fdb18852a25b2fe00e" + integrity sha512-R5R6NVXDKXEjAOGBqgRGrchFlfdZIx/qiDvH63m1u1NQVOQFUMfHth9VzVwuTZ2LHzbb9UrYpBumh2YytFE9iQ== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + ansi-escapes "^4.3.2" + +"@inquirer/prompts@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-4.3.1.tgz#f2906a5d7b4c2c8af9bd5bd8d495466bdd52f411" + integrity sha512-FI8jhVm3GRJ/z40qf7YZnSP0TfPKDPdIYZT9W6hmiYuaSmAXL66YMXqonKyysE5DwtKQBhIqt0oSoTKp7FCvQQ== + dependencies: + "@inquirer/checkbox" "^2.2.1" + "@inquirer/confirm" "^3.1.1" + "@inquirer/core" "^7.1.1" + "@inquirer/editor" "^2.1.1" + "@inquirer/expand" "^2.1.1" + "@inquirer/input" "^2.1.1" + "@inquirer/password" "^2.1.1" + "@inquirer/rawlist" "^2.1.1" + "@inquirer/select" "^2.2.1" + +"@inquirer/rawlist@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-2.1.1.tgz#07ba2f9c4185e3787954e4023ae16d1a44d6da92" + integrity sha512-PIpJdNqVhjnl2bDz8iUKqMmgGdspN4s7EZiuNPnNrqZLP+LRUDDHVyd7X7xjiEMulBt3lt2id4SjTbra+v/Ajg== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + chalk "^4.1.2" + +"@inquirer/select@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-2.2.1.tgz#cd1f8b7869a74ff7f409a01f27998d06e234ea98" + integrity sha512-JR4FeHvuxPSPWQy8DzkIvoIsJ4SWtSFb4xVLvLto84dL+jkv12lm8ILtuax4bMHvg5MBj3wYUF6Tk9izJ07gdw== + dependencies: + "@inquirer/core" "^7.1.1" + "@inquirer/type" "^1.2.1" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + figures "^3.2.0" + +"@inquirer/type@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.2.1.tgz#fbc7ab3a2e5050d0c150642d5e8f5e88faa066b8" + integrity sha512-xwMfkPAxeo8Ji/IxfUSqzRi0/+F2GIqJmpc5/thelgMGsjNZcjDDRBO9TLXT1s/hdx/mK5QbVIvgoLIFgXhTMQ== + "@ipld/car@^3.0.1", "@ipld/car@^3.1.20", "@ipld/car@^3.2.3": version "3.2.4" resolved "https://registry.yarnpkg.com/@ipld/car/-/car-3.2.4.tgz#115951ba2255ec51d865773a074e422c169fb01c" @@ -4952,6 +5065,13 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + "@types/node-fetch@^2.5.7": version "2.6.2" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" @@ -4980,6 +5100,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== +"@types/node@^20.11.30": + version "20.12.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.3.tgz#d6658c2c7776c1cad93534bb45428195ed840c65" + integrity sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw== + dependencies: + undici-types "~5.26.4" + "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" @@ -5207,6 +5334,11 @@ anymatch "^3.0.0" source-map "^0.6.0" +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -6118,7 +6250,7 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -7863,6 +7995,11 @@ cli-spinners@^2.5.0, cli-spinners@^2.6.1: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== +cli-spinners@^2.9.2: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + cli-table3@^0.6.1: version "0.6.2" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a" @@ -7893,6 +8030,11 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + clipboardy@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.2.tgz#2ce320b9ed9be1514f79878b53ff9765420903e2" @@ -10718,7 +10860,7 @@ extend@^3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: +external-editor@^3.0.3, external-editor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== @@ -10876,7 +11018,7 @@ figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== -figures@^3.0.0: +figures@^3.0.0, figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -15992,6 +16134,11 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mute-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + nan@^2.12.1: version "2.16.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" @@ -18071,11 +18218,16 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@2.5.1, "prettier@>=2.2.1 <=2.3.0", prettier@^2.5.1: +prettier@2.5.1, prettier@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== +"prettier@>=2.2.1 <=2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" + integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== + pretty-error@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" @@ -19886,7 +20038,7 @@ 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: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== @@ -20404,7 +20556,7 @@ string-argv@^0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": 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== @@ -20422,6 +20574,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, 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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -20563,7 +20724,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm: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== @@ -20577,6 +20738,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.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.0, strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -21591,6 +21759,11 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + undici@5.9.1: version "5.9.1" resolved "https://registry.yarnpkg.com/undici/-/undici-5.9.1.tgz#fc9fd85dd488f965f153314a63d9426a11f3360b" @@ -22632,7 +22805,7 @@ wrangler@^2.0.23: optionalDependencies: fsevents "~2.3.2" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm: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== @@ -22650,6 +22823,15 @@ 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"