diff --git a/.circleci/config.yml b/.circleci/config.yml index 42af97c0955..04c7026e61e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -104,6 +104,35 @@ jobs: paths: - "persist" + test-remixdesktop-linux: + machine: + image: ubuntu-2004:current + resource_class: + xlarge + working_directory: ~/remix-project + parallelism: 10 + steps: + - run: ldd --version + - checkout + - attach_workspace: + at: . + - run: unzip ./persist/desktopbuild.zip + - run: + command: | + node -v + mkdir apps/remixdesktop/build + cp -r dist/apps/remix-ide apps/remixdesktop/build + cd apps/remixdesktop/ + yarn add node-pty + yarn --ignore-optional + yarn add @remix-project/remix-ws-templates + ./rundist.bash + - run: + name: "Run tests" + command: | + cd apps/remixdesktop/ + ./run_ci_test.sh + build-remixdesktop-linux: machine: image: ubuntu-2004:current @@ -125,15 +154,25 @@ jobs: yarn add node-pty yarn --ignore-optional yarn add @remix-project/remix-ws-templates - PUBLISH_FOR_PULL_REQUEST='true' yarn dist + ./rundist.bash rm -rf release/*-unpacked - save_cache: key: remixdesktop-linux-deps-{{ checksum "apps/remixdesktop/yarn.lock" }} paths: - apps/remixdesktop/node_modules + - run: + name: "remove unnecessary files" + command: | + rm -rf ~/remix-project/apps/remixdesktop/release/.icon* + rm -rf ~/remix-project/apps/remixdesktop/release/builder* - store_artifacts: path: apps/remixdesktop/release/ destination: remixdesktop-linux + - persist_to_workspace: + root: apps/remixdesktop + paths: + - "release" + build-remixdesktop-windows: executor: @@ -168,8 +207,9 @@ jobs: mkdir apps/remixdesktop/build cp -r dist/apps/remix-ide apps/remixdesktop/build cd apps/remixdesktop/ + pip install setuptools yarn - PUBLISH_FOR_PULL_REQUEST='true' yarn dist + ./rundist.bash rm -rf release/*-unpacked - save_cache: key: remixdesktop-windows-deps-{{ checksum "apps/remixdesktop/yarn.lock" }} @@ -179,6 +219,59 @@ jobs: root: apps/remixdesktop paths: - "release" + + test-remixdesktop-windows: + executor: + name: win/default # executor type + size: xlarge # can be medium, large, xlarge, 2xlarge + shell: bash.exe + parallelism: 10 + working_directory: ~/remix-project + steps: + - checkout + - attach_workspace: + at: . + - run: unzip ./persist/desktopbuild.zip + - restore_cache: + key: node-20-windows-v3 + - run: + command: | + nvm install 20.0.0 + nvm use 20.0.0 + node -v + npx -v + npm install --global yarn + yarn -v + - run: + name: start selenium + command: | + cd "apps/remixdesktop/" + yarn -v + shell: powershell.exe + - save_cache: + key: node-20-windows-v3 + paths: + - /ProgramData/nvm/v20.0.0 + - restore_cache: + keys: + - remixdesktop-windows-deps-{{ checksum "apps/remixdesktop/yarn.lock" }} + - run: + command: | + mkdir apps/remixdesktop/build + cp -r dist/apps/remix-ide apps/remixdesktop/build + cd apps/remixdesktop/ + nvm use 20.0.0 + node -v + pip install setuptools + yarn + ./rundist.bash + - run: + name: start tests offline + command: | + cd "apps/remixdesktop/" + yarn -v + sleep 15 + ./run_ci_test.sh # see https://docs.digicert.com/en/software-trust-manager/ci-cd-integrations/script-integrations/github-integration-ksp.html sign-remixdesktop-windows: executor: win/default # executor type @@ -229,28 +322,66 @@ jobs: command: | Get-ChildItem -Path 'C:\Program Files (x86)\Windows Kits\10\App Certification Kit' -Filter signtool.exe -Recurse - run: - name: "Signtool-Signing" + name: read env shell: powershell.exe command: | - & $env:Signtool sign /sha1 $env:SM_CODE_SIGNING_CERT_SHA1_HASH /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 $env:RemixSetupExe + # Specify the path to your package.json file + $packageJsonPath = "C:\Users\circleci\remix-project\apps\remixdesktop\package.json" + + # Check if the file exists + if (Test-Path $packageJsonPath) { + # Read the content of the package.json file + $packageJsonContent = Get-Content $packageJsonPath -Raw | ConvertFrom-Json + + # Check if the 'version' field exists in the package.json + if ($packageJsonContent.'version' -ne $null) { + # Store the version value in an environment variable + $version = $packageJsonContent.version + $file = "C:\Users\circleci\remix-project\release\Remix-Desktop-Setup-$($version).exe" + Write-Host "Version $(file) stored in PACKAGE_VERSION environment variable." + "Set-Variable -Name 'PACKAGE_VERSION' -Value '$file' -Scope Global" > SetEnvVars.ps1 + dir Env: + } else { + Write-Host "Error: 'version' field not found in package.json." + } + } else { + Write-Host "Error: package.json file not found at $packageJsonPath." + } + - run: + name: "Signtool-Signing" + shell: powershell.exe + command: | + . .\SetEnvVars.ps1 + dir Env: + & $env:Signtool sign /sha1 $env:SM_CODE_SIGNING_CERT_SHA1_HASH /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 $PACKAGE_VERSION - run: name: "Signtool-Verification" shell: powershell.exe command: | - $verify_output = $(& $env:Signtool verify /v /pa $env:RemixSetupExe) + . .\SetEnvVars.ps1 + $verify_output = $(& $env:Signtool verify /v /pa $PACKAGE_VERSION) echo ${verify_output} if (!$verify_output.Contains("Number of files successfully Verified: 1")) { echo 'Verification failed' exit 1 } + - run: + name: "remove unnecessary files" + shell: bash.exe + command: | + rm -rf ~/remix-project/release/.icon* + rm -rf ~/remix-project/release/builder* - store_artifacts: path: ~/remix-project/release/ destination: remixdesktop-windows + - persist_to_workspace: + root: ~/remix-project/ + paths: + - "release" environment: SM_CLIENT_CERT_FILE: 'C:\Certificate_pkcs12.p12' Signtool: 'C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe' SSM: 'C:\Program Files\DigiCert\DigiCert One Signing Manager Tools' - RemixSetupExe: 'C:\Users\circleci\remix-project\release\Remix IDE.exe' build-remixdesktop-mac: macos: @@ -258,10 +389,26 @@ jobs: resource_class: macos.m1.large.gen1 working_directory: ~/remix-project + parameters: + arch: + type: string steps: - checkout - attach_workspace: at: . + - run: + name: Install Apple Certificate + command: | + echo $APPLE_CERTIFICATE_BASE64 | base64 --decode > /tmp/certificate.p12 + security create-keychain -p ci-password build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p ci-password build.keychain + curl -o DeveloperIDG2CA.cer "https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer" + sudo security import DeveloperIDG2CA.cer -k /Library/Keychains/System.keychain -T /usr/bin/codesign + sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain DeveloperIDG2CA.cer + security import /tmp/certificate.p12 -k build.keychain -P $APPLE_CERTIFICATE_PASSWORD -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple: -s -k ci-password build.keychain + security find-identity -v -p codesigning - run: unzip ./persist/desktopbuild.zip - run: command: | @@ -283,20 +430,107 @@ jobs: # use USE_HARD_LINK=false https://github.com/electron-userland/electron-builder/issues/3179 - run: command: | - nvm use 20.0.0 + nvm use 20 mkdir apps/remixdesktop/build cp -r dist/apps/remix-ide apps/remixdesktop/build cd apps/remixdesktop yarn - yarn installRipGrepMacOXarm64 - PUBLISH_FOR_PULL_REQUEST='true' USE_HARD_LINKS=false yarn dist --mac --arm64 - yarn installRipGrepMacOXx64 - PUBLISH_FOR_PULL_REQUEST='true' USE_HARD_LINKS=false yarn dist --mac --x64 - rm -rf release/mac* + - run: + command: | + nvm use 20 + cd apps/remixdesktop + yarn installRipGrepMacOX<< parameters.arch >> + PUBLISH_FOR_PULL_REQUEST='false' USE_HARD_LINKS=false ./rundist.bash --<< parameters.arch >> + if [ -f release/latest-mac.yml ]; then + cat release/latest-mac.yml + mv release/latest-mac.yml release/latest-mac-<< parameters.arch >>.yml + fi + - run: + name: Notarize the app + command: | + brew install jq + cd apps/remixdesktop + zsh notarizedmg.sh + - run: + name: "remove unnecessary files" + command: | + rm -rf ~/remix-project/apps/remixdesktop/release/.icon* + rm -rf ~/remix-project/apps/remixdesktop/release/builder* + rm -rf ~/remix-project/apps/remixdesktop/release/*.blockmap + rm -rf ~/remix-project/apps/remixdesktop/release/_.* - store_artifacts: path: apps/remixdesktop/release/ destination: remixdesktop-mac - + - persist_to_workspace: + root: apps/remixdesktop + paths: + - "release" + test-remixdesktop-mac: + macos: + xcode: 14.2.0 + resource_class: + macos.m1.large.gen1 + working_directory: ~/remix-project + parallelism: 10 + steps: + - checkout + - attach_workspace: + at: . + - run: unzip ./persist/desktopbuild.zip + - run: + command: | + ls -la dist/apps/remix-ide + nvm install 20.0.0 + nvm use 20.0.0 + - restore_cache: + keys: + - remixdesktop-deps-mac-{{ checksum "apps/remixdesktop/yarn.lock" }} + - run: + command: | + nvm use 20.0.0 + cd apps/remixdesktop && yarn + yarn add @remix-project/remix-ws-templates + - save_cache: + key: remixdesktop-deps-mac-{{ checksum "apps/remixdesktop/yarn.lock" }} + paths: + - apps/remixdesktop/node_modules + - run: + command: | + nvm use 20 + mkdir apps/remixdesktop/build + cp -r dist/apps/remix-ide apps/remixdesktop/build + cd apps/remixdesktop + yarn + - run: + command: | + nvm use 20 + cd apps/remixdesktop + yarn installRipGrepMacOXarm64 + PUBLISH_FOR_PULL_REQUEST='false' USE_HARD_LINKS=false ./rundist.bash --arm64 + - run: + name: "Run tests" + command: | + nvm use 20 + cd apps/remixdesktop + ./run_ci_test.sh + + uploadartifacts: + docker: + - image: cimg/node:20.0.0-browsers + resource_class: + xlarge + working_directory: ~/remix-project + steps: + - checkout + - attach_workspace: + at: . + - restore_cache: + keys: + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn + - run: + name: "Upload Artifacts" + command: npx ts-node apps/remix-ide/ci/update_desktop_release_assets.ts lint: docker: - image: cimg/node:20.0.0-browsers @@ -502,6 +736,12 @@ workflows: - build-remixdesktop-mac: requires: - build-desktop + matrix: + parameters: + arch: ["arm64", "x64"] + - test-remixdesktop-mac: + requires: + - build-desktop - build-remixdesktop-windows: requires: - build-desktop @@ -511,6 +751,20 @@ workflows: - build-remixdesktop-linux: requires: - build-desktop + - test-remixdesktop-linux: + requires: + - build-desktop + - test-remixdesktop-windows: + requires: + - build-desktop + - uploadartifacts: + requires: + - build-remixdesktop-mac + - build-remixdesktop-linux + - sign-remixdesktop-windows + - test-remixdesktop-windows + - test-remixdesktop-linux + - test-remixdesktop-mac - build-plugin: matrix: parameters: diff --git a/.gitignore b/.gitignore index a9157706ae7..9e408323247 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ soljson.js *_group*.*.ts *_group*.ts stats.json +release # compiled output @@ -61,7 +62,10 @@ testem.log apps/remixdesktop/.webpack apps/remixdesktop/out apps/remixdesktop/release/ +apps/remixdesktop/build*/ apps/remix-ide/src/assets/list.json apps/remix-ide/src/assets/esbuild.wasm apps/remixdesktop/build* -logs \ No newline at end of file +apps/remixdesktop/reports +apps/remixdesktop/logs/ +logs diff --git a/apps/remix-ide-e2e/src/commands/addLocalPlugin.ts b/apps/remix-ide-e2e/src/commands/addLocalPlugin.ts index 51358b730fc..492a44dfeeb 100644 --- a/apps/remix-ide-e2e/src/commands/addLocalPlugin.ts +++ b/apps/remix-ide-e2e/src/commands/addLocalPlugin.ts @@ -24,7 +24,7 @@ function addLocalPlugin (browser: NightwatchBrowser, profile: Profile & Location browser.waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]') .execute(function () { - window.testmode = true + (window as any).testmode = true }) .click('*[data-id="pluginManagerComponentPluginSearchButton"]') .waitForElementVisible('*[data-id="pluginManagerLocalPluginModalDialogModalDialogContainer-react"]') diff --git a/apps/remix-ide/ci/update_desktop_release_assets.ts b/apps/remix-ide/ci/update_desktop_release_assets.ts new file mode 100644 index 00000000000..9dc8b4f1577 --- /dev/null +++ b/apps/remix-ide/ci/update_desktop_release_assets.ts @@ -0,0 +1,245 @@ +import { Octokit } from 'octokit' +import * as fs from 'fs' +import * as path from 'path' +import YAML from 'yaml' +import crypto from 'crypto' + +const owner = 'remix-project-org' +let repo = 'remix-desktop' +const headers = { + 'X-GitHub-Api-Version': '2022-11-28', +} + +const version = getVersionFromPackageJson() +let channel = 'latest' + +if (version.includes('beta')) { + channel = 'beta' +} +if (version.includes('alpha')) { + channel = 'alpha' +} +if (version.includes('insiders')) { + channel = 'insiders' +} + +if (channel !== 'latest') repo = `remix-desktop-${channel}` + +const octokit = new Octokit({ + auth: process.env.GH_TOKEN_DESKTOP_PUBLISH, +}) + +async function getAllReleases() { + const releases = await octokit.request('GET /repos/{owner}/{repo}/releases', { + owner: owner, + repo: repo, + headers: headers, + }) + return releases.data +} + +async function uploadReleaseAsset(release, name, file) { + const upload_url = release.upload_url + console.log(`Uploading ${name} to ${upload_url}`) + if (fs.existsSync(file)) { + octokit.request({ + method: "POST", + url: upload_url, + headers: { + "content-type": "text/plain", + }, + data: fs.readFileSync(file), + name, + label: name + }); + } else { + console.log(`File ${file} does not exist. Skipping...`) + } +} + +function getVersionFromPackageJson() { + // ignore ts error + // eslint-disable-next-line @typescript-eslint/no-var-requires + const packageJson = require(__dirname + '/../../../apps/remixdesktop/package.json') + return packageJson.version +} + +async function readReleaseFilesFromLocalDirectory() { + const directoryPath = path.join(__dirname, '../../../release') + const files = fs.readdirSync(directoryPath) + return files +} + +async function removeAsset(asset) { + await octokit.request('DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}', { + owner: owner, + repo: repo, + asset_id: asset.id, + headers: headers, + }) +} + +async function hashFile(file): Promise { + return new Promise((resolve, reject) => { + const hash = crypto.createHash('sha512').setEncoding('base64'); + // hash.on('error', reject).setEncoding(encoding); + fs.createReadStream( + file, + Object.assign({}, {}, { + highWaterMark: 1024 * 1024, + /* better to use more memory but hash faster */ + }) + ) + .on('error', reject) + .on('end', () => { + hash.end(); + console.log('hash done'); + console.log(hash.read()); + resolve(hash.digest('base64')); + }) + .pipe( + hash, + { + end: false, + } + ); + }); +} + +async function main() { + + + + const allReleases = await getAllReleases() + + console.log(`preparing release version: ${version}`) + let release + allReleases.find((r) => { + if (r.tag_name === `v${version}`) { + release = r + } + }) + if (!release) { + console.log('No release found.') + // create release + console.log(`Creating release ${version}`) + const r = await octokit.request('POST /repos/{owner}/{repo}/releases', { + owner: owner, + repo: repo, + tag_name: `v${version}`, + name: `${version}`, + draft: true, + prerelease: true, + headers: headers, + }) + release = r.data + } + + + let ymlFiles = await readReleaseFilesFromLocalDirectory() + ymlFiles = ymlFiles.filter((file) => file.endsWith('.yml') && file.startsWith('latest')) + + console.log(`Found ${ymlFiles.length} yml files to upload`) + + // read and parse yml latest files + // the yml files contain the sha512 hash and file size of the executable + // we need to recalculate the hash and file size of the executable + // and update the yml files + // this is because the executable is resigned after the yml files are created + for (const file of ymlFiles) { + const content = fs.readFileSync(path.join(__dirname, '../../../release', file), 'utf8') + const parsed = YAML.parse(content) + const hashes: { + url: string, + sha512: string, + size: number + }[] = [] + if (parsed.files) { + console.log(`Found`, parsed.files) + for (const f of parsed.files) { + const executable = f.url + const exists = fs.existsSync(path.join(__dirname, '../../../release', executable)) + if (!exists) { + console.log(`File ${executable} does not exist on local fs. Skipping...`) + continue + } else { + console.log(`File ${executable} exists on local fs. Recalculating hash...`) + // calculate sha512 hash of executable + const hash: string = await hashFile(path.join(__dirname, '../../../release', executable)) + console.log(hash) + // calculate file size of executable + const stats = fs.statSync(path.join(__dirname, '../../../release', executable)) + const fileSizeInBytes = stats.size + console.log(fileSizeInBytes) + hashes.push({ + url: executable, + sha512: hash, + size: fileSizeInBytes + }) + if (parsed.path === executable) { + parsed.sha512 = hash + parsed.size = fileSizeInBytes + } + } + } + } + console.log(hashes) + parsed.files = hashes + const newYml = YAML.stringify(parsed) + fs.writeFileSync(path.join(__dirname, '../../../release', file), newYml) + } + + let files = await readReleaseFilesFromLocalDirectory() + + try { + if (fs.existsSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`)) && fs.existsSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`))) { + // combine the two files + const macArm64 = fs.readFileSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`), 'utf8') + const mac = fs.readFileSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`), 'utf8') + const parsedMacArm64 = YAML.parse(macArm64) + const parsedMac = YAML.parse(mac) + console.log(parsedMacArm64) + console.log(parsedMac) + const combined = { + ...parsedMac, + files: [ + ...parsedMac.files, + ...parsedMacArm64.files + ] + } + console.log(combined) + const newYml = YAML.stringify(combined) + fs.writeFileSync(path.join(__dirname, '../../../release', `latest-mac.yml`), newYml) + // remove the arm64 file + fs.unlinkSync(path.join(__dirname, '../../../release', `latest-mac-arm64.yml`)) + fs.unlinkSync(path.join(__dirname, '../../../release', `latest-mac-x64.yml`)) + } + } catch (e) { + console.log(e) + } + + files = await readReleaseFilesFromLocalDirectory() + files = files. + filter((file) => file.endsWith('.zip') || file.endsWith('.dmg') || file.endsWith('.exe') || file.endsWith('.AppImage') || file.endsWith('.snap') || file.endsWith('.deb') || file.startsWith(`latest`)) + .filter((file) => !file.startsWith('._')) + console.log(`Found ${files.length} files to upload`) + console.log(files) + if (!release.draft) { + console.log(`Release ${version} is not a draft. Aborting...`) + return + } + // upload files + for (const file of files) { + // check if it is already uploaded + const asset = release.assets.find((a) => a.label === file) + if (asset) { + console.log(`Asset ${file} already uploaded... replacing it`) + // remove it first + await removeAsset(asset) + } + await uploadReleaseAsset(release, file, path.join(__dirname, '../../../release', file)) + } +} + +main() + diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index ccbe5ff4718..28da59dc356 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -52,7 +52,8 @@ import { electronTemplates } from './app/plugins/electron/templatesPlugin' import { xtermPlugin } from './app/plugins/electron/xtermPlugin' import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin' import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin' - +import { appUpdaterPlugin } from './app/plugins/electron/appUpdaterPlugin' + import {OpenAIGpt} from './app/plugins/openaigpt' import {SolCoder} from './app/plugins/solcoderAI' @@ -367,6 +368,8 @@ class AppComponent { this.engine.register([xterm]) const ripgrep = new ripgrepPlugin() this.engine.register([ripgrep]) + const appUpdater = new appUpdaterPlugin() + this.engine.register([appUpdater]) } const compilerloader = isElectron()? new compilerLoaderPluginDesktop(): new compilerLoaderPlugin() @@ -491,7 +494,7 @@ class AppComponent { await this.appManager.activatePlugin(['solidity-script', 'remix-templates']) if (isElectron()){ - await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep']) + await this.appManager.activatePlugin(['isogit', 'electronconfig', 'electronTemplates', 'xterm', 'ripgrep', 'appUpdater']) } this.appManager.on( diff --git a/apps/remix-ide/src/app/plugins/electron/appUpdaterPlugin.ts b/apps/remix-ide/src/app/plugins/electron/appUpdaterPlugin.ts new file mode 100644 index 00000000000..ec879fa6873 --- /dev/null +++ b/apps/remix-ide/src/app/plugins/electron/appUpdaterPlugin.ts @@ -0,0 +1,55 @@ +import { ElectronPlugin } from '@remixproject/engine-electron' + +const profile = { + displayName: 'appUpdater', + name: 'appUpdater', + description: 'appUpdater', +} + +export class appUpdaterPlugin extends ElectronPlugin { + constructor() { + console.log('appUpdaterPlugin') + super(profile) + } + + onActivation(): void { + this.on('appUpdater', 'askForUpdate', () => { + console.log('askForUpdate') + const upgradeModal = { + id: 'confirmUpdate', + title: 'An update is available', + message: `A new version of Remix Desktop is available. Do you want to update?`, + modalType: 'modal', + okLabel: 'Yes', + cancelLabel: 'No', + okFn: () => { + this.call('appUpdater', 'download') + }, + cancelFn: () => { + + }, + hideFn: () => null + } + this.call('notification', 'modal', upgradeModal) + }) + this.on('appUpdater', 'downloadReady', () => { + console.log('downloadReady') + const upgradeModal = { + id: 'confirmInstall', + title: 'An update is ready to install', + message: `A new version of Remix Desktop is ready to install. Do you want to install it now? This will close Remix Desktop.`, + modalType: 'modal', + okLabel: 'Yes', + cancelLabel: 'No', + okFn: () => { + this.call('appUpdater', 'install') + }, + cancelFn: () => { + + }, + hideFn: () => null + } + this.call('notification', 'modal', upgradeModal) + }) + } +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/plugins/remix-templates.ts b/apps/remix-ide/src/app/plugins/remix-templates.ts index e7846fbf476..d0aab28ecf0 100644 --- a/apps/remix-ide/src/app/plugins/remix-templates.ts +++ b/apps/remix-ide/src/app/plugins/remix-templates.ts @@ -5,7 +5,7 @@ const profile = { name: 'remix-templates', displayName: 'remix-templates', description: 'Remix Templates plugin', - methods: ['getTemplate', 'loadTemplateInNewWindow'], + methods: ['getTemplate', 'loadTemplateInNewWindow', 'loadFilesInNewWindow'], } export class TemplatesPlugin extends Plugin { @@ -26,5 +26,9 @@ export class TemplatesPlugin extends Plugin { const files = await this.getTemplate(template, opts) this.call('electronTemplates', 'loadTemplateInNewWindow', files) } + + async loadFilesInNewWindow (files: any) { + this.call('electronTemplates', 'loadTemplateInNewWindow', files) + } } diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 919b04a1327..1e8b81a62ae 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -282,7 +282,7 @@ export class RemixAppManager extends PluginManager { } return plugins.map(plugin => { - if (plugin.name === 'dgit' && Registry.getInstance().get('platform').api.isDesktop()) { plugin.url = 'https://dgit4-76cc9.web.app/' } // temporary fix + if (plugin.name === 'dgit' && Registry.getInstance().get('platform').api.isDesktop()) { plugin.url = 'https://dgit4-76cc9.web.app/' } if (plugin.name === testPluginName) plugin.url = testPluginUrl return new IframePlugin(plugin) }) diff --git a/apps/remixdesktop/README.md b/apps/remixdesktop/README.md index 692b5b3c4d5..bd1efb612c7 100644 --- a/apps/remixdesktop/README.md +++ b/apps/remixdesktop/README.md @@ -2,21 +2,159 @@ ## Development +### Running the app locally + In the main repo yarn, then run yarn serve In this directory apps/remixdesktop, yarn, then run: yarn start:dev to boot the electron app -In chrome chrome://inspect/#devices you can add localhost:5858 to the network targets and then you will see an inspect button electron/js2c/browser_init -file:/// -You can use that to inspect the output of the electron app + +Then app will be started in live reload mode, anything you do in Remix IDE will be reloaded. +It will not however reload electron code. You need to rerun yarn start:dev every time. If you run into issues with yarn when native node modules are being rebuilt you need - Windows: install Visual Studio Tools with Desktop Development C++ enabled in the Workloads -- MacOS: install Xcode or Xcode Command Line Tools +- MacOS: install Xcode or Xcode Command Line Tools. Also make sure the compilers (clang++ | g++) target the right sdk includes, ```export SDKROOT="xcrun --show-sdk-path"``` - Linux: unknown, probably a C++ compiler -## Builds -Builds can be found in the artefacts of CI. +### Electron Plugin + +Electron has its own Plugin Engine, which holds plugins, these plugins have plugin clients attached to them. Each of those clients is created when an instance of Remix Desktop connects +and activates a plugin. Follow all these steps to make that work. + +1. create a plugin file in apps/remixdesktop/src/plugins +2. add imports: +``` +import { Profile } from '@remixproject/plugin-utils' +import { ElectronBasePlugin, ElectronBasePluginClient } from '@remixproject/plugin-electron' +``` +3. add a base profile and a client profile: +``` +const profile: Profile = { + displayName: 'compilerLoader', + name: 'compilerloader', + description: 'Compiler Loader', +} +const clientProfile: Profile = { + name: 'compilerloader', + displayName: 'compilerloader', + description: 'Compiler Loader', + methods: ['downloadCompiler', 'listCompilers', 'getBaseUrls', 'getJsonBinData'], +} +``` + +As you can see in the clientProfile you define the methods which are exposed to the Remix plugin system. + +5. add a base plugin and a plugin client +``` +export class CompilerLoaderPlugin extends ElectronBasePlugin { + clients: CompilerLoaderPluginClient[] = [] + constructor() { + super(profile, clientProfile, CompilerLoaderPluginClient) + this.methods = [...super.methods] + } +} + +class CompilerLoaderPluginClient extends ElectronBasePluginClient { + solJsonBinData: iSolJsonBinData + constructor(webContentsId: number, profile: Profile) { + super(webContentsId, profile) + } + + async onActivation(): Promise { + this.onload(() => { + this.emit('loaded') + }) + } +} +``` +The ElectronBasePluginClient is the specific instance which will be connected to the IDE. The BasePlugin is just holding all the clients for all the instances. + +Any instance specific code is set as functions on the ElectronBasePluginClient class. + +6. If you need fs access you need to track the workingdir like we do here: +This ensures you know where the user is working + +``` + +class IsoGitPluginClient extends ElectronBasePluginClient { + workingDir: string = '' + + constructor(webContentsId: number, profile: Profile) { + super(webContentsId, profile) + this.onload(async () => { + this.on('fs' as any, 'workingDirChanged', async (path: string) => { + this.workingDir = path + }) + this.workingDir = await this.call('fs' as any, 'getWorkingDir') + + }) + } + + ``` + +7. If you need to call methods on the BASE which holds all the clients you can add methods there, for example this iterates over clients +and finds the one with the webContentsId. This ID passed on ie by menu items. Look at menu.ts to see how that works. + +``` + openTemplate(webContentsId: any): void { + const client = this.clients.find(c => c.webContentsId === webContentsId) + if (client) { + client.openTemplate() + } + } +``` + +8. Add your plugin to engine.ts + +``` +const compilerLoaderPlugin = new CompilerLoaderPlugin() +``` + +9. Register the plugin in engine.ts + +``` +engine.register(compilerLoaderPlugin) +``` + +10. activation of plugins is done when the clients connect to the engine. No need to activate it. + +11. Add the plugin to the preload.ts. Add it to this list: + +``` +const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader', 'appUpdater'] +``` + +If you don't this, it won't work. + +12. In Remix IDE create a plugin in src/app/plugins/electron. If everything works correctly the methods will be loaded from the electron side, no need to specify them here. +This plugin is only a passthrough. + +``` +const profile = { + displayName: 'compilerLoader', + name: 'compilerloader', + description: 'Loads the compiler for offline use', +} + +export class compilerLoaderPluginDesktop extends ElectronPlugin { + constructor() { + super(profile) + this.methods = [] + } + + async onActivation(): Promise { + + // something to do + + } +} +``` + +13. if you need to activate that on load you need to add it to the app.js where other plugins are activated. + + ## CI -CI will only run the builds is the branch is master or contains the word: desktop \ No newline at end of file +CI will only run the builds is the branch is master or contains the word: desktop + diff --git a/apps/remixdesktop/afterbuild.js b/apps/remixdesktop/afterbuild.js new file mode 100644 index 00000000000..bc2b1ff49d2 --- /dev/null +++ b/apps/remixdesktop/afterbuild.js @@ -0,0 +1,30 @@ +const fs = require('fs'); + +exports.default = async function afterbuild(context) { + // do not run when not on macOS or when not on CIRCLECI + if (process.platform !== 'darwin' || !process.env.CIRCLE_BRANCH) { + return; + } + + console.log('AFTER BUILD', context); + + const artifactPaths = context.artifactPaths; + const newDmgs = artifactPaths.filter((dmg) => dmg.endsWith('.dmg')).map((dmg) => dmg); // Removed unnecessary quotes for consistency + + let existingDmgs = []; + try { + // Attempt to read the existing dmgs.json file + const data = fs.readFileSync('dmgs.json', 'utf8'); + const parsedData = JSON.parse(data); + existingDmgs = parsedData.dmgs || []; // Ensure existingDmgs is an array + } catch (error) { + // If there's an error reading the file (e.g., file does not exist), proceed with an empty array + console.log('No existing dmgs.json or error reading file, creating new one.'); + } + + // Combine existing and new dmgs, avoiding duplicates + const combinedDmgs = [...new Set([...existingDmgs, ...newDmgs])]; + + // Write/overwrite the dmgs.json with the combined list of dmgs + fs.writeFileSync('dmgs.json', JSON.stringify({ dmgs: combinedDmgs }, null, 2)); +}; diff --git a/apps/remixdesktop/aftersign.js b/apps/remixdesktop/aftersign.js new file mode 100644 index 00000000000..5ea850e1642 --- /dev/null +++ b/apps/remixdesktop/aftersign.js @@ -0,0 +1,90 @@ +const { notarize } = require('@electron/notarize') +const fs = require('fs') +const { exec } = require('child_process') // Import the exec function +exports.default = async function notarizing(context) { + const { electronPlatformName, appOutDir } = context // Provided by electron-builder + + console.log('NOTARIZING') + + if (electronPlatformName !== 'darwin' || !process.env.CIRCLE_BRANCH) { + return + } + + const appName = context.packager.appInfo.productFilename + const appPath = `${appOutDir}/${appName}.app` + + // Function to promisify the exec command + function execShellCommand(cmd) { + return new Promise((resolve, reject) => { + exec(cmd, (error, stdout, stderr) => { + if (error) { + reject(new Error(`Error: ${error.message}`)); + return; + } + if (stderr) { + reject(new Error(`Stderr: ${stderr}`)); + return; + } + console.log(`stdout: ${stdout}`); + resolve(stdout); + }); + }); + } + + // Function to check if the app is stapled + // Async function to check the stapling status + async function checkStapleStatus() { + try { + console.log(`xcrun stapler validate "${appPath}"`) + await execShellCommand(`xcrun stapler validate "${appPath}"`); + console.log('App is already stapled. No action needed.'); + return true + } catch (error) { + console.log(`App is not stapled: ${error.message}`); + return false + } + } + + + + + async function runNotarize() { + + console.log('NOTARIZING + ', `xcrun stapler staple "${appPath}"`) + console.log({ + appBundleId: 'org.ethereum.remix-ide', // Your app's bundle ID + appPath: `${appOutDir}/${appName}.app`, // Path to your .app + appleId: process.env.APPLE_ID, // Your Apple ID + appleIdPassword: process.env.APPLE_ID_PASSWORD, // App-specific password + teamId: process.env.APPLE_TEAM_ID, // Your Apple Developer team ID (optional) + }) + + try { + const r = await notarize({ + appBundleId: 'org.ethereum.remix-ide', // Your app's bundle ID + appPath: `${appOutDir}/${appName}.app`, // Path to your .app + appleId: process.env.APPLE_ID, // Your Apple ID + appleIdPassword: process.env.APPLE_ID_PASSWORD, // App-specific password + teamId: process.env.APPLE_TEAM_ID, // Your Apple Developer team ID (optional) + }) + + console.log(r) + + // Stapling the app + console.log('STAPLING', `xcrun stapler staple "${appPath}"`) + + await execShellCommand(`xcrun stapler staple "${appPath}"`) + + } catch (error) { + console.error('Error during notarization:', error) + } + + } + + if(!await checkStapleStatus()){ + await runNotarize() + await checkStapleStatus() + }else{ + return [] + } +} diff --git a/apps/remixdesktop/alpha.json b/apps/remixdesktop/alpha.json new file mode 100644 index 00000000000..c1fc03dd536 --- /dev/null +++ b/apps/remixdesktop/alpha.json @@ -0,0 +1,61 @@ +{ + "productName": "Remix-Desktop-alpha", + "appId": "org.ethereum.remix-ide", + "asar": true, + "generateUpdatesFilesForAllChannels": false, + "icon": "assets", + "files": [ + "build/**/*" + ], + "afterSign": "aftersign.js", + "afterAllArtifactBuild": "afterbuild.js", + "publish": [ + { + "provider": "github", + "owner": "remix-project-org", + "repo": "remix-desktop-alpha", + "releaseType": "draft", + "publishAutoUpdate": true + } + ], + "mac": { + "category": "public.app-category.productivity", + "icon": "assets/icon.png", + "darkModeSupport": true, + "hardenedRuntime": true, + "gatekeeperAssess": false, + "entitlements": "entitlements.mac.plist", + "entitlementsInherit": "entitlements.mac.plist" + }, + "dmg": { + "writeUpdateInfo": true, + "sign": true + }, + "nsis": { + "createDesktopShortcut": "always", + "allowToChangeInstallationDirectory": true, + "oneClick": false, + "shortcutName": "Remix Desktop alpha", + "differentialPackage": false + }, + "win": { + "target": [ + "nsis" + ], + "artifactName": "${productName}-Setup-${version}.${ext}", + "icon": "assets/icon.png" + }, + "deb": {}, + "linux": { + "target": [ + "deb", + "snap", + "AppImage" + ], + "category": "WebBrowser", + "icon": "assets" + }, + "directories": { + "output": "release" + } +} \ No newline at end of file diff --git a/apps/remixdesktop/beta.json b/apps/remixdesktop/beta.json new file mode 100644 index 00000000000..7087d9147b0 --- /dev/null +++ b/apps/remixdesktop/beta.json @@ -0,0 +1,61 @@ +{ + "productName": "Remix-Desktop-Beta", + "appId": "org.ethereum.remix-ide", + "asar": true, + "generateUpdatesFilesForAllChannels": false, + "icon": "assets", + "files": [ + "build/**/*" + ], + "afterSign": "aftersign.js", + "afterAllArtifactBuild": "afterbuild.js", + "publish": [ + { + "provider": "github", + "owner": "remix-project-org", + "repo": "remix-desktop-beta", + "releaseType": "draft", + "publishAutoUpdate": true + } + ], + "mac": { + "category": "public.app-category.productivity", + "icon": "assets/icon.png", + "darkModeSupport": true, + "hardenedRuntime": true, + "gatekeeperAssess": false, + "entitlements": "entitlements.mac.plist", + "entitlementsInherit": "entitlements.mac.plist" + }, + "dmg": { + "writeUpdateInfo": true, + "sign": true + }, + "nsis": { + "createDesktopShortcut": "always", + "allowToChangeInstallationDirectory": true, + "oneClick": false, + "shortcutName": "Remix Desktop Beta", + "differentialPackage": false + }, + "win": { + "target": [ + "nsis" + ], + "artifactName": "Remix-Desktop-Setup-${version}.${ext}", + "icon": "assets/icon.png" + }, + "deb": {}, + "linux": { + "target": [ + "deb", + "snap", + "AppImage" + ], + "category": "WebBrowser", + "icon": "assets" + }, + "directories": { + "output": "release" + } +} \ No newline at end of file diff --git a/apps/remixdesktop/entitlements.mac.plist b/apps/remixdesktop/entitlements.mac.plist new file mode 100644 index 00000000000..0be645bdc8f --- /dev/null +++ b/apps/remixdesktop/entitlements.mac.plist @@ -0,0 +1,13 @@ + + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + + \ No newline at end of file diff --git a/apps/remixdesktop/insiders.json b/apps/remixdesktop/insiders.json new file mode 100644 index 00000000000..0968d6df7bd --- /dev/null +++ b/apps/remixdesktop/insiders.json @@ -0,0 +1,61 @@ +{ + "productName": "Remix-Desktop-Insiders", + "appId": "org.ethereum.remix-ide", + "asar": true, + "generateUpdatesFilesForAllChannels": false, + "icon": "assets", + "files": [ + "build/**/*" + ], + "afterSign": "aftersign.js", + "afterAllArtifactBuild": "afterbuild.js", + "publish": [ + { + "provider": "github", + "owner": "remix-project-org", + "repo": "remix-desktop-insiders", + "releaseType": "draft", + "publishAutoUpdate": true + } + ], + "mac": { + "category": "public.app-category.productivity", + "icon": "assets/icon.png", + "darkModeSupport": true, + "hardenedRuntime": true, + "gatekeeperAssess": false, + "entitlements": "entitlements.mac.plist", + "entitlementsInherit": "entitlements.mac.plist" + }, + "dmg": { + "writeUpdateInfo": true, + "sign": true + }, + "nsis": { + "createDesktopShortcut": "always", + "allowToChangeInstallationDirectory": true, + "oneClick": false, + "shortcutName": "Remix Desktop Insiders", + "differentialPackage": false + }, + "win": { + "target": [ + "nsis" + ], + "artifactName": "Remix-Desktop-Setup-${version}.${ext}", + "icon": "assets/icon.png" + }, + "deb": {}, + "linux": { + "target": [ + "deb", + "snap", + "AppImage" + ], + "category": "WebBrowser", + "icon": "assets" + }, + "directories": { + "output": "release" + } +} \ No newline at end of file diff --git a/apps/remixdesktop/latest.json b/apps/remixdesktop/latest.json new file mode 100644 index 00000000000..dd2f962c8cd --- /dev/null +++ b/apps/remixdesktop/latest.json @@ -0,0 +1,61 @@ +{ + "productName": "Remix-Desktop", + "appId": "org.ethereum.remix-ide", + "asar": true, + "generateUpdatesFilesForAllChannels": false, + "icon": "assets", + "files": [ + "build/**/*" + ], + "afterSign": "aftersign.js", + "afterAllArtifactBuild": "afterbuild.js", + "publish": [ + { + "provider": "github", + "owner": "remix-project-org", + "repo": "remix-desktop", + "releaseType": "draft", + "publishAutoUpdate": true + } + ], + "mac": { + "category": "public.app-category.productivity", + "icon": "assets/icon.png", + "darkModeSupport": true, + "hardenedRuntime": true, + "gatekeeperAssess": false, + "entitlements": "entitlements.mac.plist", + "entitlementsInherit": "entitlements.mac.plist" + }, + "dmg": { + "writeUpdateInfo": true, + "sign": true + }, + "nsis": { + "createDesktopShortcut": "always", + "allowToChangeInstallationDirectory": true, + "oneClick": false, + "shortcutName": "Remix Desktop", + "differentialPackage": false + }, + "win": { + "target": [ + "nsis" + ], + "artifactName": "${productName}-Setup-${version}.${ext}", + "icon": "assets/icon.png" + }, + "deb": {}, + "linux": { + "target": [ + "deb", + "snap", + "AppImage" + ], + "category": "WebBrowser", + "icon": "assets" + }, + "directories": { + "output": "release" + } +} \ No newline at end of file diff --git a/apps/remixdesktop/nightwatch.conf.js b/apps/remixdesktop/nightwatch.conf.js new file mode 100644 index 00000000000..03f35c43504 --- /dev/null +++ b/apps/remixdesktop/nightwatch.conf.js @@ -0,0 +1,344 @@ +// +// Refer to the online docs for more details: +// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html +// +// _ _ _ _ _ _ _ +// | \ | |(_) | | | | | | | | +// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__ +// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \ +// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | | +// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_| +// __/ | +// |___/ +// + +module.exports = { + // An array of folders (excluding subfolders) where your tests are located; + // if this is not specified, the test source must be passed as the second argument to the test runner. + src_folders: [], + + // See https://nightwatchjs.org/guide/concepts/page-object-model.html + page_objects_path: ['node_modules/nightwatch/examples/pages/'], + + // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html + custom_commands_path: ['node_modules/nightwatch/examples/custom-commands/'], + + // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html + custom_assertions_path: '', + + // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html + plugins: [], + + // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals + globals_path : '', + + webdriver: {}, + + test_settings: { + default: { + disable_error_log: false, + launch_url: 'https://nightwatchjs.org', + + screenshots: { + enabled: false, + path: 'screens', + on_failure: true + }, + + desiredCapabilities: { + browserName : 'firefox' + }, + + webdriver: { + start_process: true, + server_path: '' + } + }, + + + + firefox: { + desiredCapabilities : { + browserName : 'firefox', + alwaysMatch: { + acceptInsecureCerts: true, + 'moz:firefoxOptions': { + args: [ + // '-headless', + // '-verbose' + ] + } + } + }, + webdriver: { + start_process: true, + server_path: '', + cli_args: [ + // very verbose geckodriver logs + // '-vv' + ] + } + }, + + chrome: { + desiredCapabilities : { + browserName : 'chrome', + 'goog:chromeOptions' : { + // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ + // + // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78) + w3c: true, + args: [ + //'--no-sandbox', + //'--ignore-certificate-errors', + //'--allow-insecure-localhost', + //'--headless' + ] + } + }, + + webdriver: { + start_process: true, + server_path: '', + cli_args: [ + // --verbose + ] + } + }, + + edge: { + desiredCapabilities : { + browserName : 'MicrosoftEdge', + 'ms:edgeOptions' : { + w3c: true, + // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options + args: [ + //'--headless' + ] + } + }, + + webdriver: { + start_process: true, + // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/ + // and set the location below: + server_path: '', + cli_args: [ + // --verbose + ] + } + }, + + ////////////////////////////////////////////////////////////////////////////////// + // Configuration for when using cucumber-js (https://cucumber.io) | + // | + // It uses the bundled examples inside the nightwatch examples folder; feel free | + // to adapt this to your own project needs | + ////////////////////////////////////////////////////////////////////////////////// + 'cucumber-js': { + src_folders: ['examples/cucumber-js/features/step_definitions'], + + test_runner: { + // set cucumber as the runner + type: 'cucumber', + + // define cucumber specific options + options: { + //set the feature path + feature_path: 'node_modules/nightwatch/examples/cucumber-js/*/*.feature', + + // start the webdriver session automatically (enabled by default) + // auto_start_session: true + + // use parallel execution in Cucumber + // parallel: 2 // set number of workers to use (can also be defined in the cli as --parallel 2 + } + } + }, + + ////////////////////////////////////////////////////////////////////////////////// + // Configuration for when using the browserstack.com cloud service | + // | + // Please set the username and access key by setting the environment variables: | + // - BROWSERSTACK_USERNAME | + // - BROWSERSTACK_ACCESS_KEY | + // .env files are supported | + ////////////////////////////////////////////////////////////////////////////////// + browserstack: { + selenium: { + host: 'hub.browserstack.com', + port: 443 + }, + // More info on configuring capabilities can be found on: + // https://www.browserstack.com/automate/capabilities?tag=selenium-4 + desiredCapabilities: { + 'bstack:options' : { + userName: '${BROWSERSTACK_USERNAME}', + accessKey: '${BROWSERSTACK_ACCESS_KEY}', + } + }, + + disable_error_log: true, + webdriver: { + timeout_options: { + timeout: 15000, + retry_attempts: 3 + }, + keep_alive: true, + start_process: false + } + }, + + 'browserstack.local': { + extends: 'browserstack', + desiredCapabilities: { + 'browserstack.local': true + } + }, + + 'browserstack.chrome': { + extends: 'browserstack', + desiredCapabilities: { + browserName: 'chrome', + chromeOptions : { + w3c: true + } + } + }, + + 'browserstack.firefox': { + extends: 'browserstack', + desiredCapabilities: { + browserName: 'firefox' + } + }, + + 'browserstack.ie': { + extends: 'browserstack', + desiredCapabilities: { + browserName: 'internet explorer', + browserVersion: '11.0' + } + }, + + 'browserstack.safari': { + extends: 'browserstack', + desiredCapabilities: { + browserName: 'safari' + } + }, + + 'browserstack.local_chrome': { + extends: 'browserstack.local', + desiredCapabilities: { + browserName: 'chrome' + } + }, + + 'browserstack.local_firefox': { + extends: 'browserstack.local', + desiredCapabilities: { + browserName: 'firefox' + } + }, + ////////////////////////////////////////////////////////////////////////////////// + // Configuration for when using the SauceLabs cloud service | + // | + // Please set the username and access key by setting the environment variables: | + // - SAUCE_USERNAME | + // - SAUCE_ACCESS_KEY | + ////////////////////////////////////////////////////////////////////////////////// + saucelabs: { + selenium: { + host: 'ondemand.saucelabs.com', + port: 443 + }, + // More info on configuring capabilities can be found on: + // https://docs.saucelabs.com/dev/test-configuration-options/ + desiredCapabilities: { + 'sauce:options' : { + username: '${SAUCE_USERNAME}', + accessKey: '${SAUCE_ACCESS_KEY}', + screenResolution: '1280x1024' + // https://docs.saucelabs.com/dev/cli/sauce-connect-proxy/#--region + // region: 'us-west-1' + // https://docs.saucelabs.com/dev/test-configuration-options/#tunnelidentifier + // parentTunnel: '', + // tunnelIdentifier: '', + } + }, + disable_error_log: false, + webdriver: { + start_process: false + } + }, + 'saucelabs.chrome': { + extends: 'saucelabs', + desiredCapabilities: { + browserName: 'chrome', + browserVersion: 'latest', + javascriptEnabled: true, + acceptSslCerts: true, + timeZone: 'London', + chromeOptions : { + w3c: true + } + } + }, + 'saucelabs.firefox': { + extends: 'saucelabs', + desiredCapabilities: { + browserName: 'firefox', + browserVersion: 'latest', + javascriptEnabled: true, + acceptSslCerts: true, + timeZone: 'London' + } + }, + ////////////////////////////////////////////////////////////////////////////////// + // Configuration for when using the Selenium service, either locally or remote, | + // like Selenium Grid | + ////////////////////////////////////////////////////////////////////////////////// + selenium_server: { + // Selenium Server is running locally and is managed by Nightwatch + // Install the NPM package @nightwatch/selenium-server or download the selenium server jar file from https://github.com/SeleniumHQ/selenium/releases/, e.g.: selenium-server-4.1.1.jar + selenium: { + start_process: true, + port: 4444, + server_path: '', // Leave empty if @nightwatch/selenium-server is installed + command: 'standalone', // Selenium 4 only + cli_args: { + //'webdriver.gecko.driver': '', + //'webdriver.chrome.driver': '' + } + }, + webdriver: { + start_process: false, + default_path_prefix: '/wd/hub' + } + }, + + 'selenium.chrome': { + extends: 'selenium_server', + desiredCapabilities: { + browserName: 'chrome', + chromeOptions : { + w3c: true + } + } + }, + + 'selenium.firefox': { + extends: 'selenium_server', + desiredCapabilities: { + browserName: 'firefox', + 'moz:firefoxOptions': { + args: [ + // '-headless', + // '-verbose' + ] + } + } + } + } +}; diff --git a/apps/remixdesktop/notarizedmg.sh b/apps/remixdesktop/notarizedmg.sh new file mode 100644 index 00000000000..e621d3a422e --- /dev/null +++ b/apps/remixdesktop/notarizedmg.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Path to the JSON file containing the DMG paths +JSON_FILE="dmgs.json" + +# Read the DMGs array from the JSON file +DMG_PATHS=$(jq -r '.dmgs[]' "$JSON_FILE") + +echo $DMG_PATHS + +xcrun notarytool store-credentials "notarytool-password" \ + --apple-id ${APPLE_ID} \ + --team-id ${APPLE_TEAM_ID} \ + --password ${APPLE_ID_PASSWORD} + +# Use jq to parse the DMGs array and read each line +while IFS= read -r DMG_PATH; do + # Remove single quotes from the path if present + DMG_PATH_CLEANED=$(echo $DMG_PATH | tr -d "'") + + echo "Submitting $DMG_PATH_CLEANED for notarization..." + + # Replace `your-app-specific-args` with the actual arguments for your app + # Ensure your notarytool command and arguments are correct for your application + xcrun notarytool submit "$DMG_PATH_CLEANED" --keychain-profile "notarytool-password" --wait + + # Check the command's success + if [ $? -eq 0 ]; then + echo "Successfully submitted $DMG_PATH_CLEANED for notarization." + xcrun stapler staple "$DMG_PATH_CLEANED" + echo "Successfully stapled $DMG_PATH_CLEANED." + spctl -a -t open -vvv --context context:primary-signature "$DMG_PATH_CLEANED" + echo "Successfully checked $DMG_PATH_CLEANED." + else + echo "Failed to submit $DMG_PATH_CLEANED for notarization." + fi +done < <(jq -r '.dmgs[]' "$JSON_FILE") + +echo "All DMG submissions completed." diff --git a/apps/remixdesktop/package.json b/apps/remixdesktop/package.json index a92af25e364..d13897b3cdb 100644 --- a/apps/remixdesktop/package.json +++ b/apps/remixdesktop/package.json @@ -1,13 +1,13 @@ { "name": "remixdesktop", - "version": "0.0.11-Alpha", + "version": "1.0.4-insiders", "main": "build/main.js", "license": "MIT", "type": "commonjs", "description": "Remix IDE Desktop", "repository": { "type": "git", - "url": "git+https://github.com/bunsenstraat/remix-desktop.git" + "url": "git+https://github.com/remix-project-org/remix-desktop.git" }, "author": { "name": "Remix Team", @@ -24,98 +24,51 @@ "scripts": { "start:dev": "tsc && cp -R node_modules/yarn build/tools/ && cross-env NODE_ENV=development electron --inspect=5858 .", "start:production": "tsc && && cp -R node_modules/yarn build/tools/ && cross-env NODE_ENV=production electron .", - "dist": "tsc && cp -R node_modules/yarn build/tools/ && electron-builder", + "dist": "tsc && cp -R node_modules/yarn build/tools/ && electron-builder -p never", "installRipGrepMacOXx64": "rm -rf node_modules/@vscode/ripgrep/bin && npm_config_arch=x64 node node_modules/@vscode/ripgrep/lib/postinstall.js", "installRipGrepMacOXarm64": "rm -rf node_modules/@vscode/ripgrep/bin && npm_config_arch=arm64 node node_modules/@vscode/ripgrep/lib/postinstall.js", - "postinstall": "electron-builder install-app-deps" + "postinstall": "electron-builder install-app-deps", + "test": "yarn run build:e2e && nightwatch --config build-e2e/remixdesktop/test/nighwatch.app.js", + "test:isogit": "yarn run test --useIsoGit --test build-e2e/remixdesktop/test/tests/app/git.test.js", + "test:offline": "yarn run test --useOffline --test build-e2e/remixdesktop/test/tests/app/offline.test.js", + "build:e2e": "tsc -p tsconfig.e2e.json" }, "devDependencies": { - "@electron/rebuild": "^3.2.13", + "@electron/notarize": "^2.3.0", "@types/byline": "^4.2.35", "@types/express": "^4.17.21", + "@types/nightwatch": "^2.3.23", + "chromedriver": "116", "cross-env": "^7.0.3", - "electron": "^25.0.1", - "electron-builder": "^23.6.0", + "deep-equal": "^2.2.3", + "electron": "^26.0.0", + "electron-builder": "24.9.1", "electron-devtools-installer": "^3.2.0", + "nightwatch": "2.3", + "selenium-standalone": "^9.3.1", "typescript": "^5.1.3", "yarn": "^1.22.21" }, "dependencies": { "@remix-project/remix-url-resolver": "^0.0.65", - "@remixproject/engine": "0.3.41", - "@remixproject/engine-electron": "0.3.41", - "@remixproject/plugin": "0.3.41", - "@remixproject/plugin-api": "^0.3.38", - "@remixproject/plugin-electron": "0.3.41", + "@remixproject/engine": "0.3.43", + "@remixproject/engine-electron": "0.3.43", + "@remixproject/plugin": "0.3.43", + "@remixproject/plugin-api": "^0.3.43", + "@remixproject/plugin-electron": "0.3.43", "@vscode/ripgrep": "^1.15.6", "add": "^2.0.6", - "axios": "^1.6.1", + "axios": "^1.6.8", "byline": "^5.0.0", "chokidar": "^3.5.3", + "electron-updater": "^6.1.8", "express": "^4.19.2", "isomorphic-git": "^1.24.2", + "matomo-tracker": "^2.2.4", "node-pty": "^0.10.1", "semver": "^7.5.4" }, "optionalDependencies": { "@remix-project/remix-ws-templates": "^1.0.27" - }, - "build": { - "productName": "Remix IDE", - "appId": "org.ethereum.remix-ide", - "asar": true, - "generateUpdatesFilesForAllChannels": true, - "icon": "assets", - "files": [ - "build/**/*" - ], - "publish": [{ - "provider": "github", - "owner": "bunsenstraat", - "repo": "remix-desktop", - "releaseType": "draft", - "publishAutoUpdate": true - }], - "mac": { - "category": "public.app-category.productivity", - "target": [ - { - "target": "dmg", - "arch": [ - "x64", - "arm64" - ] - } - ], - "icon": "assets/icon.png", - "darkModeSupport": true - }, - "dmg": { - "writeUpdateInfo": false - }, - "nsis": { - "createDesktopShortcut": "always", - "allowToChangeInstallationDirectory": true, - "oneClick": false, - "shortcutName": "Remix IDE", - "differentialPackage": false - }, - "win": { - "target": [ - "nsis" - ], - "icon": "assets/icon.png", - "artifactName": "${productName}.${ext}" - }, - "linux": { - "target": [ - "deb" - ], - "category": "WebBrowser", - "icon": "assets" - }, - "directories": { - "output": "release" - } } } diff --git a/apps/remixdesktop/run_ci_test.sh b/apps/remixdesktop/run_ci_test.sh new file mode 100755 index 00000000000..3020b0daf15 --- /dev/null +++ b/apps/remixdesktop/run_ci_test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e +TEST_EXITCODE=0 +yarn run build:e2e && node ./splice_tests.js +TESTFILES=$(node ./splice_tests.js | circleci tests split --split-by=timings) +for TESTFILE in $TESTFILES; do + yarn run test --test ./build-e2e/remixdesktop/test/tests/app/${TESTFILE} || TEST_EXITCODE=1 +done + +if [ "$CIRCLE_NODE_INDEX" -eq 0 ]; then + yarn test:isogit +elif [ "$CIRCLE_NODE_INDEX" -eq 1 ]; then + yarn test:offline +fi + +echo "$TEST_EXITCODE" +if [ "$TEST_EXITCODE" -eq 1 ] +then + exit 1 +fi diff --git a/apps/remixdesktop/rundist.bash b/apps/remixdesktop/rundist.bash new file mode 100755 index 00000000000..66a3a9a0dc5 --- /dev/null +++ b/apps/remixdesktop/rundist.bash @@ -0,0 +1,24 @@ +#!/bin/bash + +# Read the version from package.json +version=$(awk -F'"' '/"version":/ {print $4}' package.json) + +# Determine the command to run based on the version +if [[ $version == *"beta"* ]]; then + command="yarn dist -c beta.json" +elif [[ $version == *"alpha"* ]]; then + command="yarn dist -c alpha.json" +elif [[ $version == *"insiders"* ]]; then + command="yarn dist -c insiders.json" +else + command="yarn dist -c latest.json" +fi + +# Append any arguments passed in CLI +for arg in "$@"; do + command+=" $arg" +done + +# Print and run the command +echo "Running command: $command" +$command diff --git a/apps/remixdesktop/splice_tests.js b/apps/remixdesktop/splice_tests.js new file mode 100755 index 00000000000..2ee58d0c02d --- /dev/null +++ b/apps/remixdesktop/splice_tests.js @@ -0,0 +1,35 @@ +const fs = require('fs'); +const path = require('path'); + +// Directory to read files from +const testDirectory = './build-e2e/remixdesktop/test/tests/app/'; + +// Function to read files in a directory and return their paths +function getTestFiles(directory) { + return fs.readdirSync(directory) + .filter(file => file.endsWith('.test.js')) // Get only .test.js files + .map(file => path.join(directory, file)); // Return full path of each file +} + +// Function to check if a file contains a specific word +function fileContainsWord(filePath, word) { + const content = fs.readFileSync(filePath, 'utf-8'); // Read file content + return content.includes(word); // Check if word is in content +} + +// Function to filter out files that do not contain the specified word +function filterFilesByWord(files, word) { + return files.filter(file => fileContainsWord(file, word)); // Return files that do not contain the word +} + +// Get all test files in the specified directory +const testFiles = getTestFiles(testDirectory); + +// Filter out files that do not contain "@offline" +const filteredFiles = filterFilesByWord(testFiles, ''); + +// Output the list of filtered files +//console.log('Files without "@offline":', filteredFiles); +for (let i = 0; i < filteredFiles.length; i++) { + console.log(path.basename(filteredFiles[i])); +} diff --git a/apps/remixdesktop/src/engine.ts b/apps/remixdesktop/src/engine.ts index 004f2d13e14..2a92603534f 100644 --- a/apps/remixdesktop/src/engine.ts +++ b/apps/remixdesktop/src/engine.ts @@ -9,6 +9,7 @@ import { ConfigPlugin } from './plugins/configPlugin'; import { TemplatesPlugin } from './plugins/templates'; import { RipgrepPlugin } from './plugins/ripgrepPlugin'; import { CompilerLoaderPlugin } from './plugins/compilerLoader'; +import { AppUpdaterPlugin } from './plugins/appUpdater'; const engine = new Engine() const appManager = new PluginManager() @@ -19,6 +20,7 @@ const configPlugin = new ConfigPlugin() const templatesPlugin = new TemplatesPlugin() const ripgrepPlugin = new RipgrepPlugin() const compilerLoaderPlugin = new CompilerLoaderPlugin() +const appUpdaterPlugin = new AppUpdaterPlugin() engine.register(appManager) engine.register(fsPlugin) @@ -28,6 +30,7 @@ engine.register(configPlugin) engine.register(templatesPlugin) engine.register(ripgrepPlugin) engine.register(compilerLoaderPlugin) +engine.register(appUpdaterPlugin) appManager.activatePlugin('electronconfig') appManager.activatePlugin('fs') @@ -53,12 +56,6 @@ ipcMain.on('git:startclone', async (event) => { isoGitPlugin.startClone(event) }) -ipcMain.on('terminal:new', async (event) => { - console.log('new terminal') - xtermPlugin.new(event) -}) - - ipcMain.handle('getWebContentsID', (event, message) => { return event.sender.id }) diff --git a/apps/remixdesktop/src/main.ts b/apps/remixdesktop/src/main.ts index 1b75ec0216f..5b667423c8e 100644 --- a/apps/remixdesktop/src/main.ts +++ b/apps/remixdesktop/src/main.ts @@ -1,10 +1,24 @@ -import { app, BrowserWindow, dialog, Menu, MenuItem, shell, utilityProcess } from 'electron'; +import { app, BrowserWindow, dialog, Menu, MenuItem, shell, utilityProcess, screen } from 'electron'; import path from 'path'; export let isPackaged = false; export const version = app.getVersion(); +const args = process.argv.slice(1) +console.log("args", args) +export const isE2ELocal = args.find(arg => arg.startsWith('--e2e-local')) +export const isE2E = args.find(arg => arg.startsWith('--e2e')) + +if (isE2ELocal) { + console.log('e2e mode') +} +const cache_dir_arg = args.find(arg => arg.startsWith('--cache_dir=')) +export let cache_dir = '' +if (cache_dir_arg) { + cache_dir = cache_dir_arg.split('=')[1] +} + if ( process.mainModule && process.mainModule.filename.indexOf('app.asar') !== -1 @@ -17,12 +31,14 @@ if ( // get system home dir const homeDir = app.getPath('userData') + const windowSet = new Set([]); export const createWindow = async (dir?: string): Promise => { // Create the browser window. const mainWindow = new BrowserWindow({ - height: 800, - width: 1024, + height: screen.getPrimaryDisplay().size.height * 0.8, + width: screen.getPrimaryDisplay().size.width * 0.8, + frame: true, webPreferences: { preload: path.join(__dirname, 'preload.js') }, @@ -35,10 +51,10 @@ export const createWindow = async (dir?: string): Promise => { const params = dir ? `?opendir=${encodeURIComponent(dir)}` : ''; // and load the index.html of the app. mainWindow.loadURL( - process.env.NODE_ENV === 'production' || isPackaged ? `file://${__dirname}/remix-ide/index.html` + params : + (process.env.NODE_ENV === 'production' || isPackaged) && !isE2ELocal ? `file://${__dirname}/remix-ide/index.html` + params : 'http://localhost:8080' + params) - mainWindow.maximize(); + trackEvent('Instance', 'create_window', '', 1); if (dir) { mainWindow.setTitle(dir) @@ -49,6 +65,9 @@ export const createWindow = async (dir?: string): Promise => { windowSet.delete(mainWindow) }) + if(isE2E) + mainWindow.maximize() + windowSet.add(mainWindow) //mainWindow.webContents.openDevTools(); }; @@ -57,6 +76,8 @@ export const createWindow = async (dir?: string): Promise => { // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on('ready', async () => { + trackEvent('App', 'Launch', app.getVersion(), 1); + trackEvent('App', 'OS', process.platform, 1); require('./engine') }); @@ -102,6 +123,8 @@ import ViewMenu from './menus/view'; import TerminalMenu from './menus/terminal'; import HelpMenu from './menus/help'; import { execCommand } from './menus/commands'; +import main from './menus/main'; +import { trackEvent } from './utils/matamo'; const commandKeys: Record = { @@ -118,8 +141,8 @@ const menu = [...(process.platform === 'darwin' ? [darwinMenu(commandKeys, execC WindowMenu(commandKeys, execCommand, []), HelpMenu(commandKeys, execCommand), ] - -Menu.setApplicationMenu(Menu.buildFromTemplate(menu)) +if(!isE2E || isE2ELocal) + Menu.setApplicationMenu(Menu.buildFromTemplate(menu)) diff --git a/apps/remixdesktop/src/menus/file.ts b/apps/remixdesktop/src/menus/file.ts index 3693da348f6..7b48bd94f6c 100644 --- a/apps/remixdesktop/src/menus/file.ts +++ b/apps/remixdesktop/src/menus/file.ts @@ -1,22 +1,4 @@ import { BrowserWindow, MenuItemConstructorOptions, app, ipcMain } from 'electron'; -import fs from 'fs' -import os from 'os' -import path from 'path' -import { cacheDir } from '../utils/config'; - -let recentFolders: string[] = [] - -if (fs.existsSync(cacheDir + '/remixdesktop.json')) { - try { - // read the cache file - const cache = fs.readFileSync(cacheDir + '/remixdesktop.json') - const data = JSON.parse(cache.toString()) - recentFolders = data && data.recentFolders || [] - console.log('recentFolders', recentFolders) - } catch (e) { - - } -} export default ( commandKeys: Record, @@ -47,19 +29,6 @@ export default ( execCommand('template:open', focusedWindow); } }, - { - role: 'recentDocuments', - submenu: recentFolders.map((folder) => { - return { - label: folder, - click(item, focusedWindow) { - if(focusedWindow) { - ipcMain.emit('fs:openFolder', focusedWindow.webContents.id, folder); - } - } - } - }) - }, { role: 'close', accelerator: commandKeys['window:close'] diff --git a/apps/remixdesktop/src/plugins/appUpdater.ts b/apps/remixdesktop/src/plugins/appUpdater.ts new file mode 100644 index 00000000000..e7a6ff56d8a --- /dev/null +++ b/apps/remixdesktop/src/plugins/appUpdater.ts @@ -0,0 +1,126 @@ +import { ElectronBasePlugin, ElectronBasePluginClient } from "@remixproject/plugin-electron" +import { Profile } from "@remixproject/plugin-utils" +import { autoUpdater } from "electron-updater" +import { app } from 'electron'; +import { isE2E } from "../main"; +import { trackEvent } from "../utils/matamo"; + +const profile = { + displayName: 'appUpdater', + name: 'appUpdater', + description: 'appUpdater', +} + +export class AppUpdaterPlugin extends ElectronBasePlugin { + clients: AppUpdaterPluginClient[] = [] + constructor() { + console.log('AppUpdaterPlugin') + super(profile, clientProfile, AppUpdaterPluginClient) + this.methods = [...super.methods] + + autoUpdater.autoDownload = false + autoUpdater.disableDifferentialDownload = true + + autoUpdater.on('checking-for-update', () => { + console.log('Checking for update...'); + this.sendToLog('Checking for update...') + }) + autoUpdater.on('update-available', (info: any) => { + console.log('Update available.', info); + this.sendToLog('Update available.') + for (const client of this.clients) { + client.askForUpdate() + } + }) + autoUpdater.on('update-not-available', () => { + console.log('Update not available.'); + this.sendToLog('App is already up to date.') + + }) + autoUpdater.on('error', (err) => { + console.log('Error in auto-updater. ' + err); + this.sendToLog('Cannot find updates...') + }) + autoUpdater.on('download-progress', (progressObj) => { + let log_message = "Download speed: " + progressObj.bytesPerSecond; + log_message = log_message + ' - Downloaded ' + progressObj.percent + '%'; + log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')'; + console.log(log_message); + this.sendToLog(log_message) + }) + autoUpdater.on('update-downloaded', (info) => { + console.log('Update downloaded'); + this.sendToLog('Update downloaded') + this.sendToLog('processing download... please wait...') + for(const client of this.clients) { + client.downloadReady() + } + }) + } + + async sendToLog(message: string): Promise { + for (const client of this.clients) { + client.call('terminal', 'log', { + type: 'log', + value: message, + }) + } + } + +} + +const clientProfile: Profile = { + name: 'appUpdater', + displayName: 'appUpdater', + description: 'appUpdater', + methods: ['checkForUpdates', 'download', 'install'], +} + +class AppUpdaterPluginClient extends ElectronBasePluginClient { + constructor(webContentsId: number, profile: Profile) { + console.log('AppUpdaterPluginClient') + super(webContentsId, profile) + } + + async onActivation(): Promise { + console.log('onActivation', 'appUpdaterPluginClient') + this.onload(async () => { + console.log('onload', 'appUpdaterPluginClient') + this.emit('loaded') + if(isE2E) return + await this.checkForUpdates() + }) + } + + async askForUpdate(): Promise { + this.emit('askForUpdate') + } + + async downloadReady(): Promise { + // we do a wait here to make sure that the download is done, it's a bug in electron-updater + setTimeout(() => { + this.emit('downloadReady') + } + , 10000) + } + + async download(): Promise { + autoUpdater.downloadUpdate() + } + + async install(): Promise { + autoUpdater.quitAndInstall() + } + + async checkForUpdates(): Promise { + console.log('checkForUpdates') + this.call('terminal', 'log', { + type: 'log', + value: 'Remix Desktop version: ' + autoUpdater.currentVersion, + }) + trackEvent('App', 'CheckForUpdate', 'Remix Desktop version: ' + autoUpdater.currentVersion, 1); + + autoUpdater.checkForUpdates() + } +} + diff --git a/apps/remixdesktop/src/plugins/compilerLoader.ts b/apps/remixdesktop/src/plugins/compilerLoader.ts index e44653135c1..846ab4641f0 100644 --- a/apps/remixdesktop/src/plugins/compilerLoader.ts +++ b/apps/remixdesktop/src/plugins/compilerLoader.ts @@ -1,16 +1,19 @@ -import {Profile} from '@remixproject/plugin-utils' -import {ElectronBasePlugin, ElectronBasePluginClient} from '@remixproject/plugin-electron' +import { Profile } from '@remixproject/plugin-utils' +import { ElectronBasePlugin, ElectronBasePluginClient } from '@remixproject/plugin-electron' import fs from 'fs/promises' import axios from 'axios' import express from 'express' -import {cacheDir} from '../utils/config' +import { cacheDir } from '../utils/config' export const baseURLBin = 'https://binaries.soliditylang.org/bin' export const baseURLWasm = 'https://binaries.soliditylang.org/wasm' const appExpress = express() +// used in e2e tests +const useOffline = process.argv.includes('--useOffline'); + console.log('cacheDir', cacheDir) appExpress.use(express.static(cacheDir)) const server = appExpress.listen(0, () => { @@ -28,9 +31,9 @@ export class CompilerLoaderPlugin extends ElectronBasePlugin { constructor() { super(profile, clientProfile, CompilerLoaderPluginClient) this.methods = [...super.methods] - ;(async () => { - await getLists() - })() + ; (async () => { + await getLists() + })() } @@ -66,16 +69,14 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { } async onActivation(): Promise { - console.log('onActivation', 'CompilerLoaderPluginClient') this.onload(() => { - console.log('onload', 'CompilerLoaderPluginClient') this.emit('loaded') }) } async downloadCompiler(url: string): Promise { console.log('downloadCompiler', url) - if(url.includes('localhost')) return + if (url.includes('localhost')) return const plugin = this try { const fileName = url.split('/').pop() @@ -129,7 +130,7 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { async getJsonBinData() { const lists = await this.getLists() - + this.solJsonBinData = { baseURLWasm: 'http://localhost:' + (server.address() as any).port + '/compilers', baseURLBin: 'http://localhost:' + (server.address() as any).port + '/compilers', @@ -139,11 +140,11 @@ class CompilerLoaderPluginClient extends ElectronBasePluginClient { const localCompilers = await this.listCompilers() this.solJsonBinData.wasmList && (this.solJsonBinData.wasmList = this.solJsonBinData.wasmList.map((item) => { - localCompilers.includes(item.path) ? (item.wasmURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded=true) : (item.wasmURL = baseURLWasm) && (item.isDownloaded = false) + localCompilers.includes(item.path) ? (item.wasmURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded = true) : (item.wasmURL = baseURLWasm) && (item.isDownloaded = false) return item })) this.solJsonBinData.binList && (this.solJsonBinData.binList = this.solJsonBinData.binList.map((item) => { - localCompilers.includes(item.path) ? (item.binURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded=true) : (item.binURL = baseURLBin) && (item.isDownloaded = false) + localCompilers.includes(item.path) ? (item.binURL = 'http://localhost:' + (server.address() as any).port + '/compilers/') && (item.isDownloaded = true) : (item.binURL = baseURLBin) && (item.isDownloaded = false) return item })) this.emit('jsonBinDataLoaded', this.solJsonBinData) @@ -158,17 +159,19 @@ const getLists = async () => { let binData let wasmData - try { - const binRes = await axios.get(baseURLBin + '/list.json') - await fs.writeFile(cacheDir + '/binlist.json', JSON.stringify(binRes.data, null, 2)) - binData = binRes.data - } catch (e) {} - - try { - const wasmRes = await axios.get(baseURLWasm + '/list.json') - await fs.writeFile(cacheDir + '/wasmlist.json', JSON.stringify(wasmRes.data, null, 2)) - wasmData = wasmRes.data - } catch (e) {} + if (!useOffline) { + try { + const binRes = await axios.get(baseURLBin + '/list.json') + await fs.writeFile(cacheDir + '/binlist.json', JSON.stringify(binRes.data, null, 2)) + binData = binRes.data + } catch (e) { } + + try { + const wasmRes = await axios.get(baseURLWasm + '/list.json') + await fs.writeFile(cacheDir + '/wasmlist.json', JSON.stringify(wasmRes.data, null, 2)) + wasmData = wasmRes.data + } catch (e) { } + } if (!wasmData) { try { diff --git a/apps/remixdesktop/src/plugins/fsPlugin.ts b/apps/remixdesktop/src/plugins/fsPlugin.ts index 0a416b52a13..d01235de661 100644 --- a/apps/remixdesktop/src/plugins/fsPlugin.ts +++ b/apps/remixdesktop/src/plugins/fsPlugin.ts @@ -3,13 +3,16 @@ import fs from 'fs/promises' import {Profile} from '@remixproject/plugin-utils' import chokidar from 'chokidar' import {dialog, shell} from 'electron' -import {createWindow, isPackaged} from '../main' +import {createWindow, isE2E, isPackaged} from '../main' import {writeConfig} from '../utils/config' import path from 'path' import {customAction} from '@remixproject/plugin-api' import { PluginEventDataBatcher } from '../utils/pluginEventDataBatcher' - +type recentFolder = { + timestamp: number, + path: string +} const profile: Profile = { displayName: 'fs', @@ -32,7 +35,7 @@ const getBaseName = (pathName: string): string => { export class FSPlugin extends ElectronBasePlugin { clients: FSPluginClient[] = [] constructor() { - super(profile, clientProfile, FSPluginClient) + super(profile, clientProfile, isE2E? FSPluginClientE2E: FSPluginClient) this.methods = [...super.methods, 'closeWatch', 'removeCloseListener'] } @@ -200,6 +203,7 @@ class FSPluginClient extends ElectronBasePluginClient { } async exists(path: string): Promise { + if (this.workingDir === '') return false return fs .access(this.fixPath(path)) .then(() => true) @@ -257,7 +261,7 @@ class FSPluginClient extends ElectronBasePluginClient { depth: 0, }) .on('all', async (eventName, path, stats) => { - this.watcherExec(eventName, path) + this.watcherExec(eventName, convertPathToPosix(path)) }) .on('error', (error) => { watcher.close() @@ -294,7 +298,6 @@ class FSPluginClient extends ElectronBasePluginClient { } else { try { const dirname = path.dirname(pathWithoutPrefix) - //console.log('check emitting', eventName, pathWithoutPrefix, this.expandedPaths, dirname) if (this.expandedPaths.includes(dirname) || this.expandedPaths.includes(pathWithoutPrefix)) { //console.log('emitting', eventName, pathWithoutPrefix, this.expandedPaths) //this.emit('change', eventName, pathWithoutPrefix) @@ -312,11 +315,37 @@ class FSPluginClient extends ElectronBasePluginClient { } } + async convertRecentFolders(): Promise { + const config = await this.call('electronconfig' as any, 'readConfig') + if(config.recentFolders) { + + const remaps = config.recentFolders.map((f: any) => { + // if type is string + if(typeof f ==='string') { + return { + path: f, + timestamp: new Date().getTime(), + } + }else{ + return f + } + }) + + config.recentFolders = remaps + await writeConfig(config) + } + } + async updateRecentFolders(path: string): Promise { + await this.convertRecentFolders() const config = await this.call('electronconfig' as any, 'readConfig') config.recentFolders = config.recentFolders || [] config.recentFolders = config.recentFolders.filter((p: string) => p !== path) - config.recentFolders.push(path) + const timestamp = new Date().getTime() + config.recentFolders.push({ + path, + timestamp, + }) writeConfig(config) } @@ -336,16 +365,18 @@ class FSPluginClient extends ElectronBasePluginClient { } async getRecentFolders(): Promise { + await this.convertRecentFolders() const config = await this.call('electronconfig' as any, 'readConfig') - let folders: string[] = config.recentFolders || [] - folders = folders.map((f: string) => convertPathToPosix(f)) + let folders: string[] = [] + folders = (config.recentFolders || []).map((f: recentFolder) => convertPathToPosix(f.path)).sort((a: recentFolder, b: recentFolder) => a.timestamp - b.timestamp).slice(-15).reverse() return folders } async removeRecentFolder(path: string): Promise { + await this.convertRecentFolders() const config = await this.call('electronconfig' as any, 'readConfig') config.recentFolders = config.recentFolders || [] - config.recentFolders = config.recentFolders.filter((p: string) => p !== path) + config.recentFolders = config.recentFolders.filter((p: recentFolder) => p.path !== path) writeConfig(config) } @@ -389,7 +420,7 @@ class FSPluginClient extends ElectronBasePluginClient { } path = dirs && dirs.length && dirs[0] ? dirs[0] : path if (!path) return - this.workingDir = path + this.workingDir = convertPathToPosix(path) await this.updateRecentFolders(path) await this.updateOpenedFolders(path) this.window.setTitle(this.workingDir) @@ -398,13 +429,14 @@ class FSPluginClient extends ElectronBasePluginClient { } async setWorkingDir(path: string): Promise { - this.workingDir = path + console.log('setWorkingDir', path) + this.workingDir = convertPathToPosix(path) await this.updateRecentFolders(path) await this.updateOpenedFolders(path) this.window.setTitle(getBaseName(this.workingDir)) this.watch() this.emit('workingDirChanged', path) - await this.call('fileManager', 'closeAllFiles') + return } async revealInExplorer(action: customAction, isAbsolutePath: boolean = false): Promise { @@ -433,3 +465,43 @@ class FSPluginClient extends ElectronBasePluginClient { createWindow(path) } } + +import os from 'os' +export class FSPluginClientE2E extends FSPluginClient { + constructor(webContentsId: number, profile: Profile) { + super(webContentsId, profile) + } + + async selectFolder(dir?: string, title?: string, button?: string): Promise { + if (!dir) { + // create random directory on os homedir + const randomdir = path.join(os.homedir(), 'remix-tests' + Date.now().toString()) + await fs.mkdir(randomdir) + return randomdir + } + if (!dir) return '' + return dir + } + + async openFolder(dir?: string): Promise { + dir = await this.selectFolder(dir) + + await this.updateRecentFolders(dir) + await this.updateOpenedFolders(dir) + if (!dir) return + + this.openWindow(dir) + } + + async openFolderInSameWindow(dir?: string): Promise { + dir = await this.selectFolder(dir) + if (!dir) return + this.workingDir = convertPathToPosix(dir) + await this.updateRecentFolders(dir) + await this.updateOpenedFolders(dir) + this.window.setTitle(this.workingDir) + this.watch() + this.emit('workingDirChanged', dir) + } + +} diff --git a/apps/remixdesktop/src/plugins/isoGitPlugin.ts b/apps/remixdesktop/src/plugins/isoGitPlugin.ts index 62a3451a63c..283cad07780 100644 --- a/apps/remixdesktop/src/plugins/isoGitPlugin.ts +++ b/apps/remixdesktop/src/plugins/isoGitPlugin.ts @@ -12,7 +12,8 @@ const profile: Profile = { displayName: 'isogit', description: 'isogit plugin', } - +// used in e2e tests +const useIsoGit = process.argv.includes('--useIsoGit'); export class IsoGitPlugin extends ElectronBasePlugin { clients: IsoGitPluginClient[] = [] constructor() { @@ -60,7 +61,7 @@ class IsoGitPluginClient extends ElectronBasePluginClient { this.gitIsInstalled = await gitProxy.version() ? true : false }) this.workingDir = await this.call('fs' as any, 'getWorkingDir') - this.gitIsInstalled = await gitProxy.version() ? true : false + this.gitIsInstalled = await gitProxy.version() && !useIsoGit ? true : false }) } @@ -335,6 +336,7 @@ class IsoGitPluginClient extends ElectronBasePluginClient { } } else { try { + this.call('terminal' as any, 'log', 'Cloning using builtin git... please wait.') const clone = await git.clone({ ...await this.getGitConfig(), ...cmd, diff --git a/apps/remixdesktop/src/plugins/ripgrepPlugin.ts b/apps/remixdesktop/src/plugins/ripgrepPlugin.ts index 4b620bb5969..f0d3d822855 100644 --- a/apps/remixdesktop/src/plugins/ripgrepPlugin.ts +++ b/apps/remixdesktop/src/plugins/ripgrepPlugin.ts @@ -1,10 +1,9 @@ -import {PluginClient} from '@remixproject/plugin' -import {Profile} from '@remixproject/plugin-utils' -import {ElectronBasePlugin, ElectronBasePluginClient} from '@remixproject/plugin-electron' +import { Profile } from '@remixproject/plugin-utils' +import { ElectronBasePlugin, ElectronBasePluginClient } from '@remixproject/plugin-electron' import path from 'path' -import {rgPath} from '@vscode/ripgrep' +import { rgPath } from '@vscode/ripgrep' import byline from 'byline' -import {spawn} from 'child_process' +import { spawn } from 'child_process' import { SearchInWorkspaceOptions } from '../lib' const profile: Profile = { @@ -69,14 +68,14 @@ export class RipgrepPluginClient extends ElectronBasePluginClient { if (opts && opts.include) { for (const include of opts.include) { if (include !== '') { - globs.push('--glob=' + include) + globs.push('--glob=' + include + '') } } } if (opts && opts.exclude) { for (const exclude of opts.exclude) { if (exclude !== '') { - globs.push('--glob=!=' + exclude) + globs.push('--glob=!' + exclude + '') } } } @@ -85,29 +84,37 @@ export class RipgrepPluginClient extends ElectronBasePluginClient { // replace packed app path with unpacked app path for release on windows const customRgPath = rgPath.includes('app.asar.unpacked') ? rgPath : rgPath.replace('app.asar', 'app.asar.unpacked') + console.log('customRgPath', [...globs, ...args, opts.pattern, '.'], path) + const rg = spawn(customRgPath, [...globs, ...args, opts.pattern, '.'], { + cwd: path + }); - const rg = spawn(customRgPath, [...globs, ...args, opts.pattern, path]) const resultrg: any[] = [] const stream = byline(rg.stdout.setEncoding('utf8')) stream.on('data', (rgresult: string) => { - let pathWithoutWorkingDir = rgresult.replace(convertPathToPosix(this.workingDir), '') + console.log('rgresult', rgresult, convertPathToPosix(this.workingDir), convertPathToPosix(rgresult)) + let pathWithoutWorkingDir = convertPathToPosix(rgresult).replace(convertPathToPosix(this.workingDir), '') + console.log(pathWithoutWorkingDir) if (pathWithoutWorkingDir.endsWith('/')) { pathWithoutWorkingDir = pathWithoutWorkingDir.slice(0, -1) } if (pathWithoutWorkingDir.startsWith('/')) { pathWithoutWorkingDir = pathWithoutWorkingDir.slice(1) } + if (pathWithoutWorkingDir.startsWith('./')) { + pathWithoutWorkingDir = pathWithoutWorkingDir.slice(2) + } if (pathWithoutWorkingDir.startsWith('\\')) { pathWithoutWorkingDir = pathWithoutWorkingDir.slice(1) } resultrg.push({ - path: convertPathToPosix(pathWithoutWorkingDir), + path: pathWithoutWorkingDir, isDirectory: false, }) }) - stream.on('end', () => { + stream.on('end', () => { c(resultrg) }) }) diff --git a/apps/remixdesktop/src/plugins/templates.ts b/apps/remixdesktop/src/plugins/templates.ts index aefadcae1bb..62cce1caf27 100644 --- a/apps/remixdesktop/src/plugins/templates.ts +++ b/apps/remixdesktop/src/plugins/templates.ts @@ -42,20 +42,26 @@ class TemplatesPluginClient extends ElectronBasePluginClient { super(webContentsId, profile) } - async loadTemplateInNewWindow (files: any) { + async loadTemplateInNewWindow(files: any) { - let folder = await this.call('fs' as any, 'selectFolder', null ,'Select or create a folder to load the template in', 'Set as destination folder for the template') + let folder = await this.call('fs' as any, 'selectFolder', null, 'Select or create a folder to load the files in', 'Set as destination folder for the files') if (!folder || folder === '') return // @ts-ignore for (const file in files) { try { - if(!folder.endsWith('/')) folder += '/' - - await fs.mkdir(path.dirname(folder + file), { recursive: true}) - await fs.writeFile(folder + file, files[file], { - encoding: 'utf8' - }) + if (!folder.endsWith('/')) folder += '/' + + await fs.mkdir(path.dirname(folder + file), { recursive: true }) + if (typeof files[file] !== 'string' && files[file].content) { + await fs.writeFile(folder + file, files[file].content, { + encoding: 'utf8', + }) + } else { + await fs.writeFile(folder + file, files[file], { + encoding: 'utf8' + }) + } } catch (error) { console.error(error) } @@ -63,7 +69,7 @@ class TemplatesPluginClient extends ElectronBasePluginClient { createWindow(folder) } - async openTemplate(){ + async openTemplate() { this.call('filePanel' as any, 'loadTemplate') } diff --git a/apps/remixdesktop/src/plugins/xtermPlugin.ts b/apps/remixdesktop/src/plugins/xtermPlugin.ts index 4b5b6c6e162..8bbfdf629b2 100644 --- a/apps/remixdesktop/src/plugins/xtermPlugin.ts +++ b/apps/remixdesktop/src/plugins/xtermPlugin.ts @@ -1,5 +1,5 @@ -import {PluginClient} from '@remixproject/plugin' -import {Profile} from '@remixproject/plugin-utils' +import { PluginClient } from '@remixproject/plugin' +import { Profile } from '@remixproject/plugin-utils' import { ElectronBasePlugin, ElectronBasePluginClient, @@ -8,25 +8,25 @@ import { import os from 'os' import * as pty from 'node-pty' import process from 'node:process' -import {userInfo} from 'node:os' -import {findExecutable} from '../utils/findExecutable' -import {spawnSync} from 'child_process' +import { userInfo } from 'node:os' +import { findExecutable } from '../utils/findExecutable' +import { spawnSync } from 'child_process' import { stripAnsi } from '../lib' import { DataBatcher } from '../lib/databatcher' export const detectDefaultShell = () => { - const {env} = process + const { env } = process if (process.platform === 'win32') { return env.SHELL || 'powershell.exe' } try { - const {shell} = userInfo() + const { shell } = userInfo() if (shell) { return shell } - } catch {} + } catch { } if (process.platform === 'darwin') { return env.SHELL || '/bin/zsh' @@ -81,7 +81,9 @@ export class XtermPlugin extends ElectronBasePlugin { new(webContentsId: any): void { const client = this.clients.find((c) => c.webContentsId === webContentsId) + console.log('new terminal', webContentsId) if (client) { + console.log('client exists') client.new() } } @@ -104,6 +106,7 @@ class XtermPluginClient extends ElectronBasePluginClient { terminals: pty.IPty[] = [] dataBatchers: DataBatcher[] = [] workingDir: string = '' + parsedEnv: any = null constructor(webContentsId: number, profile: Profile) { super(webContentsId, profile) this.onload(async () => { @@ -114,6 +117,13 @@ class XtermPluginClient extends ElectronBasePluginClient { this.workingDir = await this.call('fs' as any, 'getWorkingDir') console.log('workingDir', this.workingDir) }) + + if (!(process.platform === 'win32')) { + const { stdout } = spawnSync(defaultShell, getShellEnvArgs, { + encoding: 'utf8', + }) + this.parsedEnv = parseEnv(stdout) + } } async keystroke(key: string, pid: number): Promise { @@ -123,7 +133,7 @@ class XtermPluginClient extends ElectronBasePluginClient { async getShells(): Promise { if (os.platform() === 'win32') { let bash = await findExecutable('bash.exe') - if(bash.length === 0) { + if (bash.length === 0) { bash = await findExecutable('bash.exe', undefined, [process.env['ProgramFiles'] + '\\Git\\bin']) } if (bash) { @@ -137,48 +147,61 @@ class XtermPluginClient extends ElectronBasePluginClient { } async createTerminal(path?: string, shell?: string): Promise { - let parsedEnv: any = null - if (!(process.platform === 'win32')) { - const {stdout} = spawnSync(defaultShell, getShellEnvArgs, { - encoding: 'utf8', - }) - parsedEnv = parseEnv(stdout) - } + const start_time = Date.now() + console.log('createTerminal', path, shell || defaultShell) + - const env = parsedEnv || process.env + const env = this.parsedEnv || process.env const ptyProcess = pty.spawn(shell || defaultShell, [], { name: 'xterm-color', cols: 80, rows: 20, - cwd: path || process.cwd(), + cwd: path || this.workingDir || process.cwd(), env: env, - }) + encoding: 'utf8', + }); const dataBatcher = new DataBatcher(ptyProcess.pid) + this.dataBatchers[ptyProcess.pid] = dataBatcher ptyProcess.onData((data: string) => { + //console.log('data', data) dataBatcher.write(Buffer.from(data)) - //this.sendData(data, ptyProcess.pid) + }) + ptyProcess.onExit(() => { + const pid = ptyProcess.pid + this.closeTerminal(pid) }) dataBatcher.on('flush', (data: string, uid: number) => { this.sendData(data, uid) }) this.terminals[ptyProcess.pid] = ptyProcess - + const end_time = Date.now() + console.log('createTerminal', end_time - start_time) return ptyProcess.pid } async closeTerminal(pid: number): Promise { - this.terminals[pid].kill() - delete this.terminals[pid] + if (this.terminals) { + if (this.terminals[pid]) { + try { + this.terminals[pid].kill() + } catch (err) { + // ignore + } + delete this.terminals[pid] + } + if (this.dataBatchers[pid]) + delete this.dataBatchers[pid] + } this.emit('close', pid) } - async resize({cols, rows}: {cols: number; rows: number}, pid: number) { + async resize({ cols, rows }: { cols: number; rows: number }, pid: number) { if (this.terminals[pid]) { try { this.terminals[pid].resize(cols, rows) } catch (_err) { - const err = _err as {stack: any} + const err = _err as { stack: any } console.error(err.stack) } } else { @@ -199,8 +222,6 @@ class XtermPluginClient extends ElectronBasePluginClient { } async new(): Promise { - console.log('new terminal') - const pid = await this.createTerminal(this.workingDir) - this.emit('new', pid) + this.emit('new') } } diff --git a/apps/remixdesktop/src/preload.ts b/apps/remixdesktop/src/preload.ts index 007fe098e99..c5c8e5a65dd 100644 --- a/apps/remixdesktop/src/preload.ts +++ b/apps/remixdesktop/src/preload.ts @@ -6,7 +6,7 @@ console.log('preload.ts', new Date().toLocaleTimeString()) /* preload script needs statically defined API for each plugin */ -const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader'] +const exposedPLugins = ['fs', 'git', 'xterm', 'isogit', 'electronconfig', 'electronTemplates', 'ripgrep', 'compilerloader', 'appUpdater'] let webContentsId: number | undefined diff --git a/apps/remixdesktop/src/tools/git.ts b/apps/remixdesktop/src/tools/git.ts index a85d036997e..841ba952b0f 100644 --- a/apps/remixdesktop/src/tools/git.ts +++ b/apps/remixdesktop/src/tools/git.ts @@ -40,7 +40,7 @@ export const gitProxy = { clone: async (url: string, path: string) => { - const { stdout, stderr } = await execAsync(`git clone ${url} ${path}`); + const { stdout, stderr } = await execAsync(`git clone ${url} "${path}"`); }, async push(path: string, remote: string, src: string, branch: string, force: boolean = false) { diff --git a/apps/remixdesktop/src/utils/config.ts b/apps/remixdesktop/src/utils/config.ts index 4cbb17a3e0d..df7b8c8d153 100644 --- a/apps/remixdesktop/src/utils/config.ts +++ b/apps/remixdesktop/src/utils/config.ts @@ -4,7 +4,7 @@ import path from 'path' export const cacheDir = path.join(os.homedir(), '.cache_remix_ide') -console.log('cacheDir', cacheDir) +console.log('cache dir is:', cacheDir) export const createDefaultConfigLocations = async() => { try { diff --git a/apps/remixdesktop/src/utils/matamo.ts b/apps/remixdesktop/src/utils/matamo.ts new file mode 100644 index 00000000000..3688bab72ea --- /dev/null +++ b/apps/remixdesktop/src/utils/matamo.ts @@ -0,0 +1,32 @@ +import { isE2E } from "../main"; +import { isPackaged } from "../main"; + +var MatomoTracker = require('matomo-tracker'); + +// Function to send events to Matomo +export function trackEvent(category: string, action: string, name: string, value: string | number): void { + var matomo = new MatomoTracker(35, 'http://ethereumfoundation.matomo.cloud/matomo.php'); + matomo.on('error', function (err: any) { + console.log('error tracking request: ', err); + }); + + if ((process.env.NODE_ENV === 'production' || isPackaged) && !isE2E) { + matomo.track({ + e_c: category, + e_a: action, + e_n: name, + e_v: value, + url: 'https://github.com/remix-project-org/remix-desktop' + // You can add other parameters if needed + }, (error: any) => { + if (error) { + console.error('Error tracking event:', error); + } else { + console.log('Event tracked successfully'); + } + }); + } + +} + + diff --git a/apps/remixdesktop/test/cache_dir/remixdesktop.json b/apps/remixdesktop/test/cache_dir/remixdesktop.json new file mode 100644 index 00000000000..a50cbdd2f55 --- /dev/null +++ b/apps/remixdesktop/test/cache_dir/remixdesktop.json @@ -0,0 +1,2 @@ +{"openedFolders":["/home/bunsen/Documents/remix-reward"], +"recentFolders":["/home/bunsen/Documents/remix-reward"]} \ No newline at end of file diff --git a/apps/remixdesktop/test/nighwatch.app.ts b/apps/remixdesktop/test/nighwatch.app.ts new file mode 100644 index 00000000000..111fa7bbd36 --- /dev/null +++ b/apps/remixdesktop/test/nighwatch.app.ts @@ -0,0 +1,99 @@ +import os from 'os'; +import fs from 'fs'; + + + +const useIsoGit = process.argv.includes('--useIsoGit'); +const useOffline = process.argv.includes('--useOffline'); + +// Function to read JSON file synchronously +function readJSONFileSync(filename: string): any { + try { + const data = fs.readFileSync(filename, 'utf8'); + return JSON.parse(data); + } catch (err) { + throw err; + } +} + +const packageData: any = readJSONFileSync('package.json'); +const version = packageData.version; + +let channel: string = '' + +if (version.includes('beta')) { + channel = 'Beta'; +} else if (version.includes('alpha')) { + channel = 'Alpha'; +} else if (version.includes('insiders')) { + channel = 'Insiders'; +} + +// Determine if running on CircleCI or locally with --e2e-local +const isLocalE2E = process.argv.includes('--e2e-local') && !process.env.CIRCLECI; + +module.exports = { + src_folders: ['build-e2e/remixdesktop/test/tests/app'], + output_folder: './reports/tests', + custom_commands_path: ['build-e2e/remix-ide-e2e/src/commands'], + page_objects_path: '', + globals_path: '', + test_settings: { + default: { + enable_fail_fast: true, + selenium_port: 4444, + selenium_host: 'localhost', + globals: { + waitForConditionTimeout: 10000, + asyncHookTimeout: 100000 + }, + screenshots: { + enabled: true, + path: './reports/screenshots', + on_failure: true, + on_error: true + }, + webdriver: { + start_process: true, + timeout_options: { + timeout: 60000, + retry_attempts: 3 + } + }, + desiredCapabilities: { + browserName: 'chrome', + javascriptEnabled: true, + acceptSslCerts: true, + 'goog:chromeOptions': (() => { + const type = os.type(); + const arch = os.arch(); + let binaryPath = ""; + // Check if running on CircleCI or locally + let args = process.env.CIRCLECI ? ["--e2e"] : ["--e2e-local"]; + + if(useIsoGit) args = [...args, '--useIsoGit']; + if(useOffline) args = [...args, '--useOffline']; + + switch (type) { + case 'Windows_NT': + binaryPath = `./release/win-unpacked/Remix-Desktop-${channel}.exe`; + break; + case 'Darwin': + binaryPath = arch === 'x64' ? + `release/mac/Remix-Desktop-${channel}.app/Contents/MacOS/Remix-Desktop-${channel}` : + `release/mac-arm64/Remix-Desktop-${channel}.app/Contents/MacOS/Remix-Desktop-${channel}`; + break; + case 'Linux': + binaryPath = "release/linux-unpacked/remixdesktop"; + break; + } + + return { + binary: binaryPath, + args: args + }; + })() + } + } + } +}; diff --git a/apps/remixdesktop/test/tests/app/compiler.test.ts b/apps/remixdesktop/test/tests/app/compiler.test.ts new file mode 100644 index 00000000000..2fce46320c1 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/compiler.test.ts @@ -0,0 +1,37 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'download compiler': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .clickLaunchIcon('solidity') + .pause(1000) + .setSolidityCompilerVersion('soljson-v0.8.23+commit.f704f362.js') + .waitForElementVisible({ + selector: "//*[@data-id='selectedVersion' and contains(.,'0.8.23+commit.f704f362')]", + locateStrategy: 'xpath' + }) + .waitForElementContainsText('*[data-id="terminalJournal"]', 'Compiler downloaded from https://binaries.soliditylang.org/wasm/soljson-v0.8.23+commit.f704f362.js to soljson-v0.8.23+commit.f704f362.js', 10000) + .waitForElementPresent({ + selector: + "//a[@data-id='dropdown-item-soljson-v0.8.23+commit.f704f362.js']//*[contains(@class, 'fa-arrow-circle-down')]", + locateStrategy: 'xpath' + }) + + }, + 'refresh': function (browser: NightwatchBrowser) { + browser.refresh() + .clickLaunchIcon('solidity') + .waitForElementVisible('*[data-id="versionSelector"]') + .click('*[data-id="versionSelector"]') + .waitForElementPresent({ + selector: + "//a[@data-id='dropdown-item-soljson-v0.8.23+commit.f704f362.js']//*[contains(@class, 'fa-arrow-circle-down')]", + locateStrategy: 'xpath' + }) + } +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/externaleditor.test.ts b/apps/remixdesktop/test/tests/app/externaleditor.test.ts new file mode 100644 index 00000000000..89e991fdcde --- /dev/null +++ b/apps/remixdesktop/test/tests/app/externaleditor.test.ts @@ -0,0 +1,122 @@ +import {NightwatchBrowser} from 'nightwatch' + +const testsBash = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + open: function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]') + }, + 'open xterm linux and create a file': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible('*[data-type="remixUIXT"]', 10000) + .click('*[data-type="remixUIXT"]') + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('mkdir dir && cd dir && echo "test" >> example.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdir"]', 10000) + .openFile('dir') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdir/example.txt"]', 10000) + .openFile('dir/example.txt') + .getEditorValue((result) => { + browser.assert.equal(result, 'test\n') + }) + .waitForElementVisible('*[data-type="remixUIXT"]', 10000) + .click('*[data-type="remixUIXT"]') + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('echo "123" >> example.txt').sendKeys(this.Keys.ENTER) + }) + .pause(1000) + .getEditorValue((result) => { + browser.assert.equal(result, 'test\n123\n') + }) + .setEditorValue('somethinginthere') + .pause(1000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('cat example.txt').sendKeys(this.Keys.ENTER) + }) + .pause(1000) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('somethinginthere')) + } + ) + }, +} + +const testsWindows = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + open: function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]') + }, + 'open xterm window and create a file': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible('*[data-id="select_shell"]') + .click('*[data-id="select_shell"]') + .waitForElementVisible('*[data-id="select_powershell.exe"]') + .click('*[data-id="select_powershell.exe"]') + .pause(3000) + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .pause(1000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('New-Item -ItemType Directory -Name "dir" ; Set-Location -Path "./dir" ; Add-Content -Path "example.txt" -Value "test" -Encoding UTF8').sendKeys(this.Keys.ENTER) + }) + .pause(1000) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdir"]', 10000) + .openFile('dir') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdir/example.txt"]', 10000) + .openFile('dir/example.txt').pause(1000) + .getEditorValue((result) => { + browser.assert.equal(result, 'test\r\n') + }) + .pause(1000) + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('Add-Content -Path "example.txt" -Value "123" -Encoding UTF8').sendKeys(this.Keys.ENTER) + }) + .pause(1000) + .getEditorValue((result) => { + browser.assert.equal(result, 'test\r\n123\r\n') + }) + .setEditorValue('somethinginthere') + .pause(1000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('Get-Content example.txt').sendKeys(this.Keys.ENTER) + }).pause(1000) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('somethinginthere')) + } + ) + } +} + +module.exports = { + ...process.platform.startsWith('win')?testsWindows:testsBash +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/gist.test.ts b/apps/remixdesktop/test/tests/app/gist.test.ts new file mode 100644 index 00000000000..ecda3b8cee5 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/gist.test.ts @@ -0,0 +1,29 @@ +import { NightwatchBrowser } from 'nightwatch' + +const gist_id = '02a847917a6a7ecaf4a7e0d4e68715bf' +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'start gist': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('*[data-id="landingPageImportFromGist"]') + .click('*[data-id="landingPageImportFromGist"]') + .waitForElementVisible('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]') + .execute(function () { + (document.querySelector('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() + }) + .setValue('*[data-id="gisthandlerModalDialogModalBody-react"] input[data-id="modalDialogCustomPromp"]', gist_id) + .modalFooterOKClick('gisthandler') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewDivtreeViewItemREADME.txt"]') + }) + .click('[data-id="treeViewLitreeViewItemcontracts"]') + .openFile('contracts/3_Ballot.sol') + .end() + } +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/git.test.ts b/apps/remixdesktop/test/tests/app/git.test.ts new file mode 100644 index 00000000000..9cc26be3d03 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/git.test.ts @@ -0,0 +1,28 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + '@isogit': true, + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'clone a repo': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('button[data-id="landingPageImportFromGit"]') + .click('button[data-id="landingPageImportFromGit"]') + .pause(1000) + .waitForElementVisible('[data-id="fileSystemModalDialogModalBody-react"]') + .click('[data-id="fileSystemModalDialogModalBody-react"]') + .waitForElementVisible('[data-id="modalDialogCustomPromptTextClone"]') + .setValue('[data-id="modalDialogCustomPromptTextClone"]', 'https://github.com/ethereum/awesome-remix') + .click('[data-id="fileSystem-modal-footer-ok-react"]') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewLitreeViewItem.git"]') + }) + .end() + } +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/offline.test.ts b/apps/remixdesktop/test/tests/app/offline.test.ts new file mode 100644 index 00000000000..040e587e5e6 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/offline.test.ts @@ -0,0 +1,46 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + '@offline': true, + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'open default template': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('button[data-id="landingPageImportFromTemplate"]') + .click('button[data-id="landingPageImportFromTemplate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + .click('*[data-id="treeViewLitreeViewItemtests"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') + .click('*[data-id="treeViewLitreeViewItemcontracts"]') + .waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .openFile('contracts/1_Storage.sol') + .waitForElementVisible('*[id="editorView"]', 10000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('function retrieve() public view returns (uint256){')) + }) + }) + }, + 'compile storage': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('solidity') + .pause(1000) + .waitForElementVisible('*[data-id="compilerContainerCompileBtn"]') + .click('[data-id="compilerContainerCompileBtn"]') + .clickLaunchIcon('filePanel') + .clickLaunchIcon('solidity') + .pause(5000) + .waitForElementPresent('*[data-id="compiledContracts"] option', 60000) + .click('*[data-id="compilation-details"]') + .waitForElementVisible('*[data-id="remixui_treeviewitem_metadata"]') + } +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/search.test.ts b/apps/remixdesktop/test/tests/app/search.test.ts new file mode 100644 index 00000000000..3a10ff583e9 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/search.test.ts @@ -0,0 +1,264 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'open default template': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('button[data-id="landingPageImportFromTemplate"]') + .click('button[data-id="landingPageImportFromTemplate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + .click('*[data-id="treeViewLitreeViewItemtests"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') + .click('*[data-id="treeViewLitreeViewItemcontracts"]') + .waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .openFile('contracts/1_Storage.sol') + .waitForElementVisible('*[id="editorView"]', 10000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('function retrieve() public view returns (uint256){')) + }) + }) + }, + 'Should find text #group1': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="remixIdeSidePanel"]') + .click('*[plugin="search"]').waitForElementVisible('*[id="search_input"]') + .waitForElementVisible('*[id="search_include"]') + .setValue('*[id="search_include"]', ', *.*').pause(2000) + .setValue('*[id="search_input"]', 'read').sendKeys('*[id="search_input"]', browser.Keys.ENTER) + .pause(1000) + .waitForElementContainsText('*[data-id="search_results"]', '3_BALLOT.SOL', 60000) + .waitForElementContainsText('*[data-id="search_results"]', 'contracts', 60000) + .waitForElementContainsText('*[data-id="search_results"]', 'README.TXT', 60000) + .waitForElementContainsText('*[data-id="search_results"]', 'file must') + .waitForElementContainsText('*[data-id="search_results"]', 'be compiled') + .waitForElementContainsText('*[data-id="search_results"]', 'that person al') + .waitForElementContainsText('*[data-id="search_results"]', 'sender.voted') + .waitForElementContainsText('*[data-id="search_results"]', 'read') + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 6) + }) + }, 'Should find text with exclude #group1': function (browser: NightwatchBrowser) { + browser + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'contract').pause(1000) + .clearValue('*[id="search_include"]').pause(2000) + .setValue('*[id="search_include"]', '**').sendKeys('*[id="search_include"]', browser.Keys.ENTER).pause(4000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 62) + }) + .setValue('*[id="search_exclude"]', ',contracts/**').sendKeys('*[id="search_exclude"]', browser.Keys.ENTER).pause(4000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 56) + }) + .clearValue('*[id="search_include"]').setValue('*[id="search_include"]', '*.sol, *.js, *.txt') + .clearValue('*[id="search_exclude"]').setValue('*[id="search_exclude"]', '.*/**/*') + }, + 'Should find regex #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[id="search_input"]') + .clearValue('*[id="search_input"]').pause(2000) + .setValue('*[id="search_input"]', '^contract').sendKeys('*[id="search_input"]', browser.Keys.ENTER).pause(3000) + .waitForElementVisible('*[data-id="search_use_regex"]').click('*[data-id="search_use_regex"]').pause(3000) + .waitForElementContainsText('*[data-id="search_results"]', '3_BALLOT.SOL', 60000) + .waitForElementContainsText('*[data-id="search_results"]', '2_OWNER.SOL', 60000) + .waitForElementContainsText('*[data-id="search_results"]', '1_STORAGE.SOL', 60000) + .waitForElementContainsText('*[data-id="search_results"]', 'BALLOT_TEST.SOL', 60000) + .waitForElementContainsText('*[data-id="search_results"]', 'tests', 60000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 4) + }) + }, + 'Should find matchcase #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="search_use_regex"]').click('*[data-id="search_use_regex"]') + .waitForElementVisible('*[data-id="search_case_sensitive"]').click('*[data-id="search_case_sensitive"]').pause(4000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 0) + }) + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'Contract').sendKeys('*[id="search_input"]', browser.Keys.ENTER).pause(3000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 3) + }) + .waitForElementContainsText('*[data-id="search_results"]', 'STORAGE.TEST.JS', 60000) + }, + 'Should find matchword #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="search_case_sensitive"]').click('*[data-id="search_case_sensitive"]') + .waitForElementVisible('*[data-id="search_whole_word"]').click('*[data-id="search_whole_word"]').pause(2000) + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'contract').sendKeys('*[id="search_input"]', browser.Keys.ENTER).pause(4000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 15) + }) + }, + 'Should replace text #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="toggle_replace"]').click('*[data-id="toggle_replace"]') + .waitForElementVisible('*[id="search_replace"]') + .setValue('*[id="search_replace"]', 'replacing').sendKeys('*[id="search_replace"]', browser.Keys.ENTER).pause(1000) + .waitForElementVisible('*[data-id="contracts/2_Owner.sol-33-71"]') + .moveToElement('*[data-id="contracts/2_Owner.sol-33-71"]', 10, 10) + .waitForElementVisible('*[data-id="replace-contracts/2_Owner.sol-33-71"]') + .click('*[data-id="replace-contracts/2_Owner.sol-33-71"]').pause(2000). + modalFooterOKClick('confirmreplace').pause(2000). + getEditorValue((content) => { + browser.assert.ok(content.includes('replacing deployer for a constructor'), 'should replace text ok') + }) + }, + 'Should replace text without confirmation #group1': function (browser: NightwatchBrowser) { + browser.click('*[data-id="confirm_replace_label"]').pause(500) + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'replacing').sendKeys('*[id="search_input"]', browser.Keys.ENTER).pause(1000) + .setValue('*[id="search_replace"]', 'replacing2').pause(1000) + .waitForElementVisible('*[data-id="contracts/2_Owner.sol-33-71"]') + .moveToElement('*[data-id="contracts/2_Owner.sol-33-71"]', 10, 10) + .waitForElementVisible('*[data-id="replace-contracts/2_Owner.sol-33-71"]') + .click('*[data-id="replace-contracts/2_Owner.sol-33-71"]').pause(2000). + getEditorValue((content) => { + browser.assert.ok(content.includes('replacing2 deployer for a constructor'), 'should replace text ok') + }) + }, + 'Should replace all & undo #group1': function (browser: NightwatchBrowser) { + browser + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'storage').sendKeys('*[id="search_input"]', browser.Keys.ENTER) + .clearValue('*[id="search_replace"]') + .setValue('*[id="search_replace"]', '123test').pause(1000) + .waitForElementVisible('*[data-id="replace-all-contracts/1_Storage.sol"]') + .click('*[data-id="replace-all-contracts/1_Storage.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('contract 123test'), 'should replace text ok') + browser.assert.ok(content.includes('title 123test'), 'should replace text ok') + }) + .waitForElementVisible('*[data-id="undo-replace-contracts/1_Storage.sol"]') + .click('*[data-id="undo-replace-contracts/1_Storage.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('contract Storage'), 'should undo text ok') + browser.assert.ok(content.includes('title Storage'), 'should undo text ok') + }) + }, + 'Should replace all & undo & switch between files #group1': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[id="search_input"]') + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', 'storage').sendKeys('*[id="search_input"]', browser.Keys.ENTER) + .clearValue('*[id="search_replace"]') + .setValue('*[id="search_replace"]', '123test').pause(1000) + .waitForElementVisible('*[data-id="replace-all-contracts/1_Storage.sol"]') + .click('*[data-id="replace-all-contracts/1_Storage.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('contract 123test'), 'should replace text ok') + browser.assert.ok(content.includes('title 123test'), 'should replace text ok') + }) + .waitForElementVisible('*[data-id="undo-replace-contracts/1_Storage.sol"]') + .openFile('README.txt') + .click('*[plugin="search"]').pause(2000) + .waitForElementNotPresent('*[data-id="undo-replace-contracts/1_Storage.sol"]') + .waitForElementVisible('*[data-id="replace-all-README.txt"]') + .click('*[data-id="replace-all-README.txt"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes("123test' contract"), 'should replace text ok') + }) + .waitForElementVisible('*[data-id="undo-replace-README.txt"]') + .click('div[data-path="/contracts/1_Storage.sol"]').pause(2000) + .waitForElementVisible('*[data-id="undo-replace-contracts/1_Storage.sol"]') + .click('*[data-id="undo-replace-contracts/1_Storage.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('contract Storage'), 'should undo text ok') + browser.assert.ok(content.includes('title Storage'), 'should undo text ok') + }) + .click('div[data-path="/README.txt"]').pause(2000) + .waitForElementVisible('*[data-id="undo-replace-README.txt"]') + .click('*[data-id="undo-replace-README.txt"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes("Storage' contract"), 'should replace text ok') + }) + }, + 'Should hide button when edited content is the same #group2': function (browser: NightwatchBrowser) { + browser.refresh() + .waitForElementVisible('*[data-id="remixIdeSidePanel"]') + .addFile('test.sol', { content: '123' }) + .pause(4000) + .click('*[plugin="search"]') + .waitForElementVisible('*[id="search_input"]') + .waitForElementVisible('*[data-id="toggle_replace"]') + .click('*[data-id="toggle_replace"]') + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', '123') + .sendKeys('*[id="search_input"]', browser.Keys.ENTER) + .waitForElementVisible('*[id="search_replace"]') + .clearValue('*[id="search_replace"]') + .setValue('*[id="search_replace"]', '456').pause(1000) + .click('*[data-id="confirm_replace_label"]').pause(500) + .waitForElementVisible('*[data-id="replace-all-test.sol"]') + .click('*[data-id="replace-all-test.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('456'), 'should replace text ok') + } + ) + .setEditorValue('123') + .getEditorValue((content) => { + browser.assert.ok(content.includes('123'), 'should have text ok') + } + ).pause(5000) + .waitForElementNotPresent('*[data-id="undo-replace-test.sol"]') + }, + 'Should disable/enable button when edited content changed #group2': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[id="search_input"]') + .clearValue('*[id="search_input"]') + .clearValue('*[id="search_input"]') + .setValue('*[id="search_input"]', '123').sendKeys('*[id="search_input"]', browser.Keys.ENTER) + .clearValue('*[id="search_replace"]') + .setValue('*[id="search_replace"]', 'replaced').pause(1000) + .waitForElementVisible('*[data-id="replace-all-test.sol"]') + .click('*[data-id="replace-all-test.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('replaced'), 'should replace text ok') + } + ) + .setEditorValue('changed') + .getEditorValue((content) => { + browser.assert.ok(content.includes('changed'), 'should have text ok') + } + ).pause(5000) + .waitForElementVisible('*[data-id="undo-replace-test.sol"]') + .getAttribute('[data-id="undo-replace-test.sol"]', 'disabled', (result) => { + browser.assert.equal(result.value, 'true', 'should be disabled') + }) + .setEditorValue('replaced') + .getEditorValue((content) => { + browser.assert.ok(content.includes('replaced'), 'should have text ok') + } + ).pause(1000) + .waitForElementVisible('*[data-id="undo-replace-test.sol"]') + .getAttribute('[data-id="undo-replace-test.sol"]', 'disabled', (result) => { + browser.assert.equal(result.value, null, 'should not be disabled') + }) + .click('*[data-id="undo-replace-test.sol"]').pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('123'), 'should have text ok') + }) + .waitForElementNotPresent('*[data-id="undo-replace-test.sol"]') + }, + + 'should clear search #group2': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[id="search_input"]') + .setValue('*[id="search_input"]', 'nodata').sendKeys('*[id="search_input"]', browser.Keys.ENTER).pause(1000) + .elements('css selector', '.search_plugin_search_line', (res) => { + Array.isArray(res.value) && browser.assert.equal(res.value.length, 0) + }) + } + +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/templates.test.ts b/apps/remixdesktop/test/tests/app/templates.test.ts new file mode 100644 index 00000000000..4c4bdc4753d --- /dev/null +++ b/apps/remixdesktop/test/tests/app/templates.test.ts @@ -0,0 +1,33 @@ +import { NightwatchBrowser } from 'nightwatch' + + +module.exports = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + 'open default template': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) + .waitForElementVisible('button[data-id="landingPageImportFromTemplate"]') + .click('button[data-id="landingPageImportFromTemplate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .click('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .pause(3000) + .windowHandles(function (result) { + console.log(result.value) + browser.switchWindow(result.value[1]) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') + .click('*[data-id="treeViewLitreeViewItemtests"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemcontracts"]') + .click('*[data-id="treeViewLitreeViewItemcontracts"]') + .waitForElementVisible('[data-id="treeViewLitreeViewItemcontracts/1_Storage.sol"]') + .openFile('contracts/1_Storage.sol') + .waitForElementVisible('*[id="editorView"]', 10000) + .getEditorValue((content) => { + browser.assert.ok(content.includes('function retrieve() public view returns (uint256){')) + }) + }) + .end() + } +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/xterm.test.ts b/apps/remixdesktop/test/tests/app/xterm.test.ts new file mode 100644 index 00000000000..df238fbcc90 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/xterm.test.ts @@ -0,0 +1,246 @@ +import {NightwatchBrowser} from 'nightwatch' + + + + +const tests = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + open: function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]') + }, + 'open xterm linux and create a file': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible('*[data-type="remixUIXT"]', 10000) + .click('*[data-type="remixUIXT"]') + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('echo test > example.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemexample.txt"]', 10000) + }, + 'rename that file': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('mv example.txt newExample.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample.txt"]', 10000) + }, + 'create a file and delete it': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('touch newExample2.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('rm newExample2.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000) + }, + 'run a git clone command': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('git clone https://github.com/ethereum/awesome-remix').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000) + .click('*[data-id="treeViewLitreeViewItemawesome-remix"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix/README.md"]', 10000) + }, + 'remove the cloned repo': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-type="remixUIXT"]', 10000) + .click('*[data-type="remixUIXT"]') + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('rm -rf awesome-remix').sendKeys(this.Keys.ENTER) + }) + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000) + }, + 'list files': function (browser: NightwatchBrowser) { + browser + .pause(2000) + .waitForElementVisible({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .click({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('ls').sendKeys(this.Keys.ENTER) + }).pause(3000) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample.txt')) + } + ) + }, + 'switch to a new terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="createTerminalButton"]', 10000) + .click('*[data-id="createTerminalButton"]') + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 2) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample.txt')) + } + ) + }, + 'switch to a third terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="createTerminalButton"]', 10000) + .click('*[data-id="createTerminalButton"]') + .waitForElementVisible( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + 10000 + ) + .click({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 3) + }) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('echo thirdterminal').sendKeys(this.Keys.ENTER) + }) + }, + 'switch back to the second terminal': function (browser: NightwatchBrowser) { + browser + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.elementIdClick(Object.values((result.value as any)[1])[0] as any) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample.txt')) + } + ) + }, + 'close the second terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="closeTerminalButton"]', 10000) + .click('*[data-id="closeTerminalButton"]') + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 2) + }) + }, + 'switch back to the first terminal': function (browser: NightwatchBrowser) { + browser + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.elementIdClick(Object.values((result.value as any)[0])[0] as any) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample.txt')) + } + ) + }, + 'switch to the output panel': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="tabOutput"]', 10000).click('*[data-id="tabOutput"]').waitForElementNotPresent('*[data-id="createTerminalButton"]', 10000) + }, + 'switch back to xterminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible('*[data-type="remixUIXT"]', 10000) + .click('*[data-type="remixUIXT"]') + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample.txt')) + } + ) + }, + 'clear the terminal and type exit': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .waitForElementVisible('*[data-id="clearTerminalButton"]', 10000) + .click('*[data-id="clearTerminalButton"]') + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample.txt')) + .waitForElementVisible( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + 10000 + ) + .click({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .pause(1000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('exit').sendKeys(this.Keys.ENTER) + }) + .pause(1000) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 1) + }).end() + } + ).pause(3000) + }, +} + + +module.exports = { + ...process.platform.startsWith('win')?{}:tests +} \ No newline at end of file diff --git a/apps/remixdesktop/test/tests/app/xtermwin.test.ts b/apps/remixdesktop/test/tests/app/xtermwin.test.ts new file mode 100644 index 00000000000..cf7b1e5be40 --- /dev/null +++ b/apps/remixdesktop/test/tests/app/xtermwin.test.ts @@ -0,0 +1,249 @@ +import {NightwatchBrowser} from 'nightwatch' + +const tests = { + before: function (browser: NightwatchBrowser, done: VoidFunction) { + done() + }, + open: function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="openFolderButton"]', 10000).click('*[data-id="openFolderButton"]') + }, + 'open xterm window and create a file': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible('*[data-id="select_shell"]') + .click('*[data-id="select_shell"]') + .waitForElementVisible('*[data-id="select_powershell.exe"]') + .click('*[data-id="select_powershell.exe"]') + .pause(3000) + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .pause(1000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('"test" | Out-File -FilePath example.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemexample.txt"]', 10000) + }, + 'rename that file': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('Move-Item -Path example.txt -Destination newExample.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample.txt"]', 10000) + }, + 'create a file and delete it': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('touch newExample2.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('Remove-Item -Path newExample2.txt').sendKeys(this.Keys.ENTER) + }) + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemnewExample2.txt"]', 10000) + }, + 'run a git clone command': function (browser: NightwatchBrowser) { + browser + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('git clone https://github.com/ethereum/awesome-remix').sendKeys(this.Keys.ENTER) + }) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000) + .click('*[data-id="treeViewLitreeViewItemawesome-remix"]') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemawesome-remix/README.md"]', 10000) + }, + 'remove the cloned repo': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('Remove-Item -Path awesome-remix -Recurse -Force').sendKeys(this.Keys.ENTER) + }) + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemawesome-remix"]', 10000) + }, + 'list files': function (browser: NightwatchBrowser) { + browser + .pause(3000) + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .saveScreenshot('./reports/screenshots/list-files.png') + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('ls').sendKeys(this.Keys.ENTER) + }) + .saveScreenshot('./reports/screenshots/list-files-after.png') + .waitForElementVisible({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .pause(2000) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample')) + } + ) + }, + 'switch to a new terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="select_shell"]') + .click('*[data-id="select_shell"]') + .waitForElementVisible('*[data-id="select_powershell.exe"]') + .click('*[data-id="select_powershell.exe"]') + .pause(3000) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + console.log(result) + browser.assert.ok((result.value as any).length === 3) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample')) + } + ) + }, + 'switch to a third terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="select_shell"]') + .click('*[data-id="select_shell"]') + .waitForElementVisible('*[data-id="select_powershell.exe"]') + .click('*[data-id="select_powershell.exe"]') + .pause(3000) + .waitForElementVisible( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + 10000 + ) + .click({ + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 4) + }) + .perform(function () { + const actions = this.actions({async: true}) + return actions.sendKeys('echo thirdterminal').sendKeys(this.Keys.ENTER) + }) + }, + 'switch back to the second terminal': function (browser: NightwatchBrowser) { + browser + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.elementIdClick(Object.values((result.value as any)[2])[0] as any) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample')) + } + ) + }, + 'close the second terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="closeTerminalButton"]', 10000) + .click('*[data-id="closeTerminalButton"]') + .pause(1000) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 3) + }) + }, + 'switch back to the first terminal': function (browser: NightwatchBrowser) { + browser + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.elementIdClick(Object.values((result.value as any)[1])[0] as any) + }) + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample')) + } + ) + }, + 'switch to the output panel': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('*[data-id="tabOutput"]', 10000).click('*[data-id="tabOutput"]').waitForElementNotPresent('*[data-id="createTerminalButton"]', 10000) + }, + 'switch back to xterminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="tabXTerm"]', 10000) + .click('*[data-id="tabXTerm"]') + .waitForElementVisible("[data-active='1'][data-type='remixUIXT']", 10000) + .click("[data-active='1'][data-type='remixUIXT']") + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok((result.value as string).includes('newExample')) + } + ) + }, + 'clear the terminal': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="clearTerminalButton"]', 10000) + .click('*[data-id="clearTerminalButton"]') + .getText( + { + selector: "//*[@data-type='remixUIXT' and @data-active='1']", + timeout: 10000, + locateStrategy: 'xpath', + }, + function (result) { + console.log('Text content of the element:', result.value) + browser.assert.ok(!(result.value as string).includes('newExample')) + } + ) + }, + 'close all terminals': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="closeTerminalButton"]', 10000) + .click('*[data-id="closeTerminalButton"]') + .pause(3000) + .click('*[data-id="closeTerminalButton"]') + .pause(3000) + .click('*[data-id="closeTerminalButton"]') + .pause(3000) + .elements('css selector', '[data-type="remixUIXTSideButton"]', function (result) { + browser.assert.ok((result.value as any).length === 0) + }).end() + }, + after: function (browser: NightwatchBrowser) { + browser.end() + }, +} + +module.exports = { + ...process.platform.startsWith('win')?tests:{} +} \ No newline at end of file diff --git a/apps/remixdesktop/test/types/index.d.ts b/apps/remixdesktop/test/types/index.d.ts new file mode 100644 index 00000000000..7208a7c50d8 --- /dev/null +++ b/apps/remixdesktop/test/types/index.d.ts @@ -0,0 +1,108 @@ +// Merge custom command types with nightwatch types +/* eslint-disable no-use-before-define */ +import {NightwatchBrowser} from 'nightwatch' // eslint-disable-line @typescript-eslint/no-unused-vars +export type callbackCheckVerifyCallReturnValue = (values: string[]) => {message: string; pass: boolean} + +declare module 'nightwatch' { + export interface NightwatchCustomCommands { + clickLaunchIcon(icon: string): NightwatchBrowser + switchBrowserTab(index: number): NightwatchBrowser + scrollAndClick(target: string): NightwatchBrowser + scrollInto(target: string): NightwatchBrowser + testContracts(fileName: string, contractCode: NightwatchContractContent, compiledContractNames: string[]): NightwatchBrowser + setEditorValue(value: string, callback?: () => void): NightwatchBrowser + addFile(name: string, content: NightwatchContractContent): NightwatchBrowser + verifyContracts(compiledContractNames: string[], opts?: {wait: number; version?: string; runs?: string}): NightwatchBrowser + selectAccount(account?: string): NightwatchBrowser + clickFunction(fnFullName: string, expectedInput?: NightwatchClickFunctionExpectedInput): NightwatchBrowser + testFunction(txHash: string, expectedInput: NightwatchTestFunctionExpectedInput): NightwatchBrowser + goToVMTraceStep(step: number, incr?: number): NightwatchBrowser + checkVariableDebug(id: string, debugValue: NightwatchCheckVariableDebugValue): NightwatchBrowser + addAtAddressInstance(address: string, isValidFormat: boolean, isValidChecksum: boolean, isAbi?: boolean): NightwatchBrowser + modalFooterOKClick(id?: string): NightwatchBrowser + clickInstance(index: number): NightwatchBrowser + journalLastChildIncludes(val: string): NightwatchBrowser + executeScriptInTerminal(script: string): NightwatchBrowser + clearEditableContent(cssSelector: string): NightwatchBrowser + journalChildIncludes(val: string, opts = {shouldHaveOnlyOneOccurence: boolean}): NightwatchBrowser + debugTransaction(index: number): NightwatchBrowser + checkElementStyle(cssSelector: string, styleProperty: string, expectedResult: string): NightwatchBrowser + openFile(name: string): NightwatchBrowser + refreshPage(): NightwatchBrowser + verifyLoad(): NightwatchBrowser + renamePath(path: string, newFileName: string, renamedPath: string): NightwatchBrowser + rightClickCustom(cssSelector: string): NightwatchBrowser + scrollToLine(line: number): NightwatchBrowser + waitForElementContainsText(id: string, value: string, timeout?: number): NightwatchBrowser + getModalBody(callback: (value: string, cb: VoidFunction) => void): NightwatchBrowser + modalFooterCancelClick(id?: string): NightwatchBrowser + selectContract(contractName: string): NightwatchBrowser + createContract(inputParams: string): NightwatchBrowser + getAddressAtPosition(index: number, cb: (pos: string) => void): NightwatchBrowser + testConstantFunction(address: string, fnFullName: string, expectedInput: NightwatchTestConstantFunctionExpectedInput | null, expectedOutput: string): NightwatchBrowser + getEditorValue(callback: (content: string) => void): NightwatchBrowser + getInstalledPlugins(cb: (plugins: string[]) => void): NightwatchBrowser + verifyCallReturnValue(address: string, checks: string[] | callbackCheckVerifyCallReturnValue): NightwatchBrowser + testEditorValue(testvalue: string): NightwatchBrowser + removeFile(path: string, workspace: string): NightwatchBrowser + switchBrowserWindow(url: string, windowName: string, cb: (browser: NightwatchBrowser, window?: NightwatchCallbackResult) => void): NightwatchBrowser + setupMetamask(passphrase: string, password: string): NightwatchBrowser + signMessage(msg: string, callback: (hash: {value: string}, signature: {value: string}) => void): NightwatchBrowser + setSolidityCompilerVersion(version: string): NightwatchBrowser + clickElementAtPosition(cssSelector: string, index: number, opt?: {forceSelectIfUnselected: boolean}): NightwatchBrowser + notContainsText(cssSelector: string, text: string): NightwatchBrowser + sendLowLevelTx(address: string, value: string, callData: string): NightwatchBrowser + journalLastChild(val: string): NightwatchBrowser + checkTerminalFilter(filter: string, test: string): NightwatchBrowser + noWorkerErrorFor(version: string): NightwatchBrowser + validateValueInput(selector: string, valueTosSet: string[], expectedValue: string): NightwatchBrowser + checkAnnotations(type: string): NightwatchBrowser + checkAnnotationsNotPresent(type: string): NightwatchBrowser + getLastTransactionHash(callback: (hash: string) => void) + currentWorkspaceIs(name: string): NightwatchBrowser + addLocalPlugin(this: NightwatchBrowser, profile: Profile & LocationProfile & ExternalProfile): NightwatchBrowser + acceptAndRemember(this: NightwatchBrowser, remember: boolean, accept: boolean): NightwatchBrowser + clearConsole(this: NightwatchBrowser): NightwatchBrowser + clearTransactions(this: NightwatchBrowser): NightwatchBrowser + getBrowserLogs(this: NightwatchBrowser): NightwatchBrowser + currentSelectedFileIs(name: string): NightwatchBrowser + switchWorkspace: (workspaceName: string) => NightwatchBrowser + switchEnvironment: (provider: string) => NightwatchBrowser + connectToExternalHttpProvider: (url: string, identifier: string) => NightwatchBrowser + waitForElementNotContainsText: (id: string, value: string, timeout: number = 10000) => NightwatchBrowser + hideToolTips: (this: NightwatchBrowser) => NightwatchBrowser + enableClipBoard: () => NightwatchBrowser + } + + export interface NightwatchBrowser { + api: this + emit: (status: string) => void + fullscreenWindow: (result?: any) => this + keys(keysToSend: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): NightwatchBrowser + sendKeys: (selector: string, inputValue: string | string[], callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void) => NightwatchBrowser + } + + export interface NightwatchAPI { + keys(keysToSend: string, callback?: (this: NightwatchAPI, result: NightwatchCallbackResult) => void): NightwatchAPI + } + + export interface NightwatchContractContent { + content: string + } + + export interface NightwatchClickFunctionExpectedInput { + types: string + values: string + } + + export interface NightwatchTestFunctionExpectedInput { + [key: string]: any + } + + export interface NightwatchTestConstantFunctionExpectedInput { + types: string + values: string + } + + export type NightwatchCheckVariableDebugValue = NightwatchTestFunctionExpectedInput +} diff --git a/apps/remixdesktop/tsconfig.e2e.json b/apps/remixdesktop/tsconfig.e2e.json new file mode 100644 index 00000000000..79ebd6cd16b --- /dev/null +++ b/apps/remixdesktop/tsconfig.e2e.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "build-e2e" + }, + "include": ["test/**/*.ts", "test/**/*.js", "../remix-ide-e2e/src/commands"] + } \ No newline at end of file diff --git a/apps/remixdesktop/tsconfig.json b/apps/remixdesktop/tsconfig.json index 63acb26bd4a..ac23558de23 100644 --- a/apps/remixdesktop/tsconfig.json +++ b/apps/remixdesktop/tsconfig.json @@ -1,17 +1,21 @@ { "compilerOptions": { - "target": "es6", + "jsx": "react-jsx", + "target": "ES6", + "allowJs": true, "module": "commonjs", "skipLibCheck": true, "esModuleInterop": true, - "noImplicitAny": true, - "allowSyntheticDefaultImports": true, + "noImplicitAny": false, "sourceMap": true, - "strictPropertyInitialization": false, - "strict": true, + "baseUrl": ".", "outDir": "build", - "rootDir": "./src/", - "noEmitOnError": true, - "typeRoots": ["node_modules/@types", "./types"] - } + "moduleResolution": "node", + "resolveJsonModule": true, + "paths": { + "*": ["node_modules/*"] + }, + "typeRoots": ["src/**/*.d.ts", "node_modules/@types", "test/**/*.d.ts", "../remix-ide-e2e/src/**/*.d.ts"] + }, + "include": ["src/**/*"] } \ No newline at end of file diff --git a/apps/remixdesktop/yarn.lock b/apps/remixdesktop/yarn.lock index dfe7f7a7e78..d39ddaa9dc4 100644 --- a/apps/remixdesktop/yarn.lock +++ b/apps/remixdesktop/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"7zip-bin@~5.1.1": - version "5.1.1" - resolved "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz" - integrity sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ== +"7zip-bin@~5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.2.0.tgz#7a03314684dd6572b7dfa89e68ce31d60286854d" + integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== "@babel/runtime@^7.8.3": version "7.23.2" @@ -22,6 +22,15 @@ ajv "^6.12.0" ajv-keywords "^3.4.1" +"@electron/asar@^3.2.1": + version "3.2.8" + resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.8.tgz#2ea722f3452583dbd4ffdcc4b4f5dc903f1d8178" + integrity sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg== + dependencies: + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" + "@electron/get@^2.0.0": version "2.0.2" resolved "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz" @@ -37,34 +46,45 @@ optionalDependencies: global-agent "^3.0.0" -"@electron/rebuild@^3.2.13": - version "3.2.13" - resolved "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.13.tgz" - integrity sha512-DH9Ol4JCnHDYVOD0fKWq+Qqbn/0WU1O6QR0mIpMXEVU4YFM4PlaqNC9K36mGShNBxxGFotZCMDrB1wl/iHM12g== +"@electron/notarize@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-2.1.0.tgz#76aaec10c8687225e8d0a427cc9df67611c46ff3" + integrity sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA== + dependencies: + debug "^4.1.1" + fs-extra "^9.0.1" + promise-retry "^2.0.1" + +"@electron/notarize@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@electron/notarize/-/notarize-2.3.0.tgz#9659cf6c92563dd69411afce229f52f9f7196227" + integrity sha512-EiTBU0BwE7HZZjAG1fFWQaiQpCuPrVGn7jPss1kUjD6eTTdXXd29RiZqEqkgN7xqt/Pgn4g3I7Saqovanrfj3w== dependencies: - "@malept/cross-spawn-promise" "^2.0.0" - chalk "^4.0.0" debug "^4.1.1" - detect-libc "^2.0.1" + fs-extra "^9.0.1" + promise-retry "^2.0.1" + +"@electron/osx-sign@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@electron/osx-sign/-/osx-sign-1.0.5.tgz#0af7149f2fce44d1a8215660fd25a9fb610454d8" + integrity sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww== + dependencies: + compare-version "^0.1.2" + debug "^4.3.4" fs-extra "^10.0.0" - got "^11.7.0" - node-abi "^3.0.0" - node-api-version "^0.1.4" - node-gyp "^9.0.0" - ora "^5.1.0" - semver "^7.3.5" - tar "^6.0.5" - yargs "^17.0.1" - -"@electron/universal@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.2.1.tgz#3c2c4ff37063a4e9ab1e6ff57db0bc619bc82339" - integrity sha512-7323HyMh7KBAl/nPDppdLsC87G6RwRU02dy5FPeGB1eS7rUePh55+WNWiDPLhFQqqVPHzh77M69uhmoT8XnwMQ== + isbinaryfile "^4.0.8" + minimist "^1.2.6" + plist "^3.0.5" + +"@electron/universal@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.4.1.tgz#3fbda2a5ed9ff9f3304c8e8316b94c1e3a7b3785" + integrity sha512-lE/U3UNw1YHuowNbTmKNs9UlS3En3cPgwM5MI+agIgr/B1hSze9NdOP0qn7boZaI9Lph8IDv3/24g9IxnJP7aQ== dependencies: + "@electron/asar" "^3.2.1" "@malept/cross-spawn-promise" "^1.1.0" - asar "^3.1.0" debug "^4.3.1" - dir-compare "^2.4.0" + dir-compare "^3.0.0" fs-extra "^9.0.1" minimatch "^3.0.4" plist "^3.0.4" @@ -461,7 +481,7 @@ "@isaacs/cliui@^8.0.2": version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== dependencies: string-width "^5.1.2" @@ -478,13 +498,6 @@ dependencies: cross-spawn "^7.0.1" -"@malept/cross-spawn-promise@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz" - integrity sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg== - dependencies: - cross-spawn "^7.0.1" - "@malept/flatpak-bundler@^0.4.0": version "0.4.0" resolved "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz" @@ -495,6 +508,18 @@ lodash "^4.17.15" tmp-promise "^3.0.2" +"@nightwatch/chai@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@nightwatch/chai/-/chai-5.0.2.tgz#86b20908fc090dffd5c9567c0392bc6a494cc2e6" + integrity sha512-yzILJFCcE75OPoRfBlJ80Y3Ky06ljsdrK4Ld92yhmM477vxO2GEguwnd+ldl7pdSYTcg1gSJ1bPPQrA+/Hrn+A== + dependencies: + assertion-error "1.1.0" + check-error "1.0.2" + deep-eql "4.0.1" + loupe "2.3.4" + pathval "1.1.1" + type-detect "4.0.8" + "@noble/curves@1.1.0", "@noble/curves@~1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" @@ -512,13 +537,6 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== - dependencies: - semver "^7.3.5" - "@openzeppelin/contracts@^4.7.3": version "4.9.6" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" @@ -533,7 +551,7 @@ "@pkgjs/parseargs@^0.11.0": version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@remix-project/remix-url-resolver@^0.0.65": @@ -556,68 +574,68 @@ ethers "^5.4.2" web3 "^1.5.1" -"@remixproject/engine-electron@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/engine-electron/-/engine-electron-0.3.41.tgz#a354d4a4dd43ade644ea27636cfc0aa63c5155b2" - integrity sha512-fF2l3LkDVK1KjkIHll7mOo6AkjUg4hgbHG2jDzHZW6m1jYr6SGxauVoYlOQvlfTe283dpsGxWEdU7TOC8Kne7w== +"@remixproject/engine-electron@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/engine-electron/-/engine-electron-0.3.43.tgz#37fe98c6ef2deb6de80db60882608714d6e25274" + integrity sha512-k1Lcg67tlPiBFJwKhBRT9bDMyZuYWDdUXZOHKX8BGPZ0lS1ZQDrH4uN2QE2EFGIiCxeArcNzQ7MZ5iEo763eUA== dependencies: - "@remixproject/engine" "0.3.41" - "@remixproject/plugin-api" "0.3.41" - "@remixproject/plugin-utils" "0.3.41" + "@remixproject/engine" "0.3.43" + "@remixproject/plugin-api" "0.3.43" + "@remixproject/plugin-utils" "0.3.43" -"@remixproject/engine@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/engine/-/engine-0.3.41.tgz#71b447d07dd52ec7645c6538f64caa638f3d9702" - integrity sha512-5ppAEana+I9FvSOjdNoLkLFbBTIpLoN5DAKsw+efyZ076i/67OsZ6oHXZqzGoHTOr4s4aS0wHmCBJPSla8GUBA== +"@remixproject/engine@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/engine/-/engine-0.3.43.tgz#deceb8398a034d33f741f9de38b233ab616720a4" + integrity sha512-BKmLVdtkPUQ56yZuRsU7CxS0TgJe4b7P9RoqdBW0Udy1w8oUJsWmlmKchCLXD+/t+12jPyk4sulRN8N9YOFBAw== dependencies: - "@remixproject/plugin-api" "0.3.41" - "@remixproject/plugin-utils" "0.3.41" + "@remixproject/plugin-api" "0.3.43" + "@remixproject/plugin-utils" "0.3.43" -"@remixproject/plugin-api@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.41.tgz#9a60d92332af608a871366bec6097bda2d2d1658" - integrity sha512-+gZOzJH4KUMVOEYFFW4LwwCWbojACqxvLM9FJRRkHehohue07Y7ojIbFoYk4EPWkdBtOXOsIR2zjdUIUlzzrTg== +"@remixproject/plugin-api@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.43.tgz#68ce6799a8e6e22961b82f46a7a52b1d7a4a765c" + integrity sha512-qgwq3UQAW9JKsFv47m0E7plNNEWL4CFbqoLGbfsfwuZTd/V7HhaMc1my5dxOObW+RKExyvFNFSEvEp7HoHFsWg== dependencies: - "@remixproject/plugin-utils" "0.3.41" + "@remixproject/plugin-utils" "0.3.43" -"@remixproject/plugin-api@^0.3.38": - version "0.3.38" - resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.38.tgz#7dcff37483451b654fc51290157992fff3fbd8b7" - integrity sha512-GLXAnV7TMYV2KlXTml+W0H6s0m5EkVb5w610Jh9k4PLFVrocl9xDEG4VlZ8BF/uv+yjXRi4dn++8zWMRe5375Q== +"@remixproject/plugin-api@^0.3.43": + version "0.3.208" + resolved "https://registry.yarnpkg.com/@remixproject/plugin-api/-/plugin-api-0.3.208.tgz#28505b84ec06c84e04ca1bf7cfa51109c178c06b" + integrity sha512-11hFxABBrEzE4fgcDblWqxLAh5ARH2tBADgh9KNk+y7LUV7aQ7OZf4KiZ2US+uKiSC6497iu/uLHbWBTeRqlVA== dependencies: - "@remixproject/plugin-utils" "0.3.38" + "@remixproject/plugin-utils" "0.3.208" -"@remixproject/plugin-electron@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/plugin-electron/-/plugin-electron-0.3.41.tgz#6f736dfa5146bdf41fe0c452ab0b78e7f914fda1" - integrity sha512-E/rmKSbUa4rZKq02C+HD6WQDTS2CH6+Gqc6Z9p5wxQwbbJoMD/WVtWUvOFr1p2PSp0Nwpc4qWfOoQC6EmaugOg== +"@remixproject/plugin-electron@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/plugin-electron/-/plugin-electron-0.3.43.tgz#6c621c413745ce785f9973baea109debe3def00a" + integrity sha512-uv44xjmkTsC/o4xnMEBml6NxrMeq95aOR3FFY8MnZkKvnWOKC94SE5AYuHOAvt+FBrnar2f58+IYpBJAIkYyaQ== dependencies: - "@remixproject/engine" "0.3.41" - "@remixproject/plugin" "0.3.41" - "@remixproject/plugin-api" "0.3.41" - "@remixproject/plugin-utils" "0.3.41" + "@remixproject/engine" "0.3.43" + "@remixproject/plugin" "0.3.43" + "@remixproject/plugin-api" "0.3.43" + "@remixproject/plugin-utils" "0.3.43" -"@remixproject/plugin-utils@0.3.38": - version "0.3.38" - resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.38.tgz#402adbef700a9392fbeae7d536ba020b7cfbdfaa" - integrity sha512-DpbB+BFfWvZ/pKWlXY0Ms3mqp/ajWxBI+TUiJor2AkLtCSBS1+Uk7BWG++jNSqgjdvVKxxWa4kJygFwUPtUYXA== +"@remixproject/plugin-utils@0.3.208": + version "0.3.208" + resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.208.tgz#8ec1339af9177358c09a7dd7a39396f52c4cad27" + integrity sha512-PjEK+ty6X14ud3h2U/XH8BBbqwLF3CwduOxHCXfCG0KarR4FwuSfocWQfGlASeDFmPzyV1aMGn//U6xZ03O42Q== dependencies: tslib "2.0.1" -"@remixproject/plugin-utils@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.41.tgz#6de4d016084cf54fbf710ed717c9c1efc0a990de" - integrity sha512-pyqewxfQwr35YkFoZItH5E9qiIZRlpwxLuGBCMXzo6fmPm2YybhpblLaefppsdbqY1yEVsqakQa6U6d6vJRSNQ== +"@remixproject/plugin-utils@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/plugin-utils/-/plugin-utils-0.3.43.tgz#53206666135a360c88bfde11568c31341c9d961f" + integrity sha512-FB2Dz0/+TQ+D9AdINfsu38qHEsUVIDpaDCaXY76suDkSUudoHcGrC5TbpaV/xMUbMMma2dcLp629vBNnA5Cd0w== dependencies: tslib "2.0.1" -"@remixproject/plugin@0.3.41": - version "0.3.41" - resolved "https://registry.yarnpkg.com/@remixproject/plugin/-/plugin-0.3.41.tgz#fc82d0afd08ba659d09ee7714fa91af92cdb8e72" - integrity sha512-GqBaxExtNGQHNHwPwx/2RKX7vinEBJe9KzxzkzR2BGuBZD963+il2WsMu+QYyHjTxJ8kHZF9exqUSYJd9jZ+Yw== +"@remixproject/plugin@0.3.43": + version "0.3.43" + resolved "https://registry.yarnpkg.com/@remixproject/plugin/-/plugin-0.3.43.tgz#c7397b8e44ab6627a290c3716985439482eb4f4a" + integrity sha512-uO0wQ9kP982QTJIlGUXXeOjLG1qG64UN5kDopTcMbplzT5vXlMRV64FY8zEqSXtl+sdqKBFLXrwmb+AUNU0MTA== dependencies: - "@remixproject/plugin-api" "0.3.41" - "@remixproject/plugin-utils" "0.3.41" + "@remixproject/plugin-api" "0.3.43" + "@remixproject/plugin-utils" "0.3.43" events "3.2.0" "@scure/base@~1.1.0": @@ -661,6 +679,11 @@ dependencies: defer-to-connect "^2.0.1" +"@testim/chrome-version@^1.1.3": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090" + integrity sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" @@ -698,6 +721,11 @@ "@types/node" "*" "@types/responselike" "^1.0.0" +"@types/chai@*": + version "4.3.11" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" + integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== + "@types/connect@*": version "3.4.38" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" @@ -732,21 +760,13 @@ "@types/qs" "*" "@types/serve-static" "*" -"@types/fs-extra@^9.0.11": +"@types/fs-extra@9.0.13", "@types/fs-extra@^9.0.11": version "9.0.13" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== dependencies: "@types/node" "*" -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - "@types/http-cache-semantics@*": version "4.0.1" resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" @@ -774,16 +794,20 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - "@types/ms@*": version "0.7.31" resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== +"@types/nightwatch@^2.3.23": + version "2.3.30" + resolved "https://registry.yarnpkg.com/@types/nightwatch/-/nightwatch-2.3.30.tgz#bb342bf21bc6cd0a7134681523ba42eeefe73c4d" + integrity sha512-TiVGKR9mORwx0nN3ylonXp2IobpQoZxwV63IjABYkxsEpNauHL8GU9kmceEThjqDUigKaeh6aPOqepwC4bwCfA== + dependencies: + "@types/chai" "*" + "@types/selenium-webdriver" "*" + devtools-protocol "^0.0.1025565" + "@types/node@*": version "20.3.2" resolved "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz" @@ -838,6 +862,13 @@ dependencies: "@types/node" "*" +"@types/selenium-webdriver@*": + version "4.1.21" + resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.21.tgz#79fe31faf9953a4143c3e32944d98d5146bbe185" + integrity sha512-QGURnImvxYlIQz5DVhvHdqpYNLBjhJ2Vm+cnQI2G9QZzkWlZm0LkLcvDcHp+qE6N2KBz4CeuvXgPO7W3XQ0Tyw== + dependencies: + "@types/ws" "*" + "@types/send@*": version "0.17.4" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" @@ -860,17 +891,12 @@ resolved "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz" integrity sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ== -"@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - -"@types/yargs@^17.0.1": - version "17.0.31" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.31.tgz#8fd0089803fd55d8a285895a18b88cb71a99683c" - integrity sha512-bocYSx4DI8TmdlvxqGpVNXOgCNR1Jj0gNPhhAY+iz1rgKDAaYrAYdFYnhDV1IFuiuVc9HkOwyDcFxaTElF3/wg== +"@types/ws@*": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: - "@types/yargs-parser" "*" + "@types/node" "*" "@types/yauzl@^2.9.1": version "2.10.0" @@ -879,6 +905,11 @@ dependencies: "@types/node" "*" +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + "@vscode/ripgrep@^1.15.6": version "1.15.6" resolved "https://registry.npmjs.org/@vscode/ripgrep/-/ripgrep-1.15.6.tgz" @@ -892,11 +923,6 @@ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - abortcontroller-polyfill@^1.7.5: version "1.7.5" resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" @@ -920,7 +946,7 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== -agent-base@6, agent-base@^6.0.2: +agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -934,18 +960,9 @@ agent-base@^7.0.2: dependencies: debug "^4.3.4" -agentkeepalive@^4.2.1: - version "4.3.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz" - integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== - dependencies: - debug "^4.1.0" - depd "^2.0.0" - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: +aggregate-error@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -966,6 +983,18 @@ ajv@^6.10.0, ajv@^6.12.0, ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" @@ -973,7 +1002,7 @@ ansi-regex@^5.0.1: ansi-regex@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== ansi-styles@^4.0.0, ansi-styles@^4.1.0: @@ -985,9 +1014,16 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: ansi-styles@^6.1.0: version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +ansi-to-html@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.7.2.tgz#a92c149e4184b571eb29a0135ca001a8e2d710cb" + integrity sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g== + dependencies: + entities "^2.2.0" + anymatch@~3.1.2: version "3.1.3" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" @@ -1001,51 +1037,40 @@ app-builder-bin@4.0.0: resolved "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz" integrity sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA== -app-builder-lib@23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-23.6.0.tgz#03cade02838c077db99d86212d61c5fc1d6da1a8" - integrity sha512-dQYDuqm/rmy8GSCE6Xl/3ShJg6Ab4bZJMT8KaTKGzT436gl1DN4REP3FCWfXoh75qGTJ+u+WsdnnpO9Jl8nyMA== +app-builder-lib@24.9.1: + version "24.9.1" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-24.9.1.tgz#bf3568529298b4de8595ed1acbb351fe27db5ba4" + integrity sha512-Q1nYxZcio4r+W72cnIRVYofEAyjBd3mG47o+zms8HlD51zWtA/YxJb01Jei5F+jkWhge/PTQK+uldsPh6d0/4g== dependencies: - "7zip-bin" "~5.1.1" + "7zip-bin" "~5.2.0" "@develar/schema-utils" "~2.6.5" - "@electron/universal" "1.2.1" + "@electron/notarize" "2.1.0" + "@electron/osx-sign" "1.0.5" + "@electron/universal" "1.4.1" "@malept/flatpak-bundler" "^0.4.0" + "@types/fs-extra" "9.0.13" async-exit-hook "^2.0.1" bluebird-lst "^1.0.9" - builder-util "23.6.0" - builder-util-runtime "9.1.1" + builder-util "24.8.1" + builder-util-runtime "9.2.3" chromium-pickle-js "^0.2.0" debug "^4.3.4" - ejs "^3.1.7" - electron-osx-sign "^0.6.0" - electron-publish "23.6.0" + ejs "^3.1.8" + electron-publish "24.8.1" form-data "^4.0.0" fs-extra "^10.1.0" hosted-git-info "^4.1.0" is-ci "^3.0.0" - isbinaryfile "^4.0.10" + isbinaryfile "^5.0.0" js-yaml "^4.1.0" lazy-val "^1.0.5" - minimatch "^3.1.2" - read-config-file "6.2.0" + minimatch "^5.1.1" + read-config-file "6.3.2" sanitize-filename "^1.6.3" - semver "^7.3.7" - tar "^6.1.11" + semver "^7.3.8" + tar "^6.1.12" temp-file "^3.4.0" -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - argparse@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" @@ -1087,17 +1112,10 @@ arraybuffer.prototype.slice@^1.0.2: is-array-buffer "^3.0.2" is-shared-array-buffer "^1.0.2" -asar@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/asar/-/asar-3.2.0.tgz#e6edb5edd6f627ebef04db62f771c61bea9c1221" - integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg== - dependencies: - chromium-pickle-js "^0.2.0" - commander "^5.0.0" - glob "^7.1.6" - minimatch "^3.0.4" - optionalDependencies: - "@types/glob" "^7.1.1" +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== asn1@~0.2.3: version "0.2.6" @@ -1111,6 +1129,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== +assertion-error@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" @@ -1161,6 +1184,11 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== +axe-core@^4.4.3: + version "4.8.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.3.tgz#205df863dd9917d5979e9435dab4d47692759051" + integrity sha512-d5ZQHPSPkF9Tw+yfyDcRoUOc4g/8UloJJe5J8m4L5+c7AtDdjDLRxew/knnI4CxvtdxEUVgWz4x3OIQUIFiMfw== + axios@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.2.tgz#72681724c6e6a43a9fea860fc558127dbe32f9f1" @@ -1170,15 +1198,28 @@ axios@1.2.2: form-data "^4.0.0" proxy-from-env "^1.1.0" -axios@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.1.tgz#76550d644bf0a2d469a01f9244db6753208397d7" - integrity sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g== +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.14.9" + form-data "^4.0.0" + +axios@^1.4.0, axios@^1.6.8: + version "1.6.8" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" + integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== + dependencies: + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" +b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -1282,6 +1323,20 @@ boolean@^3.0.1: resolved "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz" integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== +boxen@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -1309,6 +1364,11 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -1337,33 +1397,15 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== -buffer-equal@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" - integrity sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ== - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== +buffer-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.1.tgz#2f7651be5b1b3f057fcd6e7ee16cf34767077d90" + integrity sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg== buffer-from@^1.0.0: version "1.1.2" @@ -1395,31 +1437,30 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.3.0" -builder-util-runtime@9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.1.1.tgz#2da7b34e78a64ad14ccd070d6eed4662d893bd60" - integrity sha512-azRhYLEoDvRDR8Dhis4JatELC/jUvYjm4cVSj7n9dauGTOM2eeNn9KS0z6YA6oDsjI1xphjNbY6PZZeHPzzqaw== +builder-util-runtime@9.2.3: + version "9.2.3" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.3.tgz#0a82c7aca8eadef46d67b353c638f052c206b83c" + integrity sha512-FGhkqXdFFZ5dNC4C+yuQB9ak311rpGAw+/ASz8ZdxwODCv1GGMWgLDeofRkdi0F3VCHQEWy/aXcJQozx2nOPiw== dependencies: debug "^4.3.4" sax "^1.2.4" -builder-util@23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-23.6.0.tgz#1880ec6da7da3fd6fa19b8bd71df7f39e8d17dd9" - integrity sha512-QiQHweYsh8o+U/KNCZFSvISRnvRctb8m/2rB2I1JdByzvNKxPeFLlHFRPQRXab6aYeXc18j9LpsDLJ3sGQmWTQ== +builder-util@24.8.1: + version "24.8.1" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-24.8.1.tgz#594d45b0c86d1d17f5c7bebbb77405080b2571c2" + integrity sha512-ibmQ4BnnqCnJTNrdmdNlnhF48kfqhNzSeqFMXHLIl+o9/yhn6QfOaVrloZ9YUu3m0k3rexvlT5wcki6LWpjTZw== dependencies: - "7zip-bin" "~5.1.1" + "7zip-bin" "~5.2.0" "@types/debug" "^4.1.6" - "@types/fs-extra" "^9.0.11" app-builder-bin "4.0.0" bluebird-lst "^1.0.9" - builder-util-runtime "9.1.1" - chalk "^4.1.1" + builder-util-runtime "9.2.3" + chalk "^4.1.2" cross-spawn "^7.0.3" debug "^4.3.4" - fs-extra "^10.0.0" + fs-extra "^10.1.0" http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" is-ci "^3.0.0" js-yaml "^4.1.0" source-map-support "^0.5.19" @@ -1436,24 +1477,6 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^17.0.0: - version "17.1.3" - resolved "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz" - integrity sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - cacheable-lookup@^5.0.3: version "5.0.4" resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" @@ -1486,20 +1509,53 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +camelcase@^6.0.0, camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1: +chai-nightwatch@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/chai-nightwatch/-/chai-nightwatch-0.5.3.tgz#980ecf63dde5a04e7f3524370682c7ff01178ffb" + integrity sha512-38ixH/mqpY6IwnZkz6xPqx8aB5/KVR+j6VPugcir3EGOsphnWXrPH/mUt8Jp+ninL6ghY0AaJDQ10hSfCPGy/g== + dependencies: + assertion-error "1.1.0" + +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^3.5.3: +charenc@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== + +check-error@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== + +chokidar@3.5.3, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -1524,11 +1580,29 @@ chownr@^2.0.0: resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chromedriver@116: + version "116.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-116.0.0.tgz#3f5d07b5427953270461791651d7b68cb6afe9fe" + integrity sha512-/TQaRn+RUAYnVqy5Vx8VtU8DvtWosU8QLM2u7BoNM5h55PRQPXF/onHAehEi8Sj/CehdKqH50NFdiumQAUr0DQ== + dependencies: + "@testim/chrome-version" "^1.1.3" + axios "^1.4.0" + compare-versions "^6.0.0" + extract-zip "^2.0.1" + https-proxy-agent "^5.0.1" + proxy-from-env "^1.1.0" + tcp-port-used "^1.0.1" + chromium-pickle-js@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" integrity sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw== +ci-info@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + ci-info@^3.2.0: version "3.8.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" @@ -1565,20 +1639,25 @@ clean-git-ref@^2.0.1: clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-spinners@^2.5.0: - version "2.9.0" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz" - integrity sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-truncate@^2.1.0: version "2.1.0" @@ -1588,6 +1667,15 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" @@ -1606,7 +1694,7 @@ clone-response@^1.0.2: clone@^1.0.2: version "1.0.4" - resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== color-convert@^2.0.1: @@ -1621,16 +1709,6 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== - combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -1638,32 +1716,38 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - integrity sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A== - dependencies: - graceful-readlink ">= 1.0.0" - -commander@^5.0.0: +commander@^5.0.0, commander@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + compare-version@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" integrity sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A== +compare-versions@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.0.tgz#3f2131e3ae93577df111dba133e6db876ffe127a" + integrity sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +config-file-ts@^0.2.4: + version "0.2.6" + resolved "https://registry.yarnpkg.com/config-file-ts/-/config-file-ts-0.2.6.tgz#b424ff74612fb37f626d6528f08f92ddf5d22027" + integrity sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w== + dependencies: + glob "^10.3.10" + typescript "^5.3.3" content-disposition@0.5.4: version "0.5.4" @@ -1772,6 +1856,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypt@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== + d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -1787,20 +1876,39 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@2.6.9, debug@^2.2.0, debug@^2.6.8: +debug@2.6.9, debug@^2.2.0: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decode-uri-component@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" @@ -1820,9 +1928,45 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" +deep-eql@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445" + integrity sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA== + dependencies: + type-detect "^4.0.0" + +deep-equal@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.13" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + defaults@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== dependencies: clone "^1.0.2" @@ -1841,6 +1985,20 @@ define-data-property@^1.0.1, define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + define-properties@^1.1.3: version "1.2.0" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" @@ -1849,7 +2007,7 @@ define-properties@^1.1.3: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -define-properties@^1.1.4, define-properties@^1.2.0: +define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -1863,12 +2021,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -depd@2.0.0, depd@^2.0.0: +depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -1878,40 +2031,48 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-libc@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== - detect-node@^2.0.4: version "2.1.0" resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== +devtools-protocol@^0.0.1025565: + version "0.0.1025565" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1025565.tgz#0b3da0d3714c556aad06b0ec60f4fde68a701a90" + integrity sha512-0s5sbGQR/EfYQhd8EpZgphpndsv+CufTlaeUyA6vYXCA0H5kMAsHCS/cHtUFWoKJCO125hpoKicQCfpxRj4oqw== + +didyoumean@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + diff3@0.0.3: version "0.0.3" resolved "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz" integrity sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g== -dir-compare@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631" - integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dir-compare@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-3.3.0.tgz#2c749f973b5c4b5d087f11edaae730db31788416" + integrity sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg== dependencies: - buffer-equal "1.0.0" - colors "1.0.3" - commander "2.9.0" - minimatch "3.0.4" + buffer-equal "^1.0.0" + minimatch "^3.0.4" -dmg-builder@23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-23.6.0.tgz#d39d3871bce996f16c07d2cafe922d6ecbb2a948" - integrity sha512-jFZvY1JohyHarIAlTbfQOk+HnceGjjAdFjVn3n8xlDWKsYNqbO4muca6qXEZTfGXeQMG7TYim6CeS5XKSfSsGA== +dmg-builder@24.9.1: + version "24.9.1" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-24.9.1.tgz#04bf6c0dcd235f6214511f2358a78ed2b9379421" + integrity sha512-huC+O6hvHd24Ubj3cy2GMiGLe2xGFKN3klqVMLAdcbB6SWMd1yPSdZvV8W1O01ICzCCRlZDHiv4VrNUgnPUfbQ== dependencies: - app-builder-lib "23.6.0" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - fs-extra "^10.0.0" + app-builder-lib "24.9.1" + builder-util "24.8.1" + builder-util-runtime "9.2.3" + fs-extra "^10.1.0" iconv-lite "^0.6.2" js-yaml "^4.1.0" optionalDependencies: @@ -1941,6 +2102,11 @@ dotenv-expand@^5.1.0: resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== +dotenv@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + dotenv@^9.0.2: version "9.0.2" resolved "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz" @@ -1948,7 +2114,7 @@ dotenv@^9.0.2: eastasianwidth@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecc-jsbn@~0.1.1: @@ -1964,30 +2130,36 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -ejs@^3.1.7: +ejs@3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" + integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + dependencies: + jake "^10.8.5" + +ejs@^3.1.8: version "3.1.9" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== dependencies: jake "^10.8.5" -electron-builder@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-23.6.0.tgz#c79050cbdce90ed96c5feb67c34e9e0a21b5331b" - integrity sha512-y8D4zO+HXGCNxFBV/JlyhFnoQ0Y0K7/sFH+XwIbj47pqaW8S6PGYQbjoObolKBR1ddQFPt4rwp4CnwMJrW3HAw== - dependencies: - "@types/yargs" "^17.0.1" - app-builder-lib "23.6.0" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - chalk "^4.1.1" - dmg-builder "23.6.0" - fs-extra "^10.0.0" +electron-builder@24.9.1: + version "24.9.1" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-24.9.1.tgz#4aee03947963b829a7f48a850fe02c219311ef63" + integrity sha512-v7BuakDuY6sKMUYM8mfQGrwyjBpZ/ObaqnenU0H+igEL10nc6ht049rsCw2HghRBdEwJxGIBuzs3jbEhNaMDmg== + dependencies: + app-builder-lib "24.9.1" + builder-util "24.8.1" + builder-util-runtime "9.2.3" + chalk "^4.1.2" + dmg-builder "24.9.1" + fs-extra "^10.1.0" is-ci "^3.0.0" lazy-val "^1.0.5" - read-config-file "6.2.0" - simple-update-notifier "^1.0.7" - yargs "^17.5.1" + read-config-file "6.3.2" + simple-update-notifier "2.0.0" + yargs "^17.6.2" electron-devtools-installer@^3.2.0: version "3.2.0" @@ -1999,35 +2171,37 @@ electron-devtools-installer@^3.2.0: tslib "^2.1.0" unzip-crx-3 "^0.2.0" -electron-osx-sign@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz#9b69c191d471d9458ef5b1e4fdd52baa059f1bb8" - integrity sha512-+hiIEb2Xxk6eDKJ2FFlpofCnemCbjbT5jz+BKGpVBrRNT3kWTGs4DfNX6IzGwgi33hUcXF+kFs9JW+r6Wc1LRg== - dependencies: - bluebird "^3.5.0" - compare-version "^0.1.2" - debug "^2.6.8" - isbinaryfile "^3.0.2" - minimist "^1.2.0" - plist "^3.0.1" - -electron-publish@23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-23.6.0.tgz#ac9b469e0b07752eb89357dd660e5fb10b3d1ce9" - integrity sha512-jPj3y+eIZQJF/+t5SLvsI5eS4mazCbNYqatv5JihbqOstIM13k0d1Z3vAWntvtt13Itl61SO6seicWdioOU5dg== +electron-publish@24.8.1: + version "24.8.1" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-24.8.1.tgz#4216740372bf4297a429543402a1a15ce8c3560b" + integrity sha512-IFNXkdxMVzUdweoLJNXSupXkqnvgbrn3J4vognuOY06LaS/m0xvfFYIf+o1CM8if6DuWYWoQFKPcWZt/FUjZPw== dependencies: "@types/fs-extra" "^9.0.11" - builder-util "23.6.0" - builder-util-runtime "9.1.1" - chalk "^4.1.1" - fs-extra "^10.0.0" + builder-util "24.8.1" + builder-util-runtime "9.2.3" + chalk "^4.1.2" + fs-extra "^10.1.0" lazy-val "^1.0.5" mime "^2.5.2" -electron@^25.0.1: - version "25.9.5" - resolved "https://registry.yarnpkg.com/electron/-/electron-25.9.5.tgz#c030368ebe1b40580e781d89fa8ce7ef19202692" - integrity sha512-gM7GXUSd3JVRcYbBnNOtZeNnE5MCJjtZTT8QyIxJvpQ0Dh9dz3hTuEL62dOwnMFW/l47ACQ6es/8qi01P4QGZA== +electron-updater@^6.1.8: + version "6.1.8" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.1.8.tgz#17637bca165322f4e526b13c99165f43e6f697d8" + integrity sha512-hhOTfaFAd6wRHAfUaBhnAOYc+ymSGCWJLtFkw4xJqOvtpHmIdNHnXDV9m1MHC+A6q08Abx4Ykgyz/R5DGKNAMQ== + dependencies: + builder-util-runtime "9.2.3" + fs-extra "^10.1.0" + js-yaml "^4.1.0" + lazy-val "^1.0.5" + lodash.escaperegexp "^4.1.2" + lodash.isequal "^4.5.0" + semver "^7.3.8" + tiny-typed-emitter "^2.1.0" + +electron@^26.0.0: + version "26.6.7" + resolved "https://registry.yarnpkg.com/electron/-/electron-26.6.7.tgz#ba9a5d2b857f54f3f3cba9fe1d2da7c33f6501ab" + integrity sha512-2iG08Q2KAPTBlxPqEB3qmVUqDdmcPAvgGhiULggkeoLTznhg5yqkOJPe+Hpuc176i4gjsQVTpK7zbhq21Y3FoQ== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18" @@ -2053,7 +2227,7 @@ emoji-regex@^8.0.0: emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== encodeurl@~1.0.2: @@ -2061,13 +2235,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" @@ -2075,14 +2242,24 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +entities@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +envinfo@7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + err-code@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== es-abstract@^1.22.1: @@ -2130,6 +2307,33 @@ es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.13" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + es-set-tostringtag@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" @@ -2202,7 +2406,7 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@^4.0.0: +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -2370,10 +2574,36 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== +execa@^3.3.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@^5.0.0, execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" express@^4.14.0, express@^4.19.2: version "4.19.2" @@ -2450,6 +2680,11 @@ fast-deep-equal@^3.1.1: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" @@ -2489,10 +2724,50 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -follow-redirects@^1.15.0: - version "1.15.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" - integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== +find-process@^1.4.7: + version "1.4.7" + resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.7.tgz#8c76962259216c381ef1099371465b5b439ea121" + integrity sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg== + dependencies: + chalk "^4.0.0" + commander "^5.1.0" + debug "^4.1.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +fkill@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/fkill/-/fkill-7.2.1.tgz#7036200cd2edd28a6bc40f0defc1e159d9e24e64" + integrity sha512-eN9cmsIlRdq06wu3m01OOEgQf5Xh/M7REm0jfZ4eL3V3XisjXzfRq3iyqtKS+FhO6wB36FvWRiRGdeSx5KpLAQ== + dependencies: + aggregate-error "^3.1.0" + arrify "^2.0.1" + execa "^5.0.0" + pid-port "^0.1.0" + process-exists "^4.0.0" + ps-list "^7.2.0" + taskkill "^3.1.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +follow-redirects@^1.14.9: + version "1.15.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" + integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + +follow-redirects@^1.15.0, follow-redirects@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" @@ -2503,7 +2778,7 @@ for-each@^0.3.3: foreground-child@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" + 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" @@ -2612,13 +2887,6 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" -fs-minipass@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.2.tgz" - integrity sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g== - dependencies: - minipass "^5.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -2654,25 +2922,16 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" @@ -2693,14 +2952,25 @@ get-intrinsic@^1.1.1: has-proto "^1.0.1" has-symbols "^1.0.3" -get-stream@^5.1.0: +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" -get-stream@^6.0.1: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -2727,18 +2997,30 @@ glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob@^10.2.2: - version "10.3.0" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.0.tgz" - integrity sha512-AQ1/SB9HH0yCx1jXAT4vmCbTOPe5RQ+kCurjbel5xSCGhebumUv+GJZfa1rEqor3XIViqwSEmlkZCQD43RWrBg== +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + 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.0.3" + jackspeak "^2.3.5" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" -glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.3, glob@^7.1.6, glob@^7.2.3: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2803,9 +3085,9 @@ got@12.1.0: p-cancelable "^3.0.0" responselike "^2.0.0" -got@^11.7.0, got@^11.8.5: +got@^11.8.5, got@^11.8.6: version "11.8.6" - resolved "https://registry.npmjs.org/got/-/got-11.8.6.tgz" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== dependencies: "@sindresorhus/is" "^4.0.0" @@ -2820,15 +3102,15 @@ got@^11.7.0, got@^11.8.5: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== har-schema@^2.0.0: version "2.0.0" @@ -2860,6 +3142,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" @@ -2877,11 +3166,6 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - has@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" @@ -2913,6 +3197,11 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2929,7 +3218,7 @@ hosted-git-info@^4.1.0: dependencies: lru-cache "^6.0.0" -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0: version "4.1.1" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -2984,9 +3273,9 @@ http2-wrapper@^2.1.10: quick-lru "^5.1.1" resolve-alpn "^1.2.0" -https-proxy-agent@^5.0.0: +https-proxy-agent@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -3000,12 +3289,15 @@ https-proxy-agent@^7.0.2: agent-base "^7.0.2" debug "4" -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== iconv-corefoundation@^1.1.7: version "1.1.7" @@ -3051,14 +3343,9 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: @@ -3074,6 +3361,15 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +internal-slot@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + internal-slot@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" @@ -3083,17 +3379,17 @@ internal-slot@^1.0.5: hasown "^2.0.0" side-channel "^1.0.4" -ip@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" - integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== +ip-regex@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-arguments@^1.0.4: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -3132,6 +3428,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -3144,13 +3445,18 @@ is-ci@^3.0.0: dependencies: ci-info "^3.2.0" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -3187,13 +3493,13 @@ is-hex-prefixed@1.0.0: is-interactive@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== +is-map@^2.0.2, is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== is-negative-zero@^2.0.2: version "2.0.2" @@ -3212,6 +3518,16 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-port-reachable@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-3.1.0.tgz#f6668d3bca9c36b07f737c48a8f875ab0653cd2b" + integrity sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -3220,6 +3536,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-set@^2.0.2, is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -3227,6 +3548,11 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -3255,9 +3581,19 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-url@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -3265,6 +3601,30 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +is2@^2.0.6: + version "2.0.9" + resolved "https://registry.yarnpkg.com/is2/-/is2-2.0.9.tgz#ff63b441f90de343fa8fac2125ee170da8e8240d" + integrity sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g== + dependencies: + deep-is "^0.1.3" + ip-regex "^4.1.0" + is-url "^1.2.4" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -3275,18 +3635,16 @@ isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isbinaryfile@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" - integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== - dependencies: - buffer-alloc "^1.2.0" - -isbinaryfile@^4.0.10: +isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== +isbinaryfile@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" + integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -3314,10 +3672,10 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -jackspeak@^2.0.3: - version "2.2.1" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz" - integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== +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: @@ -3343,7 +3701,7 @@ js-sha3@^0.5.7: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== -js-yaml@^4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -3406,7 +3764,7 @@ jsprim@^1.2.2: json-schema "0.4.0" verror "1.10.0" -jszip@^3.1.0: +jszip@^3.1.0, jszip@^3.10.0: version "3.10.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== @@ -3444,19 +3802,146 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash._arraycopy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1" + integrity sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A== + +lodash._arrayeach@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz#bab156b2a90d3f1bbd5c653403349e5e5933ef9e" + integrity sha512-Mn7HidOVcl3mkQtbPsuKR0Fj0N6Q6DQB77CtYncZcJc0bx5qv2q4Gl6a0LC1AN+GSxpnBDNnK3CKEm9XNA4zqQ== + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ== + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._baseclone@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz#303519bf6393fe7e42f34d8b630ef7794e3542b7" + integrity sha512-1K0dntf2dFQ5my0WoGKkduewR6+pTNaqX03kvs45y7G5bzl4B3kTR4hDfJIc2aCQDeLyQHhS280tc814m1QC1Q== + dependencies: + lodash._arraycopy "^3.0.0" + lodash._arrayeach "^3.0.0" + lodash._baseassign "^3.0.0" + lodash._basefor "^3.0.0" + lodash.isarray "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ== + +lodash._basefor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz#7550b4e9218ef09fad24343b612021c79b4c20c2" + integrity sha512-6bc3b8grkpMgDcVJv9JYZAk/mHgcqMljzm7OsbmcE2FGUMmmLQTPHlh/dFqR8LA0GQ7z4K67JSotVKu5058v1A== + +lodash._bindcallback@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ== + +lodash.clone@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-3.0.3.tgz#84688c73d32b5a90ca25616963f189252a997043" + integrity sha512-yVYPpFTdZDCLG2p07gVRTvcwN5X04oj2hu4gG6r0fer58JA08wAVxXzWM+CmmxO2bzOH8u8BkZTZqgX6juVF7A== + dependencies: + lodash._baseclone "^3.0.0" + lodash._bindcallback "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.defaultsdeep@4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.escape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw== + +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw== + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ== + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ== + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.mapvalues@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" + integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== + +lodash.merge@4.6.2, lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash@^4.17.15: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^4.1.0: +log-symbols@4.1.0, log-symbols@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" is-unicode-supported "^0.1.0" +loupe@2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" + integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== + dependencies: + get-func-name "^2.0.0" + lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" @@ -3474,36 +3959,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -lru-cache@^9.1.1: - version "9.1.2" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz" - integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== - -make-fetch-happen@^11.0.3: - version "11.1.1" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" +"lru-cache@^9.1.1 || ^10.0.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== matcher@^3.0.0: version "3.0.0" @@ -3512,6 +3971,11 @@ matcher@^3.0.0: dependencies: escape-string-regexp "^4.0.0" +matomo-tracker@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/matomo-tracker/-/matomo-tracker-2.2.4.tgz#ee397d915d7b2e7964996ca28a0a03f4f0692453" + integrity sha512-7fDy4wRhDQ1dnSxVqmnVqmmos9ACKag0fCBtBD3/Qeoqks7MFqXcO35nfS6S8xU/IXNf7534q/4Gx8fuWKYW6A== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -3521,6 +3985,15 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== + dependencies: + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -3531,6 +4004,11 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -3565,7 +4043,7 @@ mime@^2.5.2: mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mimic-response@^1.0.0: @@ -3595,21 +4073,21 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: +minimatch@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" + integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1, minimatch@^5.1.1: version "5.1.6" resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== @@ -3617,13 +4095,18 @@ minimatch@^5.0.1: brace-expansion "^2.0.1" minimatch@^9.0.1: - version "9.0.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz" - integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg== + 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.5, minimist@^1.2.6: +minimist@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -3635,45 +4118,6 @@ minimisted@^2.0.0: dependencies: minimist "^1.2.5" -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.3.tgz" - integrity sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ== - dependencies: - minipass "^5.0.0" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - minipass@^2.6.0, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" @@ -3694,10 +4138,10 @@ minipass@^5.0.0: resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"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@^1.3.3: version "1.3.3" @@ -3706,7 +4150,7 @@ minizlib@^1.3.3: dependencies: minipass "^2.9.0" -minizlib@^2.1.1, minizlib@^2.1.2: +minizlib@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -3738,6 +4182,46 @@ mkdirp@^1.0.3: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@^2.1.3: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + +mkpath@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-1.0.0.tgz#ebb3a977e7af1c683ae6fda12b545a6ba6c5853d" + integrity sha512-PbNHr7Y/9Y/2P5pKFv5XOGBfNQqZ+fdiHWcuf7swLACN5ZW5LU7J5tMU8LSBjpluAxAxKYGD9nnaIbdRy9+m1w== + +mocha@9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" + integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "4.2.1" + ms "2.1.3" + nanoid "3.3.1" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + mock-fs@^4.1.0: version "4.14.0" resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" @@ -3753,7 +4237,7 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0: +ms@2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3808,7 +4292,12 @@ nano-json-stream-parser@^0.1.2: resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== -negotiator@0.6.3, negotiator@^0.6.3: +nanoid@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + +negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== @@ -3818,12 +4307,46 @@ next-tick@^1.1.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -node-abi@^3.0.0: - version "3.45.0" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz" - integrity sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ== - dependencies: - semver "^7.3.5" +nightwatch-axe-verbose@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.0.3.tgz#719f0a1b53d611fa2b4872ee5730f5c0ad2c0cec" + integrity sha512-VxwYTXmdbWZ4GRxgAc0/6uZ1nDQ5/xnXUipLrxoUsLxrh9OjNmAwqlMsIlQN8o33XwbjGm+o9ikan5erYGEOFQ== + dependencies: + axe-core "^4.4.3" + +nightwatch@2.3: + version "2.3.9" + resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-2.3.9.tgz#3d3153d57a005e49689e5904d73a23b6bfb2c863" + integrity sha512-yjcri3URaV7bKCbTXJK0k7heBZ9OOGpuPdur4hQAxoODx/XuKVV53rtc7a/W4MZ39GhzepHKJCtelvrEu6nJeQ== + dependencies: + "@nightwatch/chai" "5.0.2" + ansi-to-html "0.7.2" + assertion-error "1.1.0" + boxen "5.1.2" + chai-nightwatch "0.5.3" + ci-info "3.3.0" + didyoumean "1.2.2" + dotenv "10.0.0" + ejs "3.1.8" + envinfo "7.8.1" + fs-extra "^10.1.0" + glob "^7.2.3" + lodash.clone "3.0.3" + lodash.defaultsdeep "4.6.1" + lodash.escape "4.0.1" + lodash.merge "4.6.2" + minimatch "3.1.2" + minimist "1.2.6" + mkpath "1.0.0" + mocha "9.2.2" + nightwatch-axe-verbose "2.0.3" + open "8.4.0" + ora "5.4.1" + selenium-webdriver "4.3.1" + semver "7.3.5" + stacktrace-parser "0.1.10" + strip-ansi "6.0.1" + uuid "8.3.2" node-addon-api@^1.6.3: version "1.7.2" @@ -3835,13 +4358,6 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== -node-api-version@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz" - integrity sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g== - dependencies: - semver "^7.3.5" - node-fetch@^2.6.0, node-fetch@^2.6.12: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -3854,23 +4370,6 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== -node-gyp@^9.0.0: - version "9.4.0" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.0.tgz" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - node-pty@^0.10.1: version "0.10.1" resolved "https://registry.npmjs.org/node-pty/-/node-pty-0.10.1.tgz" @@ -3878,13 +4377,6 @@ node-pty@^0.10.1: dependencies: nan "^2.14.0" -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -3895,15 +4387,12 @@ normalize-url@^6.0.1: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== +npm-run-path@^4.0.0, npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" + path-key "^3.0.0" number-to-bn@1.7.0: version "1.7.0" @@ -3928,6 +4417,14 @@ object-inspect@^1.13.1, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-is@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + object-keys@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" @@ -3964,16 +4461,25 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" -ora@^5.1.0: +open@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +ora@5.4.1: version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: bl "^4.1.0" @@ -3996,12 +4502,24 @@ p-cancelable@^3.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - aggregate-error "^3.0.0" + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" pako@^1.0.10, pako@~1.0.2: version "1.0.11" @@ -4018,29 +4536,39 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-scurry@^1.7.0: - version "1.9.2" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz" - integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== +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" - minipass "^5.0.0 || ^6.0.2" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +pathval@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + pbkdf2@^3.0.17: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -4067,12 +4595,27 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pid-port@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pid-port/-/pid-port-0.1.1.tgz#2ac86fa8a0e97ef2e7eb9e7e9567cdc1eda78098" + integrity sha512-boqPJtSgZC6KOgXKNPC+/XR3xwVtpOtaLa7JLcdf8jfVe0ZM2TwllBXxxLUO8GQbOLJ4/hEtf2+L1QCKbaoHUg== + dependencies: + execa "^5.0.0" + pify@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -plist@^3.0.1: +plist@^3.0.4: + version "3.0.6" + resolved "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" + integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== + dependencies: + base64-js "^1.5.1" + xmlbuilder "^15.1.1" + +plist@^3.0.5: version "3.1.0" resolved "https://registry.yarnpkg.com/plist/-/plist-3.1.0.tgz#797a516a93e62f5bde55e0b9cc9c967f860893c9" integrity sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ== @@ -4081,13 +4624,12 @@ plist@^3.0.1: base64-js "^1.5.1" xmlbuilder "^15.1.1" -plist@^3.0.4: - version "3.0.6" - resolved "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz" - integrity sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA== +process-exists@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/process-exists/-/process-exists-4.1.0.tgz#4132c516324c1da72d65896851cdbd8bbdf5b9d8" + integrity sha512-BBJoiorUKoP2AuM5q/yKwIfT1YWRHsaxjW+Ayu9erLhqKOfnXzzVVML0XTYoQZuI1YvcWKmc1dh06DEy4+KzfA== dependencies: - base64-js "^1.5.1" - xmlbuilder "^15.1.1" + ps-list "^6.3.0" process-nextick-args@~2.0.0: version "2.0.1" @@ -4099,14 +4641,14 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -progress@^2.0.3: +progress@2.0.3, progress@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-retry@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== dependencies: err-code "^2.0.2" @@ -4125,6 +4667,16 @@ proxy-from-env@^1.1.0: resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +ps-list@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-6.3.0.tgz#a2b775c2db7d547a28fbaa3a05e4c281771259be" + integrity sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA== + +ps-list@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.2.0.tgz#3d110e1de8249a4b178c9b1cf2a215d1e4e42fc0" + integrity sha512-v4Bl6I3f2kJfr5o80ShABNHAokIgY+wFDTQfE+X3zWYgSGQOCBeYptLZUpoOALBqO5EawmDN/tjTldJesd0ujQ== + psl@^1.1.28: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -4181,6 +4733,11 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" @@ -4208,11 +4765,12 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" -read-config-file@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.2.0.tgz#71536072330bcd62ba814f91458b12add9fc7ade" - integrity sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg== +read-config-file@6.3.2: + version "6.3.2" + resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.3.2.tgz#556891aa6ffabced916ed57457cb192e61880411" + integrity sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q== dependencies: + config-file-ts "^0.2.4" dotenv "^9.0.2" dotenv-expand "^5.1.0" js-yaml "^4.1.0" @@ -4307,7 +4865,7 @@ responselike@^2.0.0: restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -4315,7 +4873,7 @@ restore-cursor@^3.1.0: retry@^0.12.0: version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== rimraf@^3.0.0, rimraf@^3.0.2: @@ -4412,35 +4970,70 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" +selenium-standalone@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/selenium-standalone/-/selenium-standalone-9.3.1.tgz#a302ad9ab2f5d58f019895c87b4001de1c51969d" + integrity sha512-M/nHs/fbzCEr3370/ZlUXx8+Ia2aGbx5gSgONUn0ooCcFx8ScmouIWCp/Wms8dUTDiivC8F4WzXYRSCMIdiglw== + dependencies: + axios "^0.27.2" + commander "^8.3.0" + cross-spawn "^7.0.3" + debug "^4.3.1" + execa "^5.1.1" + find-process "^1.4.7" + fkill "^7.2.1" + got "^11.8.6" + is-port-reachable "^3.0.0" + lodash.mapvalues "^4.6.0" + lodash.merge "^4.6.2" + md5 "^2.3.0" + minimist "^1.2.5" + mkdirp "^2.1.3" + progress "2.0.3" + tar-stream "3.1.6" + which "^2.0.2" + yauzl "^2.10.0" + +selenium-webdriver@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.3.1.tgz#5e9c6c4adee65e57776b5bd4c07c59b65b8f056d" + integrity sha512-TjH/ls1WKRQoFEHcqtn6UtwcLnA3yvx08v9cSSFYvyhp8hJWRtbe9ae2I8uXPisEZ2EaGKKoxBZ4EHv0BJM15g== + dependencies: + jszip "^3.10.0" + tmp "^0.2.1" + ws ">=8.7.0" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== +semver@7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + semver@^6.2.0: version "6.3.0" resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.7, semver@^7.5.4: +semver@^7.2.1, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@^7.3.2, semver@^7.3.5: +semver@^7.3.2: version "7.5.3" resolved "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz" integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== dependencies: lru-cache "^6.0.0" -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -4467,6 +5060,13 @@ serialize-error@^7.0.1: dependencies: type-fest "^0.13.1" +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + serve-static@1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" @@ -4488,11 +5088,6 @@ servify@^0.1.12: request "^2.79.0" xhr "^2.3.3" -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - set-function-length@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" @@ -4503,6 +5098,18 @@ set-function-length@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + set-function-name@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -4551,15 +5158,15 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + 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.0.2" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz" - integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + 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" @@ -4584,12 +5191,12 @@ simple-get@^4.0.1: once "^1.3.1" simple-concat "^1.0.0" -simple-update-notifier@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" - integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== +simple-update-notifier@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== dependencies: - semver "~7.0.0" + semver "^7.5.3" slice-ansi@^3.0.0: version "3.0.0" @@ -4600,28 +5207,11 @@ slice-ansi@^3.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -smart-buffer@^4.0.2, smart-buffer@^4.2.0: +smart-buffer@^4.0.2: version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - source-map-support@^0.5.19: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" @@ -4655,12 +5245,12 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" -ssri@^10.0.0: - version "10.0.4" - resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz" - integrity sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ== +stacktrace-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== dependencies: - minipass "^5.0.0" + type-fest "^0.7.1" stat-mode@^1.0.0: version "1.0.0" @@ -4672,12 +5262,36 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +streamx@^2.15.0: + version "2.15.6" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.6.tgz#28bf36997ebc7bf6c08f9eba958735231b833887" + integrity sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== -"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: +"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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +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.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4688,7 +5302,7 @@ strict-uri-encode@^1.0.0: string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: eastasianwidth "^0.2.0" @@ -4736,7 +5350,14 @@ 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: +"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== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4750,6 +5371,11 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -4757,6 +5383,11 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + sumchecker@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" @@ -4764,6 +5395,13 @@ sumchecker@^3.0.1: dependencies: debug "^4.1.0" +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -4788,6 +5426,15 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" +tar-stream@3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + tar-stream@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" @@ -4812,10 +5459,10 @@ tar@^4.0.2: safe-buffer "^5.2.1" yallist "^3.1.1" -tar@^6.0.5, tar@^6.1.11, tar@^6.1.2: - version "6.1.15" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz" - integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== +tar@^6.1.12: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -4824,6 +5471,22 @@ tar@^6.0.5, tar@^6.1.11, tar@^6.1.2: mkdirp "^1.0.3" yallist "^4.0.0" +taskkill@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/taskkill/-/taskkill-3.1.0.tgz#28001339feb23bfae3f447902c4b4abcdd057680" + integrity sha512-5KcOFzPvd1nGFVrmB7H4+QAWVjYOf//+QTbOj0GpXbqtqbKGWVczG+rq6VhXAtdtlKLTs16NAmHRyF5vbggQ2w== + dependencies: + arrify "^2.0.1" + execa "^3.3.0" + +tcp-port-used@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.2.tgz#9652b7436eb1f4cfae111c79b558a25769f6faea" + integrity sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA== + dependencies: + debug "4.3.1" + is2 "^2.0.6" + temp-file@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" @@ -4837,6 +5500,11 @@ timed-out@^4.0.1: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== +tiny-typed-emitter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" + integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA== + tmp-promise@^3.0.2: version "3.0.3" resolved "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz" @@ -4844,7 +5512,7 @@ tmp-promise@^3.0.2: dependencies: tmp "^0.2.0" -tmp@^0.2.0: +tmp@^0.2.0, tmp@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== @@ -4905,11 +5573,26 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== +type-detect@4.0.8, type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.13.1: version "0.13.1" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -4979,6 +5662,11 @@ typescript@^5.1.3: resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz" integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== +typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" @@ -4994,20 +5682,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - universalify@^0.1.0: version "0.1.2" resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" @@ -5090,6 +5764,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -5135,7 +5814,7 @@ verror@^1.10.0: wcwidth@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" @@ -5406,6 +6085,16 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" @@ -5417,21 +6106,35 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: gopd "^1.0.1" has-tostringtag "^1.0.0" -which@^2.0.1, which@^2.0.2: +which@2.0.2, which@^2.0.1, which@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + +"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== dependencies: - string-width "^1.0.2 || 2 || 3 || 4" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -5442,7 +6145,7 @@ wide-align@^1.1.5: wrap-ansi@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: ansi-styles "^6.1.0" @@ -5459,6 +6162,11 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@>=8.7.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + ws@^3.0.0: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -5533,14 +6241,47 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.0.1, yargs@^17.5.1: +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.6.2: version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -5563,3 +6304,8 @@ yauzl@^2.10.0: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/libs/remix-core-plugin/src/lib/gist-handler.ts b/libs/remix-core-plugin/src/lib/gist-handler.ts index 83c932d4c69..afe415fc6b2 100644 --- a/libs/remix-core-plugin/src/lib/gist-handler.ts +++ b/libs/remix-core-plugin/src/lib/gist-handler.ts @@ -2,6 +2,7 @@ 'use strict' import { Plugin } from '@remixproject/engine' import isElectron from 'is-electron' +import { Registry } from '@remix-project/remix-lib' interface StringByString { [key: string]: string; @@ -17,12 +18,16 @@ const profile = { type GistCallBackFn = (gistId: string) => void export class GistHandler extends Plugin { - constructor () { + isDesktop: boolean = false + constructor() { super(profile) + if (Registry.getInstance().get('platform').api.isDesktop()) { + this.isDesktop = true + } } - async handleLoad (gistId: string | null, cb: GistCallBackFn) { - if (!cb) cb = () => {} + async handleLoad(gistId: string | null, cb: GistCallBackFn) { + if (!cb) cb = () => { } let loadingFromGist = false if (!gistId) { @@ -36,7 +41,7 @@ export class GistHandler extends Plugin { title: 'Load a Gist', message: 'Enter the ID of the Gist or URL you would like to load.', modalType: 'prompt', - okLabel: 'OK', + okLabel: (this.isDesktop ? 'Load and select destination' : 'OK'), cancelLabel: 'Cancel', okFn: (value) => { setTimeout(() => resolve(value), 0) @@ -86,7 +91,7 @@ export class GistHandler extends Plugin { return loadingFromGist } - load (gistId: string | null) { + load(gistId: string | null) { const self = this return self.handleLoad(gistId, async (gistId: string | null) => { let data: any @@ -115,34 +120,39 @@ export class GistHandler extends Plugin { } const gistIdWorkspace = 'gist ' + gistId - const workspaces = await this.call('filePanel', 'getWorkspaces') - const found = workspaces.find((workspace) => workspace.name === gistIdWorkspace) - if (found) { - await this.call('notification', 'alert', { - id: 'gistAlert', - message: `workspace "${gistIdWorkspace}" already exists`, - }) - return - } - await this.call('filePanel', 'createWorkspace', 'gist ' + gistId, '', true) - await this.call('filePanel', 'switchToWorkspace', { name: 'gist ' + gistId, isLocalHost: false }) - const obj: StringByString = {} Object.keys(data.files).forEach((element) => { const path = element.replace(/\.\.\./g, '/') obj['/' + path] = data.files[element] }) - this.call('fileManager', 'setBatchFiles', obj, isElectron()? 'electron':'workspace', true, async (errorSavingFiles: any) => { - if (errorSavingFiles) { - const modalContent = { - id: 'gisthandler', - title: 'Gist load error', - message: errorSavingFiles.message || errorSavingFiles - } - this.call('notification', 'alert', modalContent) + + if (this.isDesktop) { + await this.call('remix-templates', 'loadFilesInNewWindow', obj) + } else { + const workspaces = await this.call('filePanel', 'getWorkspaces') + const found = workspaces.find((workspace) => workspace.name === gistIdWorkspace) + if (found) { + await this.call('notification', 'alert', { + id: 'gistAlert', + message: `workspace "${gistIdWorkspace}" already exists`, + }) + return } - }) + await this.call('filePanel', 'createWorkspace', 'gist ' + gistId, '', true) + await this.call('filePanel', 'switchToWorkspace', { name: 'gist ' + gistId, isLocalHost: false }) + this.call('fileManager', 'setBatchFiles', obj, isElectron() ? 'electron' : 'workspace', true, async (errorSavingFiles: any) => { + if (errorSavingFiles) { + const modalContent = { + id: 'gisthandler', + title: 'Gist load error', + message: errorSavingFiles.message || errorSavingFiles + + } + this.call('notification', 'alert', modalContent) + } + }) + } }) } } diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFileElectron.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFileElectron.tsx index 1f67cfaff5a..3d9fdd3c8f9 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabFileElectron.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFileElectron.tsx @@ -32,9 +32,9 @@ export const HomeTabFileElectron = ({ plugin }: HomeTabFileProps) => {
- - - + + +
) diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabScamAlert.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabScamAlert.tsx index 9b75082b53f..1d674824f96 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabScamAlert.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabScamAlert.tsx @@ -1,10 +1,12 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import React from 'react' +import { appPlatformTypes, platformContext } from '@remix-ui/app' +import React, { useContext } from 'react' import {FormattedMessage} from 'react-intl' const _paq = (window._paq = window._paq || []) // eslint-disable-line function HomeTabScamAlert() { + const platform = useContext(platformContext) return (