diff --git a/.circleci/config.yml b/.circleci/config.yml index 11c6ede82b..8bcbed1fca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,17 +29,17 @@ jobs: - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - save_cache: - key: v1-deps-{{ checksum "package-lock.json" }} + key: v1-deps-{{ checksum "yarn.lock" }} paths: - node_modules - - run: npm run downloadsolc_assets + - run: yarn run downloadsolc_assets - run: npx nx build remix-ide - run: npx nx build remix-ide-e2e-src-local-plugin - - run: npm run build:libs + - run: yarn run build:libs - run: mkdir persist && zip -r persist/dist.zip dist - persist_to_workspace: root: . @@ -64,8 +64,8 @@ jobs: - checkout - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Remix Libs Linting command: ./apps/remix-ide/ci/lint.sh @@ -91,10 +91,10 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm i - - run: cd dist/libs/remix-tests && npm install - - run: npm run test:libs + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install + - run: cd dist/libs/remix-tests && yarn install + - run: yarn run test:libs remix-ide-chrome: docker: @@ -127,8 +127,8 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -170,8 +170,8 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -213,8 +213,8 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -255,8 +255,8 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -298,8 +298,8 @@ jobs: - run: unzip ./persist/dist.zip - restore_cache: keys: - - v1-deps-{{ checksum "package-lock.json" }} - - run: npm install + - v1-deps-{{ checksum "yarn.lock" }} + - run: yarn install - run: name: Start Selenium command: java -jar /usr/local/bin/selenium.jar @@ -328,9 +328,9 @@ jobs: steps: - checkout - - run: npm install - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | @@ -357,9 +357,9 @@ jobs: steps: - checkout - - run: npm install - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | @@ -385,10 +385,10 @@ jobs: steps: - checkout - - run: npm install - - run: npm run build:libs - - run: npm run downloadsolc_assets - - run: npm run build:production + - run: yarn install + - run: yarn run build:libs + - run: yarn run downloadsolc_assets + - run: yarn run build:production - run: name: Deploy command: | diff --git a/.github/workflows/publish-action.yml b/.github/workflows/publish-action.yml index b023c4ffcc..9cf0674850 100644 --- a/.github/workflows/publish-action.yml +++ b/.github/workflows/publish-action.yml @@ -9,18 +9,20 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - run: npm install + - uses: actions/setup-node@v3 + with: + node-version: 14.17.6 + - run: yarn install - run: ls - run: pwd - - run: npm run downloadsolc_assets - - run: npm run build:production - - run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs')" >> $GITHUB_ENV + - run: yarn run downloadsolc_assets + - run: yarn run build:production + - run: echo "action_state=$('./apps/remix-ide/ci/publishIpfs' ${{ secrets.IPFS_PROJET_ID }} ${{ secrets.IPFS_PROJECT_SECRET }})" >> $GITHUB_ENV - uses: mshick/add-pr-comment@v1 with: message: | ipfs://${{ env.action_state }} - https://ipfs.remixproject.org/ipfs/${{ env.action_state }} - https://gateway.ipfs.io/ipfs/${{ env.action_state }} + https://remix-project.infura-ipfs.io/ipfs/${{ env.action_state }} repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens allow-repeats: false # This is the default diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 45fe8a3680..623b4aea25 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,6 +12,6 @@ When you add a code in any library, please ensure you add related tests. You can Please conform to [standard](https://standardjs.com/) for code styles. ## Submitting Pull Request -Please follow Github's standard model of making changes & submitting pull request which is very well explained [here](https://guides.github.com/activities/forking/). Make sure your code works fine locally before submitting a pull request. +Please follow GitHub's standard model of making changes & submitting pull request which is very well explained [here](https://guides.github.com/activities/forking/). Make sure your code works fine locally before submitting a pull request. diff --git a/README.md b/README.md index b8f700f796..aea4299352 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,23 @@ [![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=social)](https://twitter.com/ethereumremix) # Remix Project +**Remix Project** is a rich toolset including Remix IDE, a comprehensive smart contract development tool. The Remix Project also includes Remix Plugin Engine and Remix Libraries which are low-level tools for wider use. -**Remix Project** is a platform for development tools that use a plugin architecture. It encompasses sub-projects including Remix Plugin Engine, Remix Libraries, and of course Remix IDE. +## Remix IDE +**Remix IDE** is used for the entire journey of contract development by users of any knowledge level. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. The IDE comes in 2 flavors and a VSCode extension: -**Remix IDE** is an open source web and desktop application. It fosters a fast development cycle and has a rich set of plugins with intuitive GUIs. Remix is used for the **entire journey of contract development with [Solidity language](https://soliditylang.org/)** as well as a playground for learning and teaching [Ethereum](https://ethereum.org/). +**Remix Online IDE**, see: [https://remix.ethereum.org](https://remix.ethereum.org) -Start developing using Remix on browser, visit: [https://remix.ethereum.org](https://remix.ethereum.org) +:point_right: Supported browsers: Firefox v100.0.1 & Chrome v101.0.4951.64. No support for Remix's use on tablets or smartphones or telephones. -For desktop version, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases) +**Remix Desktop IDE**, see releases: [https://github.com/ethereum/remix-desktop/releases](https://github.com/ethereum/remix-desktop/releases) -![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix_screenshot.png) +![Remix screenshot](https://github.com/ethereum/remix-project/raw/master/apps/remix-ide/remix-screenshot-400h.png) -:point_right: **Remix libraries** work as a core of native plugins of Remix IDE. Read more about libraries [here](libs/README.md) +**VSCode extension**, see: [Ethereum-Remix](https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix) + +## Remix libraries +Remix libraries are essential for Remix IDE's native plugins. Read more about libraries [here](libs/README.md) ## Offline Usage @@ -30,7 +35,7 @@ Note: It contains the latest supported version of Solidity available at the time ## Setup -* Install **NPM** and **Node.js**. See [Guide](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
+* Install **Yarn** and **Node.js**. See [Guide for NodeJs](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn install](https://classic.yarnpkg.com/lang/en/docs/install)
*Supported versions:* ```bash "engines": { @@ -40,7 +45,7 @@ Note: It contains the latest supported version of Solidity available at the time ``` * Install [Nx CLI](https://nx.dev/react/cli/overview) globally to enable running **nx executable commands**. ```bash -npm install -g @nrwl/cli +yarn global add @nrwl/cli ``` * Clone the github repository (`wget` need to be installed first): @@ -50,8 +55,8 @@ git clone https://github.com/ethereum/remix-project.git * Build `remix-project`: ```bash cd remix-project -npm install -npm run build:libs // Build remix libs +yarn install +yarn run build:libs // Build remix libs nx build nx serve ``` @@ -63,12 +68,12 @@ Go to your `text editor` and start developing. Browser will automatically refres ## Production Build To generate react production builds for remix-project. ```bash -npm run build:production +yarn run build:production ``` Build can be found in `remix-project/dist/apps/remix-ide` directory. ```bash -npm run serve:production +yarn run serve:production ``` Production build will be served by default to `http://localhost:8080/` or `http://127.0.0.1:8080/` @@ -133,78 +138,138 @@ For example, to run unit tests of `remix-analyzer`, use `nx test remix-analyzer` To run the Selenium tests via Nightwatch: - - Install Selenium for first time: `npm run selenium-install` - - Run a selenium server: `npm run selenium` + - Install Selenium for first time: `yarn run selenium-install` + - Run a selenium server: `yarn run selenium` - Build & Serve Remix: `nx serve` - Run all the end-to-end tests: - for Firefox: `npm run nightwatch_local_firefox`, or + for Firefox: `yarn run nightwatch_local_firefox`, or - for Google Chrome: `npm run nightwatch_local_chrome` - - Run a specific test case instead, use one of following commands: + for Google Chrome: `yarn run nightwatch_local_chrome` + - Run a specific test case instead, use a command like this: - - npm run nightwatch_local_ballot - - - npm run nightwatch_local_usingWorker - - - npm run nightwatch_local_libraryDeployment - - - npm run nightwatch_local_solidityImport + - yarn run nightwatch_local_ballot - - npm run nightwatch_local_recorder - - - npm run nightwatch_local_transactionExecution - - - npm run nightwatch_local_staticAnalysis - - - npm run nightwatch_local_signingMessage + The package.json file contains a list of all the tests you can run. + +**NOTE:** - - npm run nightwatch_local_specialFunctions +- **The `ballot` tests suite** requires to run `ganache-cli` locally. - - npm run nightwatch_local_solidityUnitTests +- **The `remixd` tests suite** requires to run `remixd` locally. - - npm run nightwatch_local_remixd # remixd needs to be run +- **The `gist` tests suite** requires specifying a github access token in **.env file**. +``` + gist_token = // token should have permission to create a gist +``` - - npm run nightwatch_local_terminal +### Using 'select_test' for locally running specific tests - - npm run nightwatch_local_gist +There is a script to allow selecting the browser and a specific test to run: - - npm run nightwatch_local_workspace +``` +yarn run select_test +``` - - npm run nightwatch_local_defaultLayout +You need to have - - npm run nightwatch_local_pluginManager +- selenium running - - npm run nightwatch_local_publishContract +- the IDE running - - npm run nightwatch_local_generalSettings +- optionally have remixd or ganache running - - npm run nightwatch_local_fileExplorer +### Splitting tests with groups - - npm run nightwatch_local_debugger +Groups can be used to group tests in a test file together. The advantage is you can avoid running long test files when you want to focus on a specific set of tests within a test file.x - - npm run nightwatch_local_editor +These groups only apply to the test file, not across all test files. So for example group1 in the ballot is not related to group1 in another test file. - - npm run nightwatch_local_compiler +Running a group only runs the tests marked as belonging to the group + all the tests in the test file that do not have a group tag. This way you can have tests that run for all groups, for example to peform common actions. - - npm run nightwatch_local_txListener +There is no need to number the groups in a certain order. The number of the group is arbitrary. - - npm run nightwatch_local_fileManager +A test can have multiple group tags, this means that this test will run in different groups. - - npm run nightwatch_local_runAndDeploy - - -**NOTE:** +You should write your tests so they can be executed in groups and not depend on other groups. -- **The `ballot` tests suite** requires to run `ganache-cli` locally. +To do this you need to: -- **The `remixd` tests suite** requires to run `remixd` locally. +- Add a group to tag to a test, they are formatted as #group followed by a number: so it becomes #group1, #group220, #group4. Any number will do. You don't have to do it in specific order. -- **The `gist` tests suite** requires specifying a github access token in **.env file**. ``` - gist_token = // token should have permission to create a gist + 'Should generate test file #group1': function (browser: NightwatchBrowser) { + browser.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]') ``` +- add '@disable': true to the test file you want to split: + +``` +module.exports = { + '@disabled': true, + before: function (browser: NightwatchBrowser, done: VoidFunction) { + init(browser, done) // , 'http://localhost:8080', false) + }, +``` +- change package json to locally run all group tests: + +``` + "nightwatch_local_debugger": "yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/debugger_*.spec.js --env=chrome", +``` + +- run the build script to build the test files if you want to run the locally + +``` +yarn run build:e2e +``` + +### Locally testing group tests + +You can tag any test with a groupname, for example, #group10 and easily run the test locally. + +- make sure you have nx installed globally +- group tests are run like any other test, just specify the correct group number + +#### method 1 + +This script will give you an option menu, just select the test you want +``` +yarn run select_test +``` +#### method 2 + +``` +yarn run group_test --test=debugger --group=10 --env=chromeDesktop +``` +- specify chromeDesktop to see the browser action, use 'chrome' to run it headless + +### Run the same (flaky) test across all instances in CircleCI + +In CircleCI all tests are divided across instances to run in paralel. +You can also run 1 or more tests simultaneously across all instances. +This way the pipeline can easily be restarted to check if a test is flaky. + +For example: + +``` + 'Static Analysis run with remixd #group3 #flaky': function (browser) { +``` + +Now group3 of this test will be executed in firefox and chrome 80 times. +If you mark more groups in other tests they will also be executed. + +**CONFIGURATION** + +It's important to set a parameter in the .circleci/config.yml, set it to false then the normal tests will run. +Set it to true to run only tests marked with flaky. +``` +parameters: + run_flaky_tests: + type: boolean + default: true +``` + + ## Important Links - Official documentation: https://remix-ide.readthedocs.io/en/latest/ diff --git a/apps/remix-ide-e2e/src/commands/verifyContracts.ts b/apps/remix-ide-e2e/src/commands/verifyContracts.ts index aef1b06217..f29c3e42c6 100644 --- a/apps/remix-ide-e2e/src/commands/verifyContracts.ts +++ b/apps/remix-ide-e2e/src/commands/verifyContracts.ts @@ -2,7 +2,7 @@ import { NightwatchBrowser } from 'nightwatch' import EventEmitter from 'events' class VerifyContracts extends EventEmitter { - command (this: NightwatchBrowser, compiledContractNames: string[], opts = { wait: 1000, version: null }): NightwatchBrowser { + command (this: NightwatchBrowser, compiledContractNames: string[], opts = { wait: 1000, version: null, runs: '200' }): NightwatchBrowser { this.api.perform((done) => { verifyContracts(this.api, compiledContractNames, opts, () => { done() @@ -13,13 +13,13 @@ class VerifyContracts extends EventEmitter { } } -function verifyContracts (browser: NightwatchBrowser, compiledContractNames: string[], opts: { wait: number, version?: string }, callback: VoidFunction) { +function verifyContracts (browser: NightwatchBrowser, compiledContractNames: string[], opts: { wait: number, version?: string, runs?: string }, callback: VoidFunction) { browser .clickLaunchIcon('solidity') .pause(opts.wait) .pause(5000) .waitForElementPresent('*[data-id="compiledContracts"] option', 60000) - .perform((done) => { + .perform(async (done) => { if (opts.version) { browser .click('*[data-id="compilation-details"]') @@ -36,10 +36,28 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str done() callback() }) - } else { - compiledContractNames.forEach((name) => { - browser.waitForElementContainsText('[data-id="compiledContracts"]', name, 60000) + } if (opts.runs) { + browser + .click('*[data-id="compilation-details"]') + .waitForElementVisible('*[data-id="remixui_treeviewitem_metadata"]') + .pause(2000) + .click('*[data-id="remixui_treeviewitem_metadata"]') + .waitForElementVisible('*[data-id="treeViewDivtreeViewItemsettings"]') + .pause(2000) + .click('*[data-id="treeViewDivtreeViewItemsettings"]') + .waitForElementVisible('*[data-id="treeViewDivtreeViewItemoptimizer"]') + .click('*[data-id="treeViewDivtreeViewItemoptimizer"]') + .waitForElementVisible('*[data-id="treeViewDivruns"]') + .assert.containsText('*[data-id="treeViewDivruns"]', `${opts.runs}`) + .click('[data-id="workspacesModalDialog-modal-footer-ok-react"]') + .perform(() => { + done() + callback() }) + } else { + for (const index in compiledContractNames) { + await browser.waitForElementContainsText('[data-id="compiledContracts"]', compiledContractNames[index], 60000) + } done() callback() } diff --git a/apps/remix-ide-e2e/src/select_tests.sh b/apps/remix-ide-e2e/src/select_tests.sh index 65fa5c1656..ee1c4e38be 100644 --- a/apps/remix-ide-e2e/src/select_tests.sh +++ b/apps/remix-ide-e2e/src/select_tests.sh @@ -24,7 +24,7 @@ do *) echo "invalid option $REPLY";; esac done -npm run build:e2e +yarn run build:e2e PS3='Select a test or command: ' TESTFILES=( $(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test\|plugin_api" | sort ) ) @@ -42,6 +42,6 @@ do done else # run the selected test - npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER + yarn run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $opt --env=$BROWSER fi done diff --git a/apps/remix-ide-e2e/src/tests/ballot.test.ts b/apps/remix-ide-e2e/src/tests/ballot.test.ts index 794dee9775..5244241e89 100644 --- a/apps/remix-ide-e2e/src/tests/ballot.test.ts +++ b/apps/remix-ide-e2e/src/tests/ballot.test.ts @@ -122,6 +122,24 @@ module.exports = { }) // Test in Udapp UI , treeViewDiv0 shows returned value on method click .assert.containsText('*[data-id="treeViewDiv0"]', 'bytes32: winnerName_ 0x48656c6c6f20576f726c64210000000000000000000000000000000000000000') + }, + + 'Compile Ballot using config file': function (browser: NightwatchBrowser) { + browser + .addFile('cf.json', {content: configFile}) + .clickLaunchIcon('solidity') + .waitForElementVisible('*[data-id="scConfigExpander"]') + .click('*[data-id="scConfigExpander"]') + .waitForElementVisible('*[data-id="scFileConfiguration"]', 10000) + .click('*[data-id="scFileConfiguration"]') + .waitForElementVisible('*[data-id="scConfigChangeFilePath"]', 10000) + .click('*[data-id="scConfigChangeFilePath"]') + .waitForElementVisible('*[data-id="scConfigFilePathInput"]', 10000) + .clearValue('*[data-id="scConfigFilePathInput"]') + .setValue('*[data-id="scConfigFilePathInput"]', 'cf.json') + .sendKeys('*[data-id$="scConfigFilePathInput"]', browser.Keys.ENTER) + .openFile('Untitled.sol') + .verifyContracts(['Ballot'], {wait: 2000, runs: '300'}) .end() } } @@ -190,6 +208,7 @@ const stateCheck = { immutable: false } } + const ballotABI = `[ { "inputs": [ @@ -356,3 +375,22 @@ const ballotABI = `[ "type": "function" } ]` + +const configFile = ` +{ + "language": "Solidity", + "settings": { + "optimizer": { + "enabled": true, + "runs": 300 + }, + "outputSelection": { + "*": { + "": ["ast"], + "*": ["abi", "metadata", "devdoc", "userdoc", "storageLayout", "evm.legacyAssembly", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers", "evm.gasEstimates", "evm.assembly"] + } + }, + "evmVersion": "byzantium" + } +} +` \ No newline at end of file diff --git a/apps/remix-ide-e2e/src/tests/compiler_api.test.ts b/apps/remix-ide-e2e/src/tests/compiler_api.test.ts index 8a6ca27cd3..0646b83f80 100644 --- a/apps/remix-ide-e2e/src/tests/compiler_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/compiler_api.test.ts @@ -46,7 +46,7 @@ module.exports = { browser .addFile('test_updateConfiguration.js', { content: updateConfiguration }) .executeScript('remix.exeCurrent()') - .pause(5000) + .pause(15000) .addFile('test_updateConfiguration.sol', { content: simpleContract }) .verifyContracts(['StorageTestUpdateConfiguration'], { wait: 5000, version: '0.6.8+commit.0bbfe453' }) }, @@ -168,3 +168,4 @@ contract DoesNotCompile { function fStackLimit(uint u1, uint u2, uint u3, uint u4, uint u5, uint u6, uint u7, uint u8, uint u9, uint u10, uint u11, uint u12) public { } }` + diff --git a/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts b/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts index 78e4ee8f1a..32da1f4828 100644 --- a/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/fileManager_api.test.ts @@ -71,7 +71,7 @@ module.exports = { .addFile('mkdirFile.js', { content: executeMkdir }) .executeScript('remix.exeCurrent()') .pause(2000) - .waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 60000) + .waitForElementPresent('[data-id="treeViewLitreeViewItemTest_Folder"]', 80000) }, 'Should execute `readdir` api from file manager external api #group3': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts index b68299e79f..bf4936a2d4 100644 --- a/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts +++ b/apps/remix-ide-e2e/src/tests/importFromGithub.test.ts @@ -23,7 +23,7 @@ module.exports = { .pause(1000) .click('button[data-id="landingPageImportFromGitHubButton"]') .waitForElementVisible('*[data-id="homeTabModalDialogModalTitle-react"]') - .assert.containsText('*[data-id="homeTabModalDialogModalTitle-react"]', 'Import from Github') + .assert.containsText('*[data-id="homeTabModalDialogModalTitle-react"]', 'Import from GitHub') .waitForElementVisible('*[data-id="homeTabModalDialogModalBody-react"]') .assert.containsText('*[data-id="homeTabModalDialogModalBody-react"]', 'Enter the github URL you would like to load.') .waitForElementVisible('input[data-id="homeTabModalDialogCustomPromptText"]') @@ -41,7 +41,7 @@ module.exports = { .assert.containsText('*[data-shared="tooltipPopup"] span', 'not found ' + testData.invalidURL) }, - 'Import From Github For Valid URL #group2': function (browser: NightwatchBrowser) { + 'Import From GitHub For Valid URL #group2': function (browser: NightwatchBrowser) { browser .waitForElementVisible('*[data-id="remixIdeIconPanel"]', 10000) .clickLaunchIcon('filePanel') @@ -62,7 +62,7 @@ module.exports = { browser.assert.ok(content.indexOf('library Roles {') !== -1, 'content does contain "library Roles {"') }) }, - 'Import JSON From Github For Valid URL #group2': function (browser: NightwatchBrowser) { + 'Import JSON From GitHub For Valid URL #group2': function (browser: NightwatchBrowser) { browser .click('div[title="home"]') .click('button[data-id="landingPageImportFromGitHubButton"]') diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index d0cdfacf13..faabf03247 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -230,7 +230,12 @@ module.exports = { }, 'Should get current files #group7': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, '/') + await clickAndCheckLog(browser, 'fileManager:readdir', { + contracts: { isDirectory: true }, + scripts: { isDirectory: true }, + tests: { isDirectory: true }, + 'README.txt': { isDirectory: false } + }, null, '/') }, 'Should throw error on current file #group7': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'fileManager:getCurrentFile', 'Error from IDE : Error: No such file or directory No file selected', null, null) @@ -285,7 +290,12 @@ module.exports = { 'Should create workspace #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'testspace') await clickAndCheckLog(browser, 'filePanel:getCurrentWorkspace', { name: 'testspace', isLocalhost: false, absolutePath: '.workspaces/testspace' }, null, null) - await clickAndCheckLog(browser, 'fileManager:readdir', { contracts: { isDirectory: true }, scripts: { isDirectory: true }, tests: { isDirectory: true }, 'README.txt': { isDirectory: false } }, null, null) + await clickAndCheckLog(browser, 'fileManager:readdir', { + contracts: { isDirectory: true }, + scripts: { isDirectory: true }, + tests: { isDirectory: true }, + 'README.txt': { isDirectory: false } + }, null, null) }, 'Should get all workspaces #group2': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:getWorkspaces', ['default_workspace', 'emptyworkspace', 'testspace'], null, null) @@ -409,7 +419,7 @@ module.exports = { .addFile('test_modal.js', { content: testModalToasterApi }) .executeScript('remix.execute(\'test_modal.js\')') .useCss() - .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]') + .waitForElementVisible('*[data-id="test_id_1_ModalDialogModalBody-react"]', 60000) .assert.containsText('*[data-id="test_id_1_ModalDialogModalBody-react"]', 'message 1') .modalFooterOKClick('test_id_1_') // check the script runner notifications diff --git a/apps/remix-ide-e2e/src/tests/providers.test.ts b/apps/remix-ide-e2e/src/tests/providers.test.ts index 8bbfa7636b..b2c883fd53 100644 --- a/apps/remix-ide-e2e/src/tests/providers.test.ts +++ b/apps/remix-ide-e2e/src/tests/providers.test.ts @@ -29,5 +29,31 @@ module.exports = { .waitForElementVisible('*[data-id="ganache-providerModalDialogModalBody-react"]') .modalFooterOKClick('ganache-provider') .waitForElementContainsText('*[data-id="settingsNetworkEnv"]', 'Custom (') + }, + + 'Should switch to foundry provider, set a custom URL and fail to connect': function (browser: NightwatchBrowser) { + browser.waitForElementVisible('div[data-id="remixIdeIconPanel"]', 10000) + .click('*[data-id="Foundry Provider"]') + .waitForElementVisible('*[data-id="foundry-providerModalDialogModalBody-react"]') + .execute(() => { + (document.querySelector('*[data-id="foundry-providerModalDialogModalBody-react"] input') as any).focus() + }, [], () => {}) + .clearValue('*[data-id="foundry-providerModalDialogModalBody-react"] input') + .setValue('*[data-id="foundry-providerModalDialogModalBody-react"] input', 'http://127.0.0.1:8084') + .modalFooterOKClick('foundry-provider') + .waitForElementContainsText('*[data-id="foundry-providerModalDialogModalBody-react"]', 'Error while connecting to the provider') + .modalFooterOKClick('foundry-provider') + .waitForElementNotVisible('*[data-id="foundry-providerModalDialogModalBody-react"]') + .waitForElementVisible('*[data-id="PermissionHandler-modal-footer-ok-react"]') + .click('*[data-id="PermissionHandler-modal-footer-ok-react"]') + .waitForElementNotVisible('*[data-id="PermissionHandler-modal-footer-ok-react"]') + .pause(1000) + +}, + 'Should switch to foundry provider, use the default foundry URL and succeed to connect': function (browser: NightwatchBrowser) { + browser.click('*[data-id="Foundry Provider"]') + .waitForElementVisible('*[data-id="foundry-providerModalDialogModalBody-react"]') + .modalFooterOKClick('foundry-provider') + .waitForElementContainsText('*[data-id="settingsNetworkEnv"]', 'Custom (') } } diff --git a/apps/remix-ide-e2e/src/tests/publishContract.test.ts b/apps/remix-ide-e2e/src/tests/publishContract.test.ts index e1a19ccabb..38ee1c3e54 100644 --- a/apps/remix-ide-e2e/src/tests/publishContract.test.ts +++ b/apps/remix-ide-e2e/src/tests/publishContract.test.ts @@ -19,17 +19,22 @@ module.exports = { .openFile('contracts/3_Ballot.sol') .verifyContracts(['Ballot']) .click('#publishOnIpfs') + .pause(2000) + .waitForElementVisible('[data-id="publishToStorageModalDialogModalBody-react"]', 60000) + .click('[data-id="publishToStorage-modal-footer-ok-react"]') .pause(8000) .waitForElementVisible('[data-id="publishToStorageModalDialogModalBody-react"]', 60000) .getText('[data-id="publishToStorageModalDialogModalBody-react"]', (result) => { const value = (result.value) browser.perform((done) => { - if (value.indexOf('Metadata of "ballot" was published successfully.') === -1) browser.assert.fail('ipfs deploy failed') + if (value.indexOf('Metadata and sources of "ballot" were published successfully.') === -1) browser.assert.fail('ipfs deploy failed') done() }) }) .click('[data-id="publishToStorage-modal-footer-ok-react"]') + .openFile('ipfs/QmSUodhSvoorFL5m5CNqve8YvmuBpjCq17NbTf4GUX8ydw') + .openFile('ipfs/QmXYUS1ueS22EqNVRaKuZa31EgHLjKZ8uTM8vWhQLxa3pw') }, /* Disableing the test untill refactoring and the new swarm usage @@ -41,7 +46,7 @@ module.exports = { const value = (result.value) browser.perform((done) => { - if (value.indexOf('Metadata of "ballot" was published successfully.') === -1) browser.assert.fail('swarm deploy failed') + if (value.indexOf('Metadata and sources of "ballot" were published successfully.') === -1) browser.assert.fail('swarm deploy failed') if (value.indexOf('bzz') === -1) browser.assert.fail('swarm deploy failed') done() }) @@ -61,11 +66,13 @@ module.exports = { .waitForElementVisible('*[data-id="Deploy - transact (not payable)"]') .click('*[data-id="Deploy - transact (not payable)"]') .pause(5000) - .waitForElementVisible('[data-id="udappModalDialogModalBody-react"]') + .waitForElementVisible('[data-id="udappModalDialogModalBody-react"]', 60000) + .modalFooterOKClick('udapp') + .pause(8000) .getText('[data-id="udappModalDialogModalBody-react"]', (result) => { const value = typeof result.value === 'string' ? result.value : null - if (value.indexOf('Metadata of "storage" was published successfully.') === -1) browser.assert.fail('ipfs deploy failed') + if (value.indexOf('Metadata and sources of "storage" were published successfully.') === -1) browser.assert.fail('ipfs deploy failed') }) .modalFooterOKClick('udapp') }, diff --git a/apps/remix-ide-e2e/src/tests/recorder.test.ts b/apps/remix-ide-e2e/src/tests/recorder.test.ts index fc77f0ef0f..7e1c0859a7 100644 --- a/apps/remix-ide-e2e/src/tests/recorder.test.ts +++ b/apps/remix-ide-e2e/src/tests/recorder.test.ts @@ -17,7 +17,7 @@ module.exports = { .pause(5000) .clickLaunchIcon('udapp') .selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite - .click('[data-id="udapp_arrow"]') + .click('[data-id="udappRecorderTitleExpander"]') .click('[data-id="runtransaction"]') .clickInstance(0) .clickInstance(1) diff --git a/apps/remix-ide-e2e/src/tests/search.test.ts b/apps/remix-ide-e2e/src/tests/search.test.ts index f7925fb9ea..9791bae4c5 100644 --- a/apps/remix-ide-e2e/src/tests/search.test.ts +++ b/apps/remix-ide-e2e/src/tests/search.test.ts @@ -33,11 +33,11 @@ module.exports = { .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, 48) + 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, 42) + 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"]', '.*/**/*') @@ -78,7 +78,7 @@ module.exports = { .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, 13) + Array.isArray(res.value) && browser.assert.equal(res.value.length, 15) }) }, 'Should replace text': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide-e2e/src/tests/solidityImport.test.ts b/apps/remix-ide-e2e/src/tests/solidityImport.test.ts index 2c0e8d4b99..3d2089fc8c 100644 --- a/apps/remix-ide-e2e/src/tests/solidityImport.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityImport.test.ts @@ -30,7 +30,7 @@ module.exports = { .assert.containsText('#compileTabView .error pre', 'not found Untitled11.sol') }, - 'Test Github Import - from master branch #group1': function (browser: NightwatchBrowser) { + 'Test GitHub Import - from master branch #group1': function (browser: NightwatchBrowser) { browser .setSolidityCompilerVersion('soljson-v0.8.0+commit.c7dfd78e.js') // open-zeppelin moved to pragma ^0.8.0 (master branch) .addFile('Untitled4.sol', sources[3]['Untitled4.sol']) @@ -38,7 +38,7 @@ module.exports = { .verifyContracts(['test7', 'ERC20'], { wait: 10000 }) }, - 'Test Github Import - from other branch #group2': function (browser: NightwatchBrowser) { + 'Test GitHub Import - from other branch #group2': function (browser: NightwatchBrowser) { browser .setSolidityCompilerVersion('soljson-v0.5.0+commit.1d4f565a.js') // switch back to 0.5.0 : release-v2.3.0 branch is not solidity 0.6 compliant .addFile('Untitled5.sol', sources[4]['Untitled5.sol']) @@ -46,7 +46,7 @@ module.exports = { .verifyContracts(['test8', 'ERC20', 'SafeMath'], { wait: 10000 }) }, - 'Test Github Import - no branch specified #group2': function (browser: NightwatchBrowser) { + 'Test GitHub Import - no branch specified #group2': function (browser: NightwatchBrowser) { browser .setSolidityCompilerVersion('soljson-v0.8.0+commit.c7dfd78e.js') // open-zeppelin moved to pragma ^0.8.0 (master branch) .clickLaunchIcon('filePanel') @@ -56,7 +56,7 @@ module.exports = { .verifyContracts(['test10', 'ERC20'], { wait: 10000 }) }, - 'Test Github Import - raw URL #group4': function (browser: NightwatchBrowser) { + 'Test GitHub Import - raw URL #group4': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('filePanel') .click('li[data-id="treeViewLitreeViewItemREADME.txt"') @@ -65,7 +65,7 @@ module.exports = { .verifyContracts(['test11', 'ERC20'], { wait: 10000 }) }, - 'Test switch to a github import from a solidity warning #group3': function (browser: NightwatchBrowser) { + 'Test switch to a GitHub import from a solidity warning #group3': function (browser: NightwatchBrowser) { browser .setSolidityCompilerVersion('soljson-v0.7.4+commit.3f05b770.js') .clickLaunchIcon('filePanel') diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index fb828248fe..a824c7871f 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -291,7 +291,7 @@ const deployWithEthersJs = ` // 'web3Provider' is a remix global variable object const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner() - let factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer); + let factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) let contract = await factory.deploy(...constructorArgs); @@ -320,7 +320,7 @@ describe("Storage with lib", function () { // Make sure contract is compiled and artifacts are generated const metadata = JSON.parse(await remix.call('fileManager', 'getFile', 'contracts/artifacts/Storage.json')) const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner() - let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer); + let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) let storage = await Storage.deploy(); console.log('storage contract Address: ' + storage.address); await storage.deployed() @@ -330,7 +330,7 @@ describe("Storage with lib", function () { it("test updating and retrieving updated value", async function () { const metadata = JSON.parse(await remix.call('fileManager', 'getFile', 'contracts/artifacts/Storage.json')) const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner() - let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer); + let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) let storage = await Storage.deploy(); await storage.deployed() const setValue = await storage.store(56); @@ -341,7 +341,7 @@ describe("Storage with lib", function () { it("fail test updating and retrieving updated value", async function () { const metadata = JSON.parse(await remix.call('fileManager', 'getFile', 'contracts/artifacts/Storage.json')) const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner() - let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer); + let Storage = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) let storage = await Storage.deploy(); await storage.deployed() const setValue = await storage.store(56); diff --git a/apps/remix-ide-e2e/src/tests/url.test.ts b/apps/remix-ide-e2e/src/tests/url.test.ts index e6233ae2e7..a201b4ea36 100644 --- a/apps/remix-ide-e2e/src/tests/url.test.ts +++ b/apps/remix-ide-e2e/src/tests/url.test.ts @@ -81,6 +81,7 @@ module.exports = { .refresh() .pause(5000) .clickLaunchIcon('solidity') + .click('*[data-id="scConfigExpander"]') .assert.containsText('#versionSelector option[data-id="selected"]', '0.7.4+commit.3f05b770') .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'istanbul') .assert.containsText('#compilierLanguageSelector option[data-id="selected"]', 'Yul') @@ -96,6 +97,7 @@ module.exports = { .pause(5000) .clickLaunchIcon('solidity') .pause(5000) + .click('*[data-id="scConfigExpander"]') .assert.containsText('#versionSelector option[data-id="selected"]', 'custom') // default values .assert.containsText('#evmVersionSelector option[data-id="selected"]', 'default') diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index 3fff396f77..7e7cfbd55e 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -50,11 +50,42 @@ module.exports = { .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/3_Ballot.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') - .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3.ts"]') - .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(2000) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, accountIndex?: number): Promise => {`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]') + .click('*[data-id="treeViewLitreeViewItemtests/storage.test.js"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`const { expect } = require("chai");`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/Ballot_test.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemREADME.txt"]') }, @@ -70,13 +101,12 @@ module.exports = { .click('select[id="wstemplate"] option[value=blank]') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(1000) + .pause(100) .assert.elementPresent('*[data-id="treeViewUltreeViewMenu"]') .execute(function () { const fileList = document.querySelector('*[data-id="treeViewUltreeViewMenu"]') return fileList.getElementsByTagName('li').length; }, [], function(result){ - // check there are no files in FE browser.assert.equal(result.value, 0, 'Incorrect number of files'); }); }, @@ -92,18 +122,91 @@ module.exports = { .click('select[id="wstemplate"] option[value=ozerc20]') .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) - .pause(1000) + .pause(100) .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC20.sol"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') - .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3.ts"]') - .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, accountIndex?: number): Promise => {`) !== -1, + 'Incorrect content') + }) .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC20_test.sol"]') }, + 'Should create ERC721 workspace with files': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="workspaceCreate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > span') + // eslint-disable-next-line dot-notation + .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' }) + .click('select[id="wstemplate"]') + .click('select[id="wstemplate"] option[value=ozerc721]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .pause(100) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemcontracts/SampleERC721.sol"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + // check js and ts files are not transformed + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_web3.ts"]') + + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './web3-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/deploy_with_ethers.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`import { deploy } from './ethers-lib'`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/web3-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, from?: string, gas?: number): Promise => {`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .click('*[data-id="treeViewLitreeViewItemscripts/ethers-lib.ts"]') + .pause(100) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`export const deploy = async (contractName: string, args: Array, accountIndex?: number): Promise => {`) !== -1, + 'Incorrect content') + }) + .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests"]') + .assert.elementPresent('*[data-id="treeViewLitreeViewItemtests/SampleERC721_test.sol"]') + }, + // WORKSPACE TEMPLATES E2E END 'Should create two workspace and switch to the first one': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide-e2e/src/types/index.d.ts b/apps/remix-ide-e2e/src/types/index.d.ts index e8698d4407..7fbcb174d5 100644 --- a/apps/remix-ide-e2e/src/types/index.d.ts +++ b/apps/remix-ide-e2e/src/types/index.d.ts @@ -11,7 +11,7 @@ declare module 'nightwatch' { 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 }): 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, diff --git a/apps/remix-ide/.babelrc b/apps/remix-ide/.babelrc index e60d3036a3..58a023dfd5 100644 --- a/apps/remix-ide/.babelrc +++ b/apps/remix-ide/.babelrc @@ -1,4 +1,4 @@ { "presets": ["@babel/preset-env", "@babel/preset-react"], - "plugins": ["@babel/plugin-proposal-class-properties"] + "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"] } diff --git a/apps/remix-ide/.npmignore b/apps/remix-ide/.npmignore index 00282f7e0c..6ad8903c48 100644 --- a/apps/remix-ide/.npmignore +++ b/apps/remix-ide/.npmignore @@ -3,5 +3,6 @@ node_modules reports npm-debug.log* package-lock.json +yarn.lock remix .DS_Store diff --git a/apps/remix-ide/.travis.yml b/apps/remix-ide/.travis.yml index ef1c5da85e..c8790fa6b8 100644 --- a/apps/remix-ide/.travis.yml +++ b/apps/remix-ide/.travis.yml @@ -9,8 +9,8 @@ branches: - master - remix_live script: - - npm install - - npm run lint && npm run test && npm run make-mock-compiler && npm run build + - yarn install + - yarn run lint && yarn run test && yarn run make-mock-compiler && yarn run build - wget http://selenium-release.storage.googleapis.com/3.5/selenium-server-standalone-3.5.3.jar - wget http://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip - unzip chromedriver_linux64.zip diff --git a/apps/remix-ide/README.md b/apps/remix-ide/README.md index 77535515cb..8f84d6771f 100644 --- a/apps/remix-ide/README.md +++ b/apps/remix-ide/README.md @@ -26,7 +26,7 @@ Install **npm** and **node.js** (see https://docs.npmjs.com/getting-started/inst Remix-ide has been published as an npm module: ```bash -npm install remix-ide -g +yarn global add remix-ide remix-ide ``` Or if you want to clone the github repository (`wget` need to be installed first) : @@ -36,12 +36,12 @@ git clone https://github.com/ethereum/remix-ide.git git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it. cd remix # only if you plan to link remix and remix-ide repositories and develop on it. -npm install # only if you plan to link remix and remix-ide repositories and develop on it. -npm run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it. +yarn install # only if you plan to link remix and remix-ide repositories and develop on it. +yarn run bootstrap # only if you plan to link remix and remix-ide repositories and develop on it. cd remix-ide -npm install -npm run setupremix # only if you plan to link remix and remix-ide repositories and develop on it. +yarn install +yarn run setupremix # only if you plan to link remix and remix-ide repositories and develop on it. npm start ``` @@ -112,40 +112,40 @@ nvm --version Register new unit test files in `test/index.js`. The tests are written using [tape](https://www.npmjs.com/package/tape). -Run the unit tests via: `npm test` +Run the unit tests via: `yarn test` -For local headless browser tests run `npm run test-browser` -(requires Selenium to be installed - can be done with `npm run selenium-install`) +For local headless browser tests run `yarn run test-browser` +(requires Selenium to be installed - can be done with `yarn run selenium-install`) -Running unit tests via `npm test` requires at least node v7.0.0 +Running unit tests via `yarn test` requires at least node v7.0.0 ## Browser Testing To run the Selenium tests via Nightwatch: - - Build Remix IDE and serve it: `npm run build && npm run serve` # starts web server at localhost:8080 - - Make sure Selenium is installed `npm run selenium-install` # don't need to repeat - - Run a selenium server `npm run selenium` - - Run all the tests `npm run nightwatch_local_firefox` or `npm run nightwatch_local_chrome` + - Build Remix IDE and serve it: `yarn run build && yarn run serve` # starts web server at localhost:8080 + - Make sure Selenium is installed `yarn run selenium-install` # don't need to repeat + - Run a selenium server `yarn run selenium` + - Run all the tests `yarn run nightwatch_local_firefox` or `yarn run nightwatch_local_chrome` - Or run a specific test case: - - npm run nightwatch_local_ballot + - yarn run nightwatch_local_ballot - - npm run nightwatch_local_libraryDeployment + - yarn run nightwatch_local_libraryDeployment - - npm run nightwatch_local_solidityImport + - yarn run nightwatch_local_solidityImport - - npm run nightwatch_local_recorder + - yarn run nightwatch_local_recorder - - npm run nightwatch_local_transactionExecution + - yarn run nightwatch_local_transactionExecution - - npm run nightwatch_local_staticAnalysis + - yarn run nightwatch_local_staticAnalysis - - npm run nightwatch_local_signingMessage + - yarn run nightwatch_local_signingMessage - - npm run nightwatch_local_console + - yarn run nightwatch_local_console - - npm run nightwatch_local_remixd # remixd needs to be run + - yarn run nightwatch_local_remixd # remixd needs to be run **NOTE:** - **the `ballot` tests suite** requires to run `ganache-cli` locally. diff --git a/apps/remix-ide/ci/browser_test.sh b/apps/remix-ide/ci/browser_test.sh index f9385198b5..7a9b536f0c 100755 --- a/apps/remix-ide/ci/browser_test.sh +++ b/apps/remix-ide/ci/browser_test.sh @@ -6,14 +6,14 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & -npm run remixd & +yarn run remixd & sleep 5 -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | sort | circleci tests split ) for TESTFILE in $TESTFILES; do diff --git a/apps/remix-ide/ci/browser_tests.sh b/apps/remix-ide/ci/browser_tests.sh index 4a093f6b5d..3070563e52 100755 --- a/apps/remix-ide/ci/browser_tests.sh +++ b/apps/remix-ide/ci/browser_tests.sh @@ -15,13 +15,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve & +yarn run ganache-cli & +yarn run serve & setupRemixd sleep 5 -npm run nightwatch_parallel || TEST_EXITCODE=1 +yarn run nightwatch_parallel || TEST_EXITCODE=1 TESTFILES=$(circleci tests glob "./apps/remix-ide/test-browser/tests/**/*.test.js" | circleci tests split ) for TESTFILE in $TESTFILES; do ./node_modules/.bin/nightwatch --config ./apps/remix-ide/nightwatch.js --env chrome $TESTFILE || TEST_EXITCODE=1 diff --git a/apps/remix-ide/ci/browser_tests_plugin_api.sh b/apps/remix-ide/ci/browser_tests_plugin_api.sh index ab94f74a31..a955297d12 100755 --- a/apps/remix-ide/ci/browser_tests_plugin_api.sh +++ b/apps/remix-ide/ci/browser_tests_plugin_api.sh @@ -6,13 +6,13 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & npx nx serve remix-ide-e2e-src-local-plugin & sleep 5 -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split ) for TESTFILE in $TESTFILES; do diff --git a/apps/remix-ide/ci/flaky.sh b/apps/remix-ide/ci/flaky.sh index 8a2dac3e73..41e6c69528 100755 --- a/apps/remix-ide/ci/flaky.sh +++ b/apps/remix-ide/ci/flaky.sh @@ -2,7 +2,7 @@ set -e -npm run build:e2e +yarn run build:e2e TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort ) # count test files @@ -18,10 +18,10 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}} echo "$BUILD_ID" TEST_EXITCODE=0 -npm run ganache-cli & -npm run serve:production & +yarn run ganache-cli & +yarn run serve:production & echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' & -npm run remixd & +yarn run remixd & npx nx serve remix-ide-e2e-src-local-plugin & sleep 5 diff --git a/apps/remix-ide/ci/lint.sh b/apps/remix-ide/ci/lint.sh index f0d0345391..fcedab9655 100755 --- a/apps/remix-ide/ci/lint.sh +++ b/apps/remix-ide/ci/lint.sh @@ -13,7 +13,7 @@ KEYS=$(jq -r '.projects | keys' workspace.json | tr -d '[],"') then echo ${row} fi -done) | circleci tests split | { while read i;do npm run lint $i; done } +done) | circleci tests split | { while read i;do yarn run lint $i; done } echo "$TEST_EXITCODE" if [ "$TEST_EXITCODE" -eq 1 ] diff --git a/apps/remix-ide/ci/publishIpfs b/apps/remix-ide/ci/publishIpfs index 0f8fd96ca0..15d2dc9b66 100755 --- a/apps/remix-ide/ci/publishIpfs +++ b/apps/remix-ide/ci/publishIpfs @@ -5,8 +5,14 @@ const { globSource } = IpfsHttpClient const folder = process.cwd() + '/dist/apps/remix-ide'; (async () => { - const host = 'ipfs.remixproject.org' - const ipfs = IpfsHttpClient({ host, port: 443, protocol: 'https' }) + const host = 'ipfs.infura.io' + const projectId = process.argv[2] + const projectSecret = process.argv[3] + const auth = 'Basic ' + Buffer.from(projectId + ':' + projectSecret).toString('base64') + + const ipfs = IpfsHttpClient({ port: 5001, host, protocol: 'https', headers: { + authorization: auth + } }) try { let result = await ipfs.add(globSource(folder, { recursive: true}), { pin: false }) const hash = result.cid.toString() diff --git a/apps/remix-ide/docs/file_explorer.md b/apps/remix-ide/docs/file_explorer.md index 545d357d22..008b044307 100644 --- a/apps/remix-ide/docs/file_explorer.md +++ b/apps/remix-ide/docs/file_explorer.md @@ -33,9 +33,9 @@ Publish to Gist The icon marked **C.** above. Publishes all files from the browser folder to a gist. Only file in the root of **browser** will be published. Files in subfolders will not be publish to the Gist. Gist API has changed in 2018 and **requires** users to be authenticated to be able to publish a gist. -Click [this link](https://github.com/settings/tokens) to Github tokens setup and select Generate new token. Then check the **Create gists** checkbox and generate a new token. +Click [this link](https://github.com/settings/tokens) to GitHub tokens setup and select Generate new token. Then check the **Create gists** checkbox and generate a new token. -Take the token and paste it in Remix's **Settings** module in the **Github Access Token** section. And then click Save. Now you should be able to use the feature. +Take the token and paste it in Remix's **Settings** module in the **GitHub Access Token** section. And then click Save. Now you should be able to use the feature. Create a folder --------------- diff --git a/apps/remix-ide/docs/locations.md b/apps/remix-ide/docs/locations.md index e193139619..ae806e3c0e 100644 --- a/apps/remix-ide/docs/locations.md +++ b/apps/remix-ide/docs/locations.md @@ -5,6 +5,10 @@ So if you've found the documentation to Remix but don't know where to find Remix - An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release. - An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version. -- npm `remix-ide` package `npm install remix-ide -g`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`. +- npm `remix-ide` package `yarn global add remix-ide`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`. see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`. -- Github release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`. + +- GitHub release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`. + +- GitHub release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `yarn run build`. + diff --git a/apps/remix-ide/docs/remix_tutorials_github.md b/apps/remix-ide/docs/remix_tutorials_github.md index 47f708e45a..1bb31de1e1 100644 --- a/apps/remix-ide/docs/remix_tutorials_github.md +++ b/apps/remix-ide/docs/remix_tutorials_github.md @@ -1,4 +1,4 @@ -Remix Github Tutorials +Remix GitHub Tutorials ======================= There are a series of tutorials in our github repo [remix-workshops](https://github.com/ethereum/remix-workshops). diff --git a/apps/remix-ide/docs/remixd.md b/apps/remix-ide/docs/remixd.md index 45e2d2062c..3fc7b1bdb3 100644 --- a/apps/remix-ide/docs/remixd.md +++ b/apps/remix-ide/docs/remixd.md @@ -8,10 +8,7 @@ The code of `remixd` is [here](https://github.com/ethereum/remixd) . `remixd` can be globally installed using the following command: -`npm install -g remixd` - -Or just install it in the directory of your choice by removing the -g flag: -`npm install remixd` +`yarn global add @remix-project/remixd` Then from the terminal, the command `remixd -s --remix-ide ` will start `remixd` and will share the given folder with remix-ide. diff --git a/apps/remix-ide/release-process.md b/apps/remix-ide/release-process.md index 45842919b0..511c8ad74e 100644 --- a/apps/remix-ide/release-process.md +++ b/apps/remix-ide/release-process.md @@ -9,7 +9,6 @@ This document includes: - git checkout origin/master - git checkout -b bumpVersion - update package.json version - - remove package-lock.json version and generate a new one with `npm install` - merge PR - git fetch origin master - git checkout origin/master @@ -18,9 +17,9 @@ This document includes: - github-changes -o ethereum -r remix-ide -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version - publish a release in github using the changelog - rm -rf node_modules - - npm install + - yarn install - remove all soljson.js files in root folder - - npm run build + - yarn run build - npm publish - after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release. @@ -29,7 +28,6 @@ This document includes: - git checkout origin/master - git checkout -b bumpVersion - update package.json version to the new version "vx.x.x-beta.1" - - remove package-lock/json version and generate a new one with `npm install` - merge PR - git fetch origin master - git checkout origin/master diff --git a/apps/remix-ide/remix-screenshot-400h.png b/apps/remix-ide/remix-screenshot-400h.png new file mode 100644 index 0000000000..74ac1e57dc Binary files /dev/null and b/apps/remix-ide/remix-screenshot-400h.png differ diff --git a/apps/remix-ide/remix_screenshot.png b/apps/remix-ide/remix_screenshot.png deleted file mode 100644 index 76df964d6d..0000000000 Binary files a/apps/remix-ide/remix_screenshot.png and /dev/null differ diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 30e653731d..4eb9423d38 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -27,6 +27,7 @@ import { NotificationPlugin } from './app/plugins/notification' import { Blockchain } from './blockchain/blockchain.js' import { HardhatProvider } from './app/tabs/hardhat-provider' import { GanacheProvider } from './app/tabs/ganache-provider' +import { FoundryProvider } from './app/tabs/foundry-provider' const isElectron = require('is-electron') @@ -177,6 +178,7 @@ class AppComponent { const web3Provider = new Web3ProviderModule(blockchain) const hardhatProvider = new HardhatProvider(blockchain) const ganacheProvider = new GanacheProvider(blockchain) + const foundryProvider = new FoundryProvider(blockchain) // ----------------- convert offset to line/column service ----------- const offsetToLineColumnConverter = new OffsetToLineColumnConverter() Registry.getInstance().put({ @@ -233,6 +235,7 @@ class AppComponent { storagePlugin, hardhatProvider, ganacheProvider, + foundryProvider, this.walkthroughService, search ]) diff --git a/apps/remix-ide/src/app/editor/editor.js b/apps/remix-ide/src/app/editor/editor.js index 9bf7e3fec6..97dc63f988 100644 --- a/apps/remix-ide/src/app/editor/editor.js +++ b/apps/remix-ide/src/app/editor/editor.js @@ -1,5 +1,6 @@ 'use strict' import React from 'react' // eslint-disable-line +import { resolve } from 'path' import { EditorUI } from '@remix-ui/editor' // eslint-disable-line import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' @@ -140,16 +141,62 @@ class Editor extends Plugin { this.on('sidePanel', 'pluginDisabled', (name) => { this.clearAllDecorationsFor(name) }) - this.on('fileManager', 'fileClosed', (name) => { - if (name === this.currentFile) { - this.currentFile = null - this.renderComponent() - } - }) this.on('theme', 'themeLoaded', (theme) => { this.currentThemeType = theme.quality this.renderComponent() }) + this.on('fileManager', 'currentFileChanged', async (name) => { + if (name.endsWith('.ts')) { + // extract the import, resolve their content + // and add the imported files to Monaco through the `addModel` + // so Monaco can provide auto completion + let content = await this.call('fileManager', 'readFile', name) + const paths = name.split('/') + paths.pop() + const fromPath = paths.join('/') // get current execution context path + for (const match of content.matchAll(/import\s+.*\s+from\s+(?:"(.*?)"|'(.*?)')/g)) { + let path = match[2] + if (path.startsWith('./') || path.startsWith('../')) path = resolve(fromPath, path) + if (path.startsWith('/')) path = path.substring(1) + if (!path.endsWith('.ts')) path = path + '.ts' + if (await this.call('fileManager', 'exists', path)) { + content = await this.call('fileManager', 'readFile', path) + this.emit('addModel', content, 'typescript', path, false) + } + } + } + }) + + this.on('fileManager', 'noFileSelected', async () => { + this.currentFile = null + this.renderComponent() + }) + this.on('fileManager', 'currentFileChanged', async (name) => { + if (name.endsWith('.ts')) { + // extract the import, resolve their content + // and add the imported files to Monaco through the `addModel` + // so Monaco can provide auto completion + let content = await this.call('fileManager', 'readFile', name) + const paths = name.split('/') + paths.pop() + const fromPath = paths.join('/') // get current execution context path + for (const match of content.matchAll(/import\s+.*\s+from\s+(?:"(.*?)"|'(.*?)')/g)) { + let path = match[2] + if (path.startsWith('./') || path.startsWith('../')) path = resolve(fromPath, path) + if (path.startsWith('/')) path = path.substring(1) + if (!path.endsWith('.ts')) path = path + '.ts' + if (await this.call('fileManager', 'exists', path)) { + content = await this.call('fileManager', 'readFile', path) + this.emit('addModel', content, 'typescript', path, false) + } + } + } + }) + + this.on('fileManager', 'noFileSelected', async () => { + this.currentFile = null + this.renderComponent() + }) try { this.currentThemeType = (await this.call('theme', 'currentTheme')).quality } catch (e) { diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index aa02851c3e..e7ae4763df 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -4,7 +4,7 @@ import * as packageJson from '../../../../../package.json' import Registry from '../state/registry' import { EventEmitter } from 'events' import { RemixAppManager } from '../../../../../libs/remix-ui/plugin-manager/src/types' -import { fileChangedToastMsg, storageFullMessage } from '@remix-ui/helper' +import { fileChangedToastMsg, recursivePasteToastMsg, storageFullMessage } from '@remix-ui/helper' import helper from '../../lib/helper.js' /* @@ -275,7 +275,7 @@ class FileManager extends Plugin { const provider = this.fileProviderOf(src) if (provider.isSubDirectory(src, dest)) { - this.call('notification', 'toast', 'File(s) to paste is an ancestor of the destination folder') + this.call('notification', 'toast', recursivePasteToastMsg()) } else { await this.inDepthCopy(src, dest) } diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 61e751ee62..1a8639149f 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -135,16 +135,12 @@ class FileProvider { if (!await window.remixFileSystem.exists(currentCheck)) { try { await window.remixFileSystem.mkdir(currentCheck) + this.event.emit('folderAdded', this._normalizePath(currentCheck)) } catch (error) { console.log(error) } } } - currentCheck = '' - for (const value of paths) { - currentCheck = currentCheck + '/' + value - this.event.emit('folderAdded', this._normalizePath(currentCheck)) - } if (cb) cb() } diff --git a/apps/remix-ide/src/app/panels/layout.ts b/apps/remix-ide/src/app/panels/layout.ts index 33704eef35..37a0ee6fe4 100644 --- a/apps/remix-ide/src/app/panels/layout.ts +++ b/apps/remix-ide/src/app/panels/layout.ts @@ -57,9 +57,6 @@ export class Layout extends Plugin { this.panels.main.active = false this.event.emit('change', null) }) - this.on('tabs', 'tabCountChanged', async count => { - if (!count) await this.call('manager', 'activatePlugin', 'home') - }) this.on('manager', 'activate', (profile: Profile) => { switch (profile.name) { case 'filePanel': diff --git a/apps/remix-ide/src/app/panels/tab-proxy.js b/apps/remix-ide/src/app/panels/tab-proxy.js index ec8026c517..82758c169f 100644 --- a/apps/remix-ide/src/app/panels/tab-proxy.js +++ b/apps/remix-ide/src/app/panels/tab-proxy.js @@ -24,7 +24,7 @@ export class TabProxy extends Plugin { this.themeQuality = 'dark' } - onActivation () { + async onActivation () { this.on('theme', 'themeChanged', (theme) => { this.themeQuality = theme.quality // update invert for all icons @@ -169,6 +169,13 @@ export class TabProxy extends Plugin { this.on('manager', 'pluginDeactivated', (profile) => { this.removeTab(profile.name) }) + + try { + this.themeQuality = (await this.call('theme', 'currentTheme') ).quality + } catch (e) { + console.log('theme plugin has an issue: ', e) + } + this.renderComponent() } focus (name) { @@ -208,6 +215,7 @@ export class TabProxy extends Plugin { } renameTab (oldName, newName) { + // The new tab is being added by FileManager this.removeTab(oldName) } @@ -275,7 +283,12 @@ export class TabProxy extends Plugin { delete this._handlers[name] let previous = currentFileTab this.loadedTabs = this.loadedTabs.filter((tab, index) => { - if (!previous && tab.name === name) previous = this.loadedTabs[index - 1] + if (!previous && tab.name === name) { + if(index - 1 >= 0 && this.loadedTabs[index - 1]) + previous = this.loadedTabs[index - 1] + else if (index + 1 && this.loadedTabs[index + 1]) + previous = this.loadedTabs[index + 1] + } return tab.name !== name }) this.renderComponent() @@ -292,7 +305,15 @@ export class TabProxy extends Plugin { } updateComponent(state) { - return + return } renderComponent () { diff --git a/apps/remix-ide/src/app/plugins/config.ts b/apps/remix-ide/src/app/plugins/config.ts index 3102d555df..b65f1ddfa7 100644 --- a/apps/remix-ide/src/app/plugins/config.ts +++ b/apps/remix-ide/src/app/plugins/config.ts @@ -18,7 +18,7 @@ export class ConfigPlugin extends Plugin { const queryParams = new QueryParams() const params = queryParams.get() const config = Registry.getInstance().get('config').api - let param = params[name] || config.get(name) || config.get('settings/' + name) + const param = params[name] || config.get(name) || config.get('settings/' + name) if (param === 'true') return true if (param === 'false') return false return param diff --git a/apps/remix-ide/src/app/plugins/remixd-handle.tsx b/apps/remix-ide/src/app/plugins/remixd-handle.tsx index 5ad5d25e60..da3b2506b9 100644 --- a/apps/remix-ide/src/app/plugins/remixd-handle.tsx +++ b/apps/remix-ide/src/app/plugins/remixd-handle.tsx @@ -134,22 +134,29 @@ export class RemixdHandle extends WebsocketPlugin { } function remixdDialog () { - const commandText = 'remixd -s -u ' + const commandText = 'remixd' + const fullCommandText = 'remixd -s -u ' return (<>
- Access your local file system from Remix IDE using Remixd NPM package.

- Remixd needs to be running in the background to load the files in localhost workspace. For more info, please check the Remixd tutorial. + Access your local file system from Remix IDE using Remixd NPM package.
- If you are just looking for the remixd command, here it is: -



{commandText} - + Remixd documentation.
- When connected, a session will be started between {window.location.origin} and your local file system at ws://127.0.0.1:65520. - The shared folder will be in the "File Explorers" workspace named "localhost". -
Read more about other Remixd ports usage + The remixd command is: +
{commandText} +
+
+ The remixd command without options uses the terminal's current directory as the shared directory and the shared Remix domain can only be https://remix.ethereum.org, https://remix-alpha.ethereum.org, or https://remix-beta.ethereum.org +
+
+ Example command with flags:
+ {fullCommandText} +
+
+ For info about ports, see Remixd ports usage
This feature is still in Alpha. We recommend to keep a backup of the shared folder. diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 8e3d17e366..23a53846f7 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -56,6 +56,10 @@ class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerA this.renderComponent() } + onFileRemoved () { + this.renderComponent() + } + onNoFileSelected () { this.renderComponent() } diff --git a/apps/remix-ide/src/app/tabs/foundry-provider.tsx b/apps/remix-ide/src/app/tabs/foundry-provider.tsx new file mode 100644 index 0000000000..47e899865a --- /dev/null +++ b/apps/remix-ide/src/app/tabs/foundry-provider.tsx @@ -0,0 +1,33 @@ +import * as packageJson from '../../../../../package.json' +import { Plugin } from '@remixproject/engine' +import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' +import React from 'react' // eslint-disable-line +import { Blockchain } from '../../blockchain/blockchain' +import { ethers } from 'ethers' +import { AbstractProvider } from './abstract-provider' + +const profile = { + name: 'foundry-provider', + displayName: 'Foundry Provider', + kind: 'provider', + description: 'Anvil', + methods: ['sendAsync'], + version: packageJson.version +} + +export class FoundryProvider extends AbstractProvider { + constructor (blockchain) { + super(profile, blockchain, 'http://127.0.0.1:8545') + } + + body (): JSX.Element { + return ( +
Note: To run Anvil on your system, run +
curl -L https://foundry.paradigm.xyz | bash
+
anvil
+ For more info, visit: Foundry Documentation +
Anvil JSON-RPC Endpoint:
+
+ ) + } +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/tabs/ganache-provider.tsx b/apps/remix-ide/src/app/tabs/ganache-provider.tsx index b73cb18786..002e31a3a2 100644 --- a/apps/remix-ide/src/app/tabs/ganache-provider.tsx +++ b/apps/remix-ide/src/app/tabs/ganache-provider.tsx @@ -23,7 +23,7 @@ export class GanacheProvider extends AbstractProvider { body (): JSX.Element { return (
Note: To run Ganache on your system, run -
npm install -g ganache
+
yarn global add ganache
ganache
For more info, visit: Ganache Documentation
Ganache JSON-RPC Endpoint:
diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 0f59ddd962..020c2a34df 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -127,6 +127,20 @@ export class RunTab extends ViewPlugin { } }) + await this.call('blockchain', 'addProvider', { + name: 'Foundry Provider', + provider: { + async sendAsync (payload, callback) { + try { + const result = await udapp.call('foundry-provider', 'sendAsync', payload) + callback(null, result) + } catch (e) { + callback(e) + } + } + } + }) + await this.call('blockchain', 'addProvider', { name: 'Wallet Connect', provider: { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 96d79aba39..bf8c5dccd3 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -7,7 +7,7 @@ const _paq = window._paq = window._paq || [] const requiredModules = [ // services + layout views + system views 'manager', 'config', 'compilerArtefacts', 'compilerMetadata', 'contextualListener', 'editor', 'offsetToLineColumnConverter', 'network', 'theme', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', - 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity-logic', 'gistHandler', 'layout', + 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout', 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', 'hardhat-provider', 'compileAndRun', 'search'] const dependentModules = ['git', 'hardhat', 'truffle', 'slither'] // module which shouldn't be manually activated (e.g git is activated by remixd) @@ -19,7 +19,7 @@ const sensitiveCalls = { } export function isNative(name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'hardhat-provider', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity', 'solidity-logic', 'solidityStaticAnalysis', 'solidityUnitTesting', 'layout', 'notification', 'hardhat-provider', 'ganache-provider'] return nativePlugins.includes(name) || requiredModules.includes(name) } diff --git a/apps/remix-ide/team-best-practices.md b/apps/remix-ide/team-best-practices.md index 3832c3be95..5a246096e7 100644 --- a/apps/remix-ide/team-best-practices.md +++ b/apps/remix-ide/team-best-practices.md @@ -54,7 +54,7 @@ Related links: - How the backend (if any) works / will work (could be a smart contract). - How the frontend works / will work. - What is the general vision of the UX design for this particular story. - Later progress and discussion is updated directly on the issue or pull request (Github). + Later progress and discussion is updated directly on the issue or pull request (GitHub). --- @@ -72,7 +72,7 @@ Before starting coding, we should ensure all devs / contributors are aware of: # Story / Bug fix -- Prioritised list of PRs / issues are tracked in a Github Project, Remix IDE issues are managed by a prioritized backlog. +- Prioritised list of PRs / issues are tracked in a GitHub Project, Remix IDE issues are managed by a prioritized backlog. - Every story can be executed by a single developer or a group of 2 or more developers (depending on the size and complexity) - Each dev should take the part he/she feels the most confortable with. - Later progress and discussion is updated directly on the issue or pull request (github). diff --git a/apps/solidity-compiler/src/app/compiler-api.ts b/apps/solidity-compiler/src/app/compiler-api.ts index ade46d3223..3065af630a 100644 --- a/apps/solidity-compiler/src/app/compiler-api.ts +++ b/apps/solidity-compiler/src/app/compiler-api.ts @@ -18,7 +18,8 @@ export const CompilerApiMixin = (Base) => class extends Base { onCurrentFileChanged: (fileName: string) => void // onResetResults: () => void - onSetWorkspace: (workspace: any) => void + onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void + onFileRemoved: (path: string) => void onNoFileSelected: () => void onCompilationFinished: (compilationDetails: { contractMap: { file: string } | Record, contractsDetails: Record }) => void onSessionSwitched: () => void @@ -237,12 +238,16 @@ export const CompilerApiMixin = (Base) => class extends Base { this.on('filePanel', 'setWorkspace', (workspace) => { this.resetResults() - if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost) + if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost, workspace.name) + }) + + this.on('fileManager', 'fileRemoved', (path) => { + if (this.onFileRemoved) this.onFileRemoved(path) }) this.on('remixd', 'rootFolderChanged', () => { this.resetResults() - if (this.onSetWorkspace) this.onSetWorkspace(true) + if (this.onSetWorkspace) this.onSetWorkspace(true, 'localhost') }) this.on('editor', 'sessionSwitched', () => { @@ -282,36 +287,34 @@ export const CompilerApiMixin = (Base) => class extends Base { type: 'warning' }) } else this.statusChanged({ key: 'succeed', title: 'compilation successful', type: 'success' }) - // Store the contracts - this.compilationDetails.contractsDetails = {} - this.compiler.visitContracts((contract) => { - this.compilationDetails.contractsDetails[contract.name] = parseContracts( - contract.name, - contract.object, - this.compiler.getSource(contract.file) - ) - }) } else { const count = (data.errors ? data.errors.filter(error => error.severity === 'error').length : 0 + (data.error ? 1 : 0)) this.statusChanged({ key: count, title: `compilation failed with ${count} error${count > 1 ? 's' : ''}`, type: 'error' }) } - // Update contract Selection - this.compilationDetails.contractMap = {} - if (success) this.compiler.visitContracts((contract) => { this.compilationDetails.contractMap[contract.name] = contract }) - this.compilationDetails.target = source.target + // Store the contracts and Update contract Selection + if (success) { + this.compilationDetails = await this.visitsContractApi(source, data) + } else { + this.compilationDetails = { + contractMap: {}, + contractsDetails: {}, + target: source.target + } + } if (this.onCompilationFinished) this.onCompilationFinished(this.compilationDetails) // set annotations if (data.errors) { for (const error of data.errors) { let pos = helper.getPositionDetails(error.formattedMessage) - if (pos.errFile) { + const file = pos.errFile + if (file) { pos = { row: pos.errLine, column: pos.errCol, text: error.formattedMessage, type: error.severity } - await this.call('editor', 'addAnnotation', pos, pos.errFile) + await this.call('editor', 'addAnnotation', pos, file) } } } @@ -332,11 +335,40 @@ export const CompilerApiMixin = (Base) => class extends Base { // ctrl+s or command+s if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.keyCode === 83 && this.currentFile !== '') { e.preventDefault() - if(await this.getAppParameter('hardhat-compilation')) this.compileTabLogic.runCompiler('hardhat') - else if(await this.getAppParameter('truffle-compilation')) this.compileTabLogic.runCompiler('truffle') - else this.compileTabLogic.runCompiler(undefined) + if (this.currentFile && (this.currentFile.endsWith('.sol') || this.currentFile.endsWith('.yul'))) { + if(await this.getAppParameter('hardhat-compilation')) this.compileTabLogic.runCompiler('hardhat') + else if(await this.getAppParameter('truffle-compilation')) this.compileTabLogic.runCompiler('truffle') + else this.compileTabLogic.runCompiler(undefined) + } } } window.document.addEventListener('keydown', this.data.eventHandlers.onKeyDown) } + + async visitsContractApi (source, data): Promise<{ contractMap: { file: string } | Record, contractsDetails: Record, target?: string }> { + return new Promise((resolve) => { + if (!data.contracts || (data.contracts && Object.keys(data.contracts).length === 0)) { + return resolve({ + contractMap: {}, + contractsDetails: {}, + target: source.target + }) + } + const contractMap = {} + const contractsDetails = {} + this.compiler.visitContracts((contract) => { + contractMap[contract.name] = contract + contractsDetails[contract.name] = parseContracts( + contract.name, + contract.object, + this.compiler.getSource(contract.file) + ) + }) + return resolve({ + contractMap, + contractsDetails, + target: source.target + }) + }) + } } diff --git a/apps/solidity-compiler/src/app/compiler.ts b/apps/solidity-compiler/src/app/compiler.ts index a58ff585a2..df64855ab9 100644 --- a/apps/solidity-compiler/src/app/compiler.ts +++ b/apps/solidity-compiler/src/app/compiler.ts @@ -6,31 +6,14 @@ import { CompilerApiMixin } from './compiler-api' import { ICompilerApi } from '@remix-project/remix-lib-ts' import { CompileTabLogic } from '@remix-ui/solidity-compiler' -const profile = { - name: 'solidity', - displayName: 'Solidity compiler', - icon: 'assets/img/solidity.webp', - description: 'Compile solidity contracts', - kind: 'compiler', - permission: true, - location: 'sidePanel', - documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html', - version: '0.0.1', - methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState'] -} - -const defaultAppParameters = { - hideWarnings: false, - autoCompile: false, - includeNightlies: false -} - const defaultCompilerParameters = { runs: '200', optimize: false, version: 'soljson-v0.8.7+commit.e28d00a7', evmVersion: null, // compiler default - language: 'Solidity' + language: 'Solidity', + useFileConfiguration: false, + configFilePath: "compiler_config.json" } export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi { constructor () { @@ -48,7 +31,9 @@ export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements optimize: localStorage.getItem('optimize') === 'true', version: localStorage.getItem('version') || defaultCompilerParameters.version, evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters.evmVersion, // default - language: localStorage.getItem('language') || defaultCompilerParameters.language + language: localStorage.getItem('language') || defaultCompilerParameters.language, + useFileConfiguration: localStorage.getItem('useFileConfiguration') === 'true', + configFilePath: localStorage.getItem('configFilePath') || defaultCompilerParameters.configFilePath } return params } diff --git a/libs/remix-analyzer/README.md b/libs/remix-analyzer/README.md index d81b93b787..a2cc46d6bd 100644 --- a/libs/remix-analyzer/README.md +++ b/libs/remix-analyzer/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-analyzer` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-analyzer` +`yarn add @remix-project/remix-analyzer` ### How to use diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 903e5f3c15..22d8646744 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-analyzer", - "version": "0.5.22", + "version": "0.5.23", "description": "Tool to perform static analysis on Solidity smart contracts", "main": "src/index.js", "types": "src/index.d.ts", @@ -22,8 +22,8 @@ "@ethereumjs/block": "^3.5.1", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-astwalker": "^0.0.43", - "@remix-project/remix-lib": "^0.5.13", + "@remix-project/remix-astwalker": "^0.0.44", + "@remix-project/remix-lib": "^0.5.14", "async": "^2.6.2", "ethereumjs-util": "^7.0.10", "ethers": "^5.4.2", @@ -52,5 +52,5 @@ "typescript": "^3.7.5" }, "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-astwalker/README.md b/libs/remix-astwalker/README.md index cc6416b8b0..6b03957968 100644 --- a/libs/remix-astwalker/README.md +++ b/libs/remix-astwalker/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-astwalker` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-astwalker` +`yarn add @remix-project/remix-astwalker` ### How to use diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 6a76dcf6dc..60e7f14374 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-astwalker", - "version": "0.0.43", + "version": "0.0.44", "description": "Tool to walk through Solidity AST", "main": "src/index.js", "scripts": { @@ -37,7 +37,7 @@ "@ethereumjs/block": "^3.5.1", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-lib": "^0.5.13", + "@remix-project/remix-lib": "^0.5.14", "@types/tape": "^4.2.33", "async": "^2.6.2", "ethereumjs-util": "^7.0.10", @@ -54,5 +54,5 @@ "tap-spec": "^5.0.0" }, "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-debug/README.md b/libs/remix-debug/README.md index c8ea008043..e512499d36 100644 --- a/libs/remix-debug/README.md +++ b/libs/remix-debug/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-debug` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-debug` +`yarn add @remix-project/remix-debug` ### How to use diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index 8d26e36358..e70aba4523 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-debug", - "version": "0.5.13", + "version": "0.5.14", "description": "Tool to debug Ethereum transactions", "contributors": [ { @@ -22,9 +22,9 @@ "@ethereumjs/common": "^2.5.0", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-astwalker": "^0.0.43", - "@remix-project/remix-lib": "^0.5.13", - "@remix-project/remix-simulator": "^0.2.13", + "@remix-project/remix-astwalker": "^0.0.44", + "@remix-project/remix-lib": "^0.5.14", + "@remix-project/remix-simulator": "^0.2.14", "ansi-gray": "^0.1.1", "async": "^2.6.2", "color-support": "^1.1.3", @@ -68,5 +68,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-lib/README.md b/libs/remix-lib/README.md index 31075ad154..64a6706ef3 100644 --- a/libs/remix-lib/README.md +++ b/libs/remix-lib/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-lib` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-lib` +`yarn add @remix-project/remix-lib` ### How to use diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index 9decef15f7..1a26aee068 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-lib", - "version": "0.5.13", + "version": "0.5.14", "description": "Library to various Remix tools", "contributors": [ { @@ -54,5 +54,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-lib/src/types/ICompilerApi.ts b/libs/remix-lib/src/types/ICompilerApi.ts index 8e43892fa0..259aa2547a 100644 --- a/libs/remix-lib/src/types/ICompilerApi.ts +++ b/libs/remix-lib/src/types/ICompilerApi.ts @@ -24,7 +24,8 @@ export interface ICompilerApi { onCurrentFileChanged: (fileName: string) => void // onResetResults: () => void, - onSetWorkspace: (workspace: any) => void + onSetWorkspace: (isLocalhost: boolean, workspaceName: string) => void + onFileRemoved: (path: string) => void onNoFileSelected: () => void onCompilationFinished: (contractsDetails: any, contractMap: any) => void onSessionSwitched: () => void diff --git a/libs/remix-simulator/README.md b/libs/remix-simulator/README.md index ebd7b31aff..bf1b0c675a 100644 --- a/libs/remix-simulator/README.md +++ b/libs/remix-simulator/README.md @@ -10,7 +10,7 @@ ### Installation `@remix-project/remix-simulator` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-simulator` +`yarn add @remix-project/remix-simulator` ### How to use diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index 95985105e7..edebf864e9 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-simulator", - "version": "0.2.13", + "version": "0.2.14", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -18,7 +18,7 @@ "@ethereumjs/common": "^2.5.0", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-lib": "^0.5.13", + "@remix-project/remix-lib": "^0.5.14", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", @@ -67,5 +67,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-simulator/src/methods/blocks.ts b/libs/remix-simulator/src/methods/blocks.ts index 1ecc7b30e4..e2594b05ac 100644 --- a/libs/remix-simulator/src/methods/blocks.ts +++ b/libs/remix-simulator/src/methods/blocks.ts @@ -40,7 +40,6 @@ export class Blocks { return cb(new Error('block not found')) } - console.log(block.transactions) const transactions = block.transactions.map((t) => { const hash = '0x' + t.hash().toString('hex') const tx = this.vmContext.txByHash[hash] @@ -95,7 +94,6 @@ export class Blocks { eth_getBlockByHash (payload, cb) { const block = this.vmContext.blocks[payload.params[0]] - console.log(block.transactions) const transactions = block.transactions.map((t) => { const hash = '0x' + t.hash().toString('hex') const tx = this.vmContext.txByHash[hash] diff --git a/libs/remix-solidity/README.md b/libs/remix-solidity/README.md index 2e448074fc..45f0cda698 100644 --- a/libs/remix-solidity/README.md +++ b/libs/remix-solidity/README.md @@ -12,7 +12,7 @@ `@remix-project/remix-solidity` is an NPM package and can be installed using NPM as: -`npm install @remix-project/remix-solidity` +`yarn add @remix-project/remix-solidity` ### How to use diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index 351f9ab46f..bc1038ded4 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-solidity", - "version": "0.4.13", + "version": "0.5.0", "description": "Tool to load and run Solidity compiler", "main": "src/index.js", "types": "src/index.d.ts", @@ -18,7 +18,7 @@ "@ethereumjs/block": "^3.5.1", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-lib": "^0.5.13", + "@remix-project/remix-lib": "^0.5.14", "async": "^2.6.2", "eslint-scope": "^5.0.0", "ethereumjs-util": "^7.0.10", @@ -61,5 +61,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-solidity/src/compiler/compiler-input.ts b/libs/remix-solidity/src/compiler/compiler-input.ts index 59a650620e..44c03305e0 100644 --- a/libs/remix-solidity/src/compiler/compiler-input.ts +++ b/libs/remix-solidity/src/compiler/compiler-input.ts @@ -46,3 +46,9 @@ export function getValidLanguage (val: string): Language { } return null } + +export function compilerInputForConfigFile(sources: Source, opts) +{ + opts.sources = sources + return JSON.stringify(opts) +} diff --git a/libs/remix-solidity/src/compiler/compiler.ts b/libs/remix-solidity/src/compiler/compiler.ts index a10fa6fce2..f728748a9e 100644 --- a/libs/remix-solidity/src/compiler/compiler.ts +++ b/libs/remix-solidity/src/compiler/compiler.ts @@ -2,7 +2,7 @@ import { update } from 'solc/abi' import * as webworkify from 'webworkify-webpack' -import compilerInput from './compiler-input' +import compilerInput, { compilerInputForConfigFile } from './compiler-input' import EventManager from '../lib/eventManager' import txHelper from './helper' import { @@ -31,6 +31,8 @@ export class Compiler { language: 'Solidity', compilationStartTime: null, target: null, + useFileConfiguration: false, + configFileContent: '', lastCompilationResult: { data: null, source: null @@ -111,11 +113,17 @@ export class Compiler { return { error: 'Deferred import' } } let result: CompilationResult = {} - let input + let input = "" try { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state - input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state + + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + result = JSON.parse(compiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -183,11 +191,17 @@ export class Compiler { return { error: 'Deferred import' } } let result: CompilationResult = {} - let input: string + let input = "" try { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state - input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state + + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -289,12 +303,26 @@ export class Compiler { this.state.compileJSON = (source: SourceWithTarget) => { if (source && source.sources) { - const { optimize, runs, evmVersion, language } = this.state + const { optimize, runs, evmVersion, language, useFileConfiguration, configFileContent } = this.state jobs.push({ sources: source }) + let input = "" + + try { + if (useFileConfiguration) { + input = compilerInputForConfigFile(source.sources, JSON.parse(configFileContent)) + } else { + input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) + } + } catch (exception) { + this.onCompilationFinished({ error: { formattedMessage: exception.message } }, [], source, "", this.state.currentVersion) + return + } + + this.state.worker.postMessage({ cmd: 'compile', job: jobs.length - 1, - input: compilerInput(source.sources, { optimize, runs, evmVersion, language }) + input: input }) } } diff --git a/libs/remix-solidity/src/compiler/types.ts b/libs/remix-solidity/src/compiler/types.ts index 76ed36ca17..c4e48dd2ff 100644 --- a/libs/remix-solidity/src/compiler/types.ts +++ b/libs/remix-solidity/src/compiler/types.ts @@ -164,6 +164,8 @@ export interface CompilerState { language: Language, compilationStartTime: number| null, target: string | null, + useFileConfiguration: boolean, + configFileContent: string, lastCompilationResult: { data: CompilationResult | null, source: SourceWithTarget | null | undefined diff --git a/libs/remix-tests/README.md b/libs/remix-tests/README.md index f08ca19985..81a3bc6aaf 100644 --- a/libs/remix-tests/README.md +++ b/libs/remix-tests/README.md @@ -12,11 +12,11 @@ To know more about Remix IDE `Solidity Unit Testing Plugin`, visit [Remix IDE of ### Installation * As a dev dependency: -`npm install --save-dev @remix-project/remix-tests` +`yarn add --dev @remix-project/remix-tests` * As a global NPM module to use as CLI: -`npm -g install @remix-project/remix-tests` +`yarn global add @remix-project/remix-tests` To confirm installation, run: ``` diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index 35e805d91f..2029b0ed7e 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-tests", - "version": "0.2.13", + "version": "0.2.14", "description": "Tool to test Solidity smart contracts", "main": "src/index.js", "types": "./src/index.d.ts", @@ -39,9 +39,9 @@ "@ethereumjs/common": "^2.5.0", "@ethereumjs/tx": "^3.3.2", "@ethereumjs/vm": "^5.5.3", - "@remix-project/remix-lib": "^0.5.13", - "@remix-project/remix-simulator": "^0.2.13", - "@remix-project/remix-solidity": "^0.4.13", + "@remix-project/remix-lib": "^0.5.14", + "@remix-project/remix-simulator": "^0.2.14", + "@remix-project/remix-solidity": "^0.5.0", "ansi-gray": "^0.1.1", "async": "^2.6.0", "axios": ">=0.21.1", @@ -79,5 +79,5 @@ "typescript": "^3.3.1" }, "typings": "src/index.d.ts", - "gitHead": "2be5108c51f2ac9226e4598c512ec6d3c63f5c78" + "gitHead": "3f311aaf25f5796f70711006bb783ee4087ffc71" } \ No newline at end of file diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index 496f6f4936..65bea514da 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -11,7 +11,7 @@ describe('testRunner: remix-tests CLI', () => { const dirContent = result.stdout.toString() // Install dependencies if 'node_modules' is not already present if(!dirContent.includes('node_modules')) { - execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) + execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) } } diff --git a/libs/remix-ui/editor/src/lib/remix-plugin-types.ts b/libs/remix-ui/editor/src/lib/remix-plugin-types.ts index 3c0a4d5e23..ceb49f5399 100644 --- a/libs/remix-ui/editor/src/lib/remix-plugin-types.ts +++ b/libs/remix-ui/editor/src/lib/remix-plugin-types.ts @@ -1,5548 +1,935 @@ -export const types = ` -declare module 'dist/packages/api/lib/compiler/type/input' { - export interface CompilationInput { - /** Source code language */ - language: 'Solidity' | 'Vyper' | 'lll' | 'assembly' | 'yul'; - sources: SourcesInput; - settings?: CompilerSettings; - outputSelection?: CompilerOutputSelection; - } - export interface CondensedCompilationInput { - language: 'Solidity' | 'Vyper' | 'lll' | 'assembly' | 'yul'; - optimize: boolean; - /** e.g: 0.6.8+commit.0bbfe453 */ - version: string; - evmVersion?: 'istanbul' | 'petersburg' | 'constantinople' | 'byzantium' | 'spuriousDragon' | 'tangerineWhistle' | 'homestead'; - } - export interface SourceInputUrls { - /** Hash of the source file. It is used to verify the retrieved content imported via URLs */ - keccak256?: string; - /** - * URL(s) to the source file. - * URL(s) should be imported in this order and the result checked against the - * keccak256 hash (if available). If the hash doesn't match or none of the - * URL(s) result in success, an error should be raised. - */ - urls: string[]; - } - export interface SourceInputContent { - /** Hash of the source file. */ - keccak256?: string; - /** Literal contents of the source file */ - content: string; - } - export interface SourcesInput { - [contractName: string]: SourceInputContent | SourceInputUrls; - } - export interface CompilerSettings { - /** Sorted list of remappings */ - remappings?: string[]; - /** Optimizer settings */ - optimizer?: Partial; - /** Version of the EVM to compile for. Affects type checking and code generation */ - evmVersion: 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople'; - /** Metadata settings */ - metadata?: CompilerMetadata; - /** Addresses of the libraries. If not all libraries are given here, it can result in unlinked objects whose output data is different. */ - libraries: CompilerLibraries; - } - export interface CompilerOptimizer { - /** disabled by default */ - enable: boolean; - /** - * Optimize for how many times you intend to run the code. - * Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage. - */ - runs: number; - } - export interface CompilerMetadata { - /** Use only literal content and not URLs (false by default) */ - useLiteralContent: boolean; - } - /** - * The top level key is the the name of the source file where the library is used. - * If remappings are used, this source file should match the global path after remappings were applied. - * If this key is an empty string, that refers to a global level. - */ - export interface CompilerLibraries { - [contractName: string]: { - [libName: string]: string; - }; - } - export type OutputType = 'abi' | 'ast' | 'devdoc' | 'userdoc' | 'metadata' | 'ir' | 'evm.assembly' | 'evm.legacyAssembly' | 'evm.bytecode.object' | 'evm.bytecode.opcodes' | 'evm.bytecode.sourceMap' | 'evm.bytecode.linkReferences' | 'evm.deployedBytecode' | 'evm.methodIdentifiers' | 'evm.gasEstimates' | 'ewasm.wast' | 'ewasm.wasm'; - /** - * The following can be used to select desired outputs. - * If this field is omitted, then the compiler loads and does type checking, but will not generate any outputs apart from errors. - * The first level key is the file name and the second is the contract name, where empty contract name refers to the file itself, - * while the star refers to all of the contracts. - * Note that using a using evm, evm.bytecode, ewasm, etc. will select every - * target part of that output. Additionally, * can be used as a wildcard to request everything. - */ - export interface CompilerOutputSelection { - [file: string]: { - [contract: string]: OutputType[]; - }; - } - -} -declare module 'dist/packages/api/lib/compiler/type/output' { - export interface CompilationFileSources { - [fileName: string]: { - keccak256?: string; - content: string; - urls?: string[]; - }; - } - export interface SourceWithTarget { - sources?: CompilationFileSources; - target?: string | null | undefined; - } - export interface CompilationResult { - /** not present if no errors/warnings were encountered */ - errors?: CompilationError[]; - /** This contains the file-level outputs. In can be limited/filtered by the outputSelection settings */ - sources: { - [contractName: string]: CompilationSource; - }; - /** This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings */ - contracts: { - /** If the language used has no contract names, this field should equal to an empty string. */ - [fileName: string]: { - [contract: string]: CompiledContract; - }; - }; - } - export interface lastCompilationResult { - data: CompilationResult | null; - source: SourceWithTarget | null | undefined; - } - export interface CompilationError { - /** Location within the source file */ - sourceLocation?: { - file: string; - start: number; - end: number; - }; - /** Error type */ - type: CompilationErrorType; - /** Component where the error originated, such as "general", "ewasm", etc. */ - component: 'general' | 'ewasm' | string; - severity: 'error' | 'warning'; - message: string; - /** the message formatted with source location */ - formattedMessage?: string; - } type CompilationErrorType = 'JSONError' | 'IOError' | 'ParserError' | 'DocstringParsingError' | 'SyntaxError' | 'DeclarationError' | 'TypeError' | 'UnimplementedFeatureError' | 'InternalCompilerError' | 'Exception' | 'CompilerError' | 'FatalError' | 'Warning'; - export interface CompilationSource { - /** Identifier of the source (used in source maps) */ - id: number; - /** The AST object */ - ast: AstNode; - /** The legacy AST object */ - legacyAST: AstNodeLegacy; - } - export interface AstNode { - absolutePath?: string; - exportedSymbols?: Object; - id: number; - nodeType: string; - nodes?: Array; - src: string; - literals?: Array; - file?: string; - scope?: number; - sourceUnit?: number; - symbolAliases?: Array; - [x: string]: any; - } - export interface AstNodeLegacy { - id: number; - name: string; - src: string; - children?: Array; - attributes?: AstNodeAtt; - } - export interface AstNodeAtt { - operator?: string; - string?: null; - type?: string; - value?: string; - constant?: boolean; - name?: string; - public?: boolean; - exportedSymbols?: Object; - argumentTypes?: null; - absolutePath?: string; - [x: string]: any; - } - export interface CompiledContract { - /** The Ethereum Contract ABI. If empty, it is represented as an empty array. */ - abi: ABIDescription[]; - metadata: string; - /** User documentation (natural specification) */ - userdoc: UserDocumentation; - /** Developer documentation (natural specification) */ - devdoc: DeveloperDocumentation; - /** Intermediate representation (string) */ - ir: string; - /** EVM-related outputs */ - evm: { - assembly: string; - legacyAssembly: {}; - /** Bytecode and related details. */ - bytecode: BytecodeObject; - deployedBytecode: BytecodeObject; - /** The list of function hashes */ - methodIdentifiers: { - [functionIdentifier: string]: string; - }; - gasEstimates: { - creation: { - codeDepositCost: string; - executionCost: 'infinite' | string; - totalCost: 'infinite' | string; - }; - external: { - [functionIdentifier: string]: string; - }; - internal: { - [functionIdentifier: string]: 'infinite' | string; - }; - }; - }; - /** eWASM related outputs */ - ewasm: { - /** S-expressions format */ - wast: string; - /** Binary format (hex string) */ - wasm: string; - }; - } - export type ABIDescription = FunctionDescription | EventDescription; - export interface FunctionDescription { - /** Type of the method. default is 'function' */ - type?: 'function' | 'constructor' | 'fallback'; - /** The name of the function. Constructor and fallback functions never have a name */ - name?: string; - /** List of parameters of the method. Fallback functions don’t have inputs. */ - inputs?: ABIParameter[]; - /** List of the output parameters for the method, if any */ - outputs?: ABIParameter[]; - /** State mutability of the method */ - stateMutability: 'pure' | 'view' | 'nonpayable' | 'payable'; - /** true if function accepts Ether, false otherwise. Default is false */ - payable?: boolean; - /** true if function is either pure or view, false otherwise. Default is false */ - constant?: boolean; - } - export interface EventDescription { - type: 'event'; - name: string; - inputs: ABIParameter & { - /** true if the field is part of the log’s topics, false if it one of the log’s data segment. */ - indexed: boolean; - }[]; - /** true if the event was declared as anonymous. */ - anonymous: boolean; - } - export interface ABIParameter { - /** The name of the parameter */ - name: string; - /** The canonical type of the parameter */ - type: ABITypeParameter; - /** Used for tuple types */ - components?: ABIParameter[]; - } - export type ABITypeParameter = 'uint' | 'uint[]' | 'int' | 'int[]' | 'address' | 'address[]' | 'bool' | 'bool[]' | 'fixed' | 'fixed[]' | 'ufixed' | 'ufixed[]' | 'bytes' | 'bytes[]' | 'function' | 'function[]' | 'tuple' | 'tuple[]' | string; - export interface UserDocumentation { - methods: UserMethodList; - notice: string; - } - export type UserMethodList = { - [functionIdentifier: string]: UserMethodDoc; - } & { - 'constructor'?: string; - }; - export interface UserMethodDoc { - notice: string; - } - export interface DeveloperDocumentation { - author: string; - title: string; - details: string; - methods: DevMethodList; - } - export interface DevMethodList { - [functionIdentifier: string]: DevMethodDoc; - } - export interface DevMethodDoc { - author: string; - details: string; - return: string; - returns: { - [param: string]: string; - }; - params: { - [param: string]: string; - }; - } - export interface BytecodeObject { - /** The bytecode as a hex string. */ - object: string; - /** Opcodes list */ - opcodes: string; - /** The source mapping as a string. See the source mapping definition. */ - sourceMap: string; - /** If given, this is an unlinked object. */ - linkReferences?: { - [contractName: string]: { - /** Byte offsets into the bytecode. */ - [library: string]: { - start: number; - length: number; - }[]; - }; - }; - } - export {}; - -} -declare module 'dist/packages/api/lib/compiler/type/index' { - export * from 'dist/packages/api/lib/compiler/type/input'; - export * from 'dist/packages/api/lib/compiler/type/output'; - -} -declare module 'packages/utils/src/lib/tools/event-name' { - /** Create the name of the event for a call */ - export function callEvent(name: string, key: string, id: number): string; - /** Create the name of the event for a listen */ - export function listenEvent(name: string, key: string): string; - -} -declare module 'packages/utils/src/lib/tools/method-path' { - /** Create a method path based on the method name and the path */ - export function getMethodPath(method: string, path?: string): string; - /** Get the root name of a path */ - export function getRootPath(path: string): string; - -} -declare module 'packages/utils/src/lib/types/service' { - export type IPluginService = any> = { - methods: string[]; - readonly path: string; - } & T; - export type GetPluginService> = S extends IPluginService ? S : IPluginService; - -} -declare module 'packages/utils/src/lib/types/status' { - export interface Status { - /** Display an icon or number */ - key: number | 'edited' | 'succeed' | 'loading' | 'failed' | 'none'; - /** Bootstrap css color */ - type?: 'success' | 'info' | 'warning' | 'error'; - /** Describe the status on mouseover */ - title?: string; - } - export type StatusEvents = { - statusChanged: (status: Status) => void; - }; - -} -declare module 'packages/utils/src/lib/types/api' { - import { StatusEvents } from 'packages/utils/src/lib/types/status'; - export interface Api { - events: { - [key: string]: (...args: any[]) => void; - } & StatusEvents; - methods: { - [key: string]: (...args: any[]) => void; - }; - } - export type EventKey = Extract; - export type EventParams> = T extends Api ? Parameters : any[]; - export type EventCallback> = T extends Api ? T['events'][K] : (...payload: any[]) => void; - export type MethodKey = Extract; - export type MethodParams> = T extends Api ? Parameters : any[]; - export interface EventApi { - on: >(name: event, cb: T['events'][event]) => void; - } - export type MethodApi = { - [m in Extract]: (...args: Parameters) => Promise>; - }; - export type CustomApi = EventApi & MethodApi; - /** A map of Api used to describe all the plugin's api in the project */ - export type ApiMap = Readonly>; - /** A map of plugin based on the ApiMap. It enforces the PluginEngine */ - export type PluginApi = { - [name in keyof T]: CustomApi; - }; - export type API = { - [M in keyof T['methods']]: T['methods'][M] | Promise; - }; - -} -declare module 'packages/utils/src/lib/types/plugin' { - import type { IPluginService } from 'packages/utils/src/lib/types/service'; - import { EventCallback, MethodParams, MethodKey, EventKey, Api, ApiMap, EventParams } from 'packages/utils/src/lib/types/api'; - export interface PluginBase { - methods: string[]; - activateService: Record Promise>; - /** Listen on an event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen one time on an event from another plugin, then remove event listener */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Stop listening on an event from another plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Call a method of another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise; - /** Clear calls in queue of a plugin called by plugin */ - cancel, Key extends MethodKey>(name: Name, key: Key): void; - /** Emit an event */ - emit>(key: Key, ...payload: EventParams): void; - } - -} -declare module 'packages/utils/src/lib/tools/service' { - import type { IPluginService, GetPluginService } from 'packages/utils/src/lib/types/service'; - import type { Api, ApiMap } from 'packages/utils/src/lib/types/api'; - import type { PluginBase } from 'packages/utils/src/lib/types/plugin'; - /** Check if the plugin is an instance of PluginService */ - export const isPluginService: (service: any) => service is PluginService; - /** - * Return the methods of a service, except "constructor" and methods starting with "_" - * @param instance The instance of a class to get the method from - */ - export function getMethods(service: IPluginService): any; - /** - * Create a plugin service - * @param path The path of the service separated by '.' (ex: 'box.profile') - * @param service The service template - * @note If the service doesn't provide a property "methods" then all methods are going to be exposed by default - */ - export function createService>(path: string, service: T): GetPluginService; - /** - * Connect the service to the plugin client - * @param client The main client of the plugin - * @param service A service to activate - */ - export function activateService(client: PluginBase, service: IPluginService): any; - /** - * A node that forward the call to the right path - */ - export abstract class PluginService implements IPluginService { - methods: string[]; - abstract readonly path: string; - protected abstract plugin: PluginBase; - emit(key: string, ...payload: any[]): void; - /** - * Create a subservice under this service - * @param name The name of the subservice inside this service - * @param service The subservice to add - */ - createService>(name: string, service: S): Promise>; - /** - * Prepare a service to be lazy loaded. - * Service can be activated by doing client.activateService(path) - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): void; - } - -} -declare module 'packages/utils/src/lib/types/message' { - export interface PluginRequest { - /** The name of the plugin making the request */ - from: string; - /** @deprecated Will be remove in the next version */ - isFromNative?: boolean; - /** - * The path to access the request inside the plugin - * @example 'remixd.cmd.git' - */ - path?: string; - } type MessageActions = 'on' | 'off' | 'once' | 'call' | 'response' | 'emit' | 'cancel'; type OldMessageActions = 'notification' | 'request' | 'response' | 'listen'; - export interface Message { - id: number; - action: MessageActions | OldMessageActions; - name: string; - key: string; - payload: any; - requestInfo: PluginRequest; - error?: Error | string; - } - export {}; - -} -declare module 'packages/utils/src/lib/types/queue' { - import type { PluginRequest } from 'packages/utils/src/lib/types/message'; - export interface PluginQueueInterface { - setCurrentRequest(request: PluginRequest): void; - callMethod(method: string, args: any[]): void; - letContinue(): void; - cancel(): void; - } - -} -declare module 'packages/utils/src/lib/types/profile' { - import { MethodKey, Api, ApiMap, EventKey } from 'packages/utils/src/lib/types/api'; - /** Describe a plugin */ - export interface Profile { - name: string; - displayName?: string; - methods?: MethodKey[]; - events?: EventKey[]; - permission?: boolean; - hash?: string; - description?: string; - documentation?: string; - version?: string; - kind?: string; - canActivate?: string[]; - icon?: string; - } - export interface LocationProfile { - location: string; - } - export interface ExternalProfile { - url: string; - } - export interface HostProfile extends Profile { - methods: ('addView' | 'removeView' | 'focus' | string)[]; - } - export interface LibraryProfile extends Profile { - events?: EventKey[]; - notifications?: { - [name: string]: string[]; - }; - } - /** A map of profile */ - export type ProfileMap = Partial<{ - [name in keyof T]: Profile; - }>; - /** Extract the API of a profile */ - export type ApiFromProfile = T extends Profile ? I : never; - /** Create an ApiMap from a Profile Map */ - export type ApiMapFromProfileMap> = { - [name in keyof T]: ApiFromProfile; - }; - /** Transform an ApiMap into a profile map */ - export type ProfileMapFromApiMap = Readonly<{ - [name in keyof T]: Profile; - }>; - -} -declare module 'packages/utils/src/lib/tools/queue' { - import { PluginQueueInterface } from 'packages/utils/src/lib/types/queue'; - import type { PluginRequest } from 'packages/utils/src/lib/types/message'; - import { Profile } from 'packages/utils/src/lib/types/profile'; - import { Api } from 'packages/utils/src/lib/types/api'; - import { PluginOptions } from '@remixproject/plugin-utils'; - export class PluginQueueItem implements PluginQueueInterface { - private resolve; - private reject; - private timer; - private running; - private args; - method: Profile['methods'][number]; - timedout: boolean; - canceled: boolean; - finished: boolean; - request: PluginRequest; - private options; - constructor(resolve: (value: unknown) => void, reject: (reason: any) => void, request: PluginRequest, method: Profile['methods'][number], options: PluginOptions, args: any[]); - setCurrentRequest(request: PluginRequest): void; - callMethod(method: string, args: any[]): void; - letContinue(): void; - cancel(): void; - run(): Promise; - } - -} -declare module 'packages/utils/src/lib/types/options' { - export interface PluginOptions { - /** The time to wait for a call to be executed before going to next call in the queue */ - queueTimeout?: number; - } - -} -declare module 'packages/utils/src/index' { - export * from 'packages/utils/src/lib/tools/event-name'; - export * from 'packages/utils/src/lib/tools/method-path'; - export * from 'packages/utils/src/lib/tools/service'; - export * from 'packages/utils/src/lib/tools/queue'; - export * from 'packages/utils/src/lib/types/api'; - export * from 'packages/utils/src/lib/types/message'; - export * from 'packages/utils/src/lib/types/plugin'; - export * from 'packages/utils/src/lib/types/profile'; - export * from 'packages/utils/src/lib/types/service'; - export * from 'packages/utils/src/lib/types/status'; - export * from 'packages/utils/src/lib/types/queue'; - export * from 'packages/utils/src/lib/types/options'; - -} -declare module 'dist/packages/api/lib/compiler/api' { - import { CompilationResult, CompilationFileSources, lastCompilationResult, CondensedCompilationInput, SourcesInput } from 'dist/packages/api/lib/compiler/type'; - import { StatusEvents, Api } from '@remixproject/plugin-utils'; - export interface ICompiler extends Api { - events: { - compilationFinished: (fileName: string, source: CompilationFileSources, languageVersion: string, data: CompilationResult) => void; - } & StatusEvents; - methods: { - getCompilationResult(): lastCompilationResult; - compile(fileName: string): void; - setCompilerConfig(settings: CondensedCompilationInput): void; - compileWithParameters(targets: SourcesInput, settings: CondensedCompilationInput): lastCompilationResult; - }; - } - -} -declare module 'dist/packages/api/lib/compiler/profile' { - import { ICompiler } from 'dist/packages/api/lib/compiler/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const compilerProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/compiler/index' { - export * from 'dist/packages/api/lib/compiler/api'; - export * from 'dist/packages/api/lib/compiler/type'; - export * from 'dist/packages/api/lib/compiler/profile'; - -} -declare module 'dist/packages/api/lib/content-import/type' { - export interface ContentImport { - content: any; - cleanUrl: string; - type: 'github' | 'http' | 'https' | 'swarm' | 'ipfs'; - url: string; - } - -} -declare module 'dist/packages/api/lib/content-import/api' { - import { ContentImport } from 'dist/packages/api/lib/content-import/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IContentImport { - events: {} & StatusEvents; - methods: { - resolve(path: string): ContentImport; - resolveAndSave(url: string, targetPath: string): string; - }; - } - -} -declare module 'dist/packages/api/lib/content-import/profile' { - import { IContentImport } from 'dist/packages/api/lib/content-import/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const contentImportProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/content-import/index' { - export * from 'dist/packages/api/lib/content-import/api'; - export * from 'dist/packages/api/lib/content-import/type'; - export * from 'dist/packages/api/lib/content-import/profile'; - -} -declare module 'dist/packages/api/lib/editor/type' { - export interface HighlightPosition { - start: { - line: number; - column: number; - }; - end: { - line: number; - column: number; - }; - } - export interface Annotation { - row: number; - column: number; - text: string; - type: "error" | "warning" | "info"; - } - -} -declare module 'dist/packages/api/lib/editor/api' { - import { HighlightPosition, Annotation } from 'dist/packages/api/lib/editor/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IEditor { - events: {} & StatusEvents; - methods: { - highlight(position: HighlightPosition, filePath: string, hexColor: string): void; - discardHighlight(): void; - discardHighlightAt(line: number, filePath: string): void; - addAnnotation(annotation: Annotation): void; - clearAnnotations(): void; - }; - } - -} -declare module 'dist/packages/api/lib/editor/profile' { - import { IEditor } from 'dist/packages/api/lib/editor/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const editorProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/editor/index' { - export * from 'dist/packages/api/lib/editor/type'; - export * from 'dist/packages/api/lib/editor/api'; - export * from 'dist/packages/api/lib/editor/profile'; - -} -declare module 'dist/packages/api/lib/file-system/type' { - export interface Folder { - [path: string]: { - isDirectory: boolean; - }; - } - -} -declare module 'dist/packages/api/lib/file-system/api' { - import { Folder } from 'dist/packages/api/lib/file-system/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IFileSystem { - events: { - currentFileChanged: (file: string) => void; - fileSaved: (file: string) => void; - fileAdded: (file: string) => void; - fileRemoved: (file: string) => void; - fileClosed: (file: string) => void; - noFileSelected: () => void; - fileRenamed: (oldName: string, newName: string, isFolder: boolean) => void; - } & StatusEvents; - methods: { - /** Open the content of the file in the context (eg: Editor) */ - open(path: string): void; - /** Set the content of a specific file */ - writeFile(path: string, data: string): void; - /** Return the content of a specific file */ - readFile(path: string): string; - /** Change the path of a file */ - rename(oldPath: string, newPath: string): void; - /** Upsert a file with the content of the source file */ - copyFile(src: string, dest: string): void; - /** Create a directory */ - mkdir(path: string): void; - /** Get the list of files in the directory */ - readdir(path: string): string[]; - /** Removes a file or directory recursively */ - remove(path: string): void; - /** Get the name of the file currently focused if any */ - getCurrentFile(): string; - /** @deprecated Use readdir */ - getFolder(path: string): Folder; - /** @deprecated Use readFile */ - getFile(path: string): string; - /** @deprecated Use writeFile */ - setFile(path: string, content: string): void; - /** @deprecated Use open */ - switchFile(path: string): void; - }; - } - -} -declare module 'dist/packages/api/lib/file-system/profile' { - import { IFileSystem } from 'dist/packages/api/lib/file-system/api'; - import { LocationProfile, Profile } from '@remixproject/plugin-utils'; - export const filSystemProfile: Profile & LocationProfile; - -} -declare module 'dist/packages/api/lib/file-system/index' { - export * from 'dist/packages/api/lib/file-system/api'; - export * from 'dist/packages/api/lib/file-system/type'; - export * from 'dist/packages/api/lib/file-system/profile'; - -} -declare module 'dist/packages/api/lib/git/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IGitSystem { - events: {} & StatusEvents; - methods: { - clone(url: string): string; - checkout(cmd: string): string; - init(): string; - add(cmd: string): string; - commit(cmd: string): string; - fetch(cmd: string): string; - pull(cmd: string): string; - push(cmd: string): string; - reset(cmd: string): string; - status(cmd: string): string; - remote(cmd: string): string; - log(): string; - }; - } - -} -declare module 'dist/packages/api/lib/git/profile' { - import { IGitSystem } from 'dist/packages/api/lib/git/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const gitProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/git/index' { - export * from 'dist/packages/api/lib/git/api'; - export * from 'dist/packages/api/lib/git/profile'; - -} -declare module 'dist/packages/api/lib/network/type' { - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export interface CustomNetwork { - id?: string; - name: string; - url: string; - } - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export type NetworkProvider = 'vm' | 'injected' | 'web3'; - export type Network = { - id: '1'; - name: 'Main'; - } | { - id: '2'; - name: 'Morden (deprecated)'; - } | { - id: '3'; - name: 'Ropsten'; - } | { - id: '4'; - name: 'Rinkeby'; - } | { - id: '5'; - name: 'Goerli'; - } | { - id: '42'; - name: 'Kovan'; - }; - -} -declare module 'dist/packages/api/lib/network/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { NetworkProvider, Network, CustomNetwork } from 'dist/packages/api/lib/network/type'; - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export interface INetwork { - events: { - providerChanged: (provider: NetworkProvider) => void; - } & StatusEvents; - methods: { - getNetworkProvider(): NetworkProvider; - detectNetwork(): Network | Partial; - getEndpoint(): string; - addNetwork(network: CustomNetwork): void; - removeNetwork(name: string): void; - }; - } - -} -declare module 'dist/packages/api/lib/network/profile' { - import { INetwork } from 'dist/packages/api/lib/network/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const networkProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/network/index' { - export * from 'dist/packages/api/lib/network/api'; - export * from 'dist/packages/api/lib/network/type'; - export * from 'dist/packages/api/lib/network/profile'; - -} -declare module 'dist/packages/api/lib/plugin-manager/api' { - import { StatusEvents, Profile } from '@remixproject/plugin-utils'; - export interface IPluginManager { - events: { - profileUpdated(profile: Profile): void; - profileAdded(profile: Profile): void; - pluginDeactivated(profile: Profile): void; - pluginActivated(profile: Profile): void; - } & StatusEvents; - methods: { - getProfile(name: string): Promise; - updateProfile(profile: Partial): any; - activatePlugin(name: string): any; - deactivatePlugin(name: string): any; - isActive(name: string): boolean; - canCall(from: string, to: string, method: string, message?: string): any; - }; - } - -} -declare module 'dist/packages/api/lib/plugin-manager/profile' { - import { IPluginManager } from 'dist/packages/api/lib/plugin-manager/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const pluginManagerProfile: LibraryProfile & { - name: 'manager'; - }; - -} -declare module 'dist/packages/api/lib/plugin-manager/index' { - export * from 'dist/packages/api/lib/plugin-manager/api'; - export * from 'dist/packages/api/lib/plugin-manager/profile'; - -} -declare module 'dist/packages/api/lib/settings/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface ISettings { - events: {} & StatusEvents; - methods: { - getGithubAccessToken(): string; - }; - } - -} -declare module 'dist/packages/api/lib/settings/profile' { - import { ISettings } from 'dist/packages/api/lib/settings/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const settingsProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/settings/index' { - export * from 'dist/packages/api/lib/settings/api'; - export * from 'dist/packages/api/lib/settings/profile'; - -} -declare module 'dist/packages/api/lib/theme/types' { - export interface Theme { - url?: string; - /** @deprecated Use brightness instead */ - quality?: 'dark' | 'light'; - brightness: 'dark' | 'light'; - colors: { - surface: string; - background: string; - foreground: string; - primary: string; - primaryContrast: string; - secondary?: string; - secondaryContrast?: string; - success?: string; - successContrast?: string; - warn: string; - warnContrast: string; - error: string; - errorContrast: string; - disabled: string; - }; - breakpoints: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; - fontFamily: string; - /** A unit to multiply for margin & padding */ - space: number; - } - export interface ThemeUrls { - light: string; - dark: string; - } - -} -declare module 'dist/packages/api/lib/theme/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { Theme } from 'dist/packages/api/lib/theme/types'; - export interface ITheme { - events: { - themeChanged: (theme: Theme) => void; - } & StatusEvents; - methods: { - currentTheme(): Theme; - }; - } - -} -declare module 'dist/packages/api/lib/theme/profile' { - import { ITheme } from 'dist/packages/api/lib/theme/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const themeProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/theme/index' { - export * from 'dist/packages/api/lib/theme/api'; - export * from 'dist/packages/api/lib/theme/profile'; - export * from 'dist/packages/api/lib/theme/types'; - -} -declare module 'dist/packages/api/lib/udapp/type' { - export type RemixTxEvent = { - contractAddress: string; - data: string; - envMode: 'vm'; - executionCost: string; - from: string; - gas: string; - hash: string; - input: string; - logs: any[]; - returnValue: Uint8Array; - status: '0x01' | '0x00'; - transactionCost: string; - transactionHash: string; - value: string; - } | { - blockHash: string; - blockNumber: number; - envMod: 'injected' | 'web3'; - from: string; - gas: number; - gasPrice: { - c: number[]; - e: number; - s: number; - }; - hash: string; - input: string; - none: number; - r: string; - s: string; - v: string; - status: '0x01' | '0x00'; - to: string; - transactionCost: string; - transactionIndex: number; - value: { - c: number[]; - e: number; - s: number; - }; - }; - export interface RemixTx { - data: string; - from: string; - to?: string; - timestamp?: string; - gasLimit: string; - value: string; - useCall: boolean; - } - export interface RemixTxReceipt { - transactionHash: string; - status: 0 | 1; - gasUsed: string; - error: string; - return: string; - createdAddress?: string; - } - export interface VMAccount { - privateKey: string; - balance: string; - } - export interface UdappSettings { - selectedAccount: string; - selectedEnvMode: 'vm' | 'injected' | 'web3'; - networkEnvironment: string; - } - -} -declare module 'dist/packages/api/lib/udapp/api' { - import { RemixTx, RemixTxReceipt, RemixTxEvent, VMAccount, UdappSettings } from 'dist/packages/api/lib/udapp/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IUdapp { - events: { - newTransaction: (transaction: RemixTxEvent) => void; - } & StatusEvents; - methods: { - sendTransaction(tx: RemixTx): RemixTxReceipt; - getAccounts(): string[]; - createVMAccount(vmAccount: VMAccount): string; - getSettings(): UdappSettings; - setEnvironmentMode(env: 'vm' | 'injected' | 'web3'): void; - }; - } - -} -declare module 'dist/packages/api/lib/udapp/profile' { - import { IUdapp } from 'dist/packages/api/lib/udapp/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const udappProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/udapp/index' { - export * from 'dist/packages/api/lib/udapp/api'; - export * from 'dist/packages/api/lib/udapp/type'; - export * from 'dist/packages/api/lib/udapp/profile'; - -} -declare module 'dist/packages/api/lib/unit-testing/type' { - export interface UnitTestResult { - totalFailing: number; - totalPassing: number; - totalTime: number; - errors: UnitTestError[]; - } - export interface UnitTestError { - context: string; - value: string; - message: string; - } - -} -declare module 'dist/packages/api/lib/unit-testing/api' { - import { UnitTestResult } from 'dist/packages/api/lib/unit-testing/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IUnitTesting { - events: {} & StatusEvents; - methods: { - testFromPath(path: string): UnitTestResult; - testFromSource(sourceCode: string): UnitTestResult; - }; - } - -} -declare module 'dist/packages/api/lib/unit-testing/profile' { - import { IUnitTesting } from 'dist/packages/api/lib/unit-testing/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const unitTestProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/unit-testing/index' { - export * from 'dist/packages/api/lib/unit-testing/api'; - export * from 'dist/packages/api/lib/unit-testing/type'; - export * from 'dist/packages/api/lib/unit-testing/profile'; - -} -declare module 'dist/packages/api/lib/window/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IWindow { - events: {} & StatusEvents; - methods: { - /** Display an input window */ - prompt(message?: string): string; - /** Ask confirmation for an action */ - confirm(message: string): boolean; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): string | void; - }; - } - -} -declare module 'dist/packages/api/lib/window/profile' { - import { IWindow } from 'dist/packages/api/lib/window/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const windowProfile: LibraryProfile; - -} -declare module 'dist/packages/api/lib/window/index' { - export * from 'dist/packages/api/lib/window/api'; - export * from 'dist/packages/api/lib/window/profile'; - -} -declare module 'dist/packages/api/lib/remix-profile' { - import { ProfileMap } from '@remixproject/plugin-utils'; - import { ICompiler } from 'dist/packages/api/lib/compiler'; - import { IFileSystem } from 'dist/packages/api/lib/file-system'; - import { IEditor } from 'dist/packages/api/lib/editor'; - import { INetwork } from 'dist/packages/api/lib/network'; - import { IUdapp } from 'dist/packages/api/lib/udapp'; - import { ITheme } from 'dist/packages/api/lib/theme'; - import { IUnitTesting } from 'dist/packages/api/lib/unit-testing'; - import { IContentImport } from 'dist/packages/api/lib/content-import'; - import { ISettings } from 'dist/packages/api/lib/settings'; - import { IPluginManager } from 'dist/packages/api/lib/plugin-manager'; - export interface IRemixApi { - manager: IPluginManager; - solidity: ICompiler; - fileManager: IFileSystem; - solidityUnitTesting: IUnitTesting; - editor: IEditor; - network: INetwork; - udapp: IUdapp; - contentImport: IContentImport; - settings: ISettings; - theme: ITheme; - } - export type RemixApi = Readonly; - /** @deprecated Use remixProfiles instead. Will be remove in next version */ - export const remixApi: ProfileMap; - /** Profiles of all the remix's Native Plugins */ - export const remixProfiles: ProfileMap; - -} -declare module 'dist/packages/api/lib/standard-profile' { - import { ProfileMap } from '@remixproject/plugin-utils'; - import { ICompiler } from 'dist/packages/api/lib/compiler'; - import { IFileSystem } from 'dist/packages/api/lib/file-system'; - import { IEditor } from 'dist/packages/api/lib/editor'; - import { INetwork } from 'dist/packages/api/lib/network'; - import { IUdapp } from 'dist/packages/api/lib/udapp'; - import { IPluginManager } from 'dist/packages/api/lib/plugin-manager'; - export interface IStandardApi { - manager: IPluginManager; - solidity: ICompiler; - fileManager: IFileSystem; - editor: IEditor; - network: INetwork; - udapp: IUdapp; - } - export type StandardApi = Readonly; - /** Profiles of all the standard's Native Plugins */ - export const standardProfiles: ProfileMap; - -} -declare module 'dist/packages/api/index' { - export * from 'dist/packages/api/lib/compiler'; - export * from 'dist/packages/api/lib/content-import'; - export * from 'dist/packages/api/lib/editor'; - export * from 'dist/packages/api/lib/file-system'; - export * from 'dist/packages/api/lib/git'; - export * from 'dist/packages/api/lib/network'; - export * from 'dist/packages/api/lib/plugin-manager'; - export * from 'dist/packages/api/lib/settings'; - export * from 'dist/packages/api/lib/theme'; - export * from 'dist/packages/api/lib/udapp'; - export * from 'dist/packages/api/lib/unit-testing'; - export * from 'dist/packages/api/lib/window'; - export * from 'dist/packages/api/lib/remix-profile'; - export * from 'dist/packages/api/lib/standard-profile'; - -} -declare module 'dist/packages/engine/core/lib/abstract' { - import type { Api, EventKey, EventParams, MethodKey, MethodParams, EventCallback, ApiMap, Profile, PluginRequest, PluginApi, PluginBase, IPluginService } from '@remixproject/plugin-utils'; - export interface RequestParams { - name: string; - key: string; - payload: any[]; - } - export interface PluginOptions { - /** The time to wait for a call to be executed before going to next call in the queue */ - queueTimeout?: number; - } - export class Plugin implements PluginBase { - profile: Profile; - activateService: Record Promise>; - protected requestQueue: Array<() => Promise>; - protected currentRequest: PluginRequest; - /** Give access to all the plugins registered by the engine */ - protected app: PluginApi; - protected options: PluginOptions; - onRegistration?(): void; - onActivation?(): void; - onDeactivation?(): void; - constructor(profile: Profile); - get name(): string; - get methods(): Extract[]; - set methods(methods: Extract[]); - activate(): any | Promise; - deactivate(): any | Promise; - setOptions(options?: Partial): void; - /** Call a method from this plugin */ - protected callPluginMethod(key: string, args: any[]): any; - /** Add a request to the list of current requests */ - protected addRequest(request: PluginRequest, method: Profile['methods'][number], args: any[]): Promise; - /** - * Ask the plugin manager if current request can call a specific method - * @param method The method to call - * @param message An optional message to show to the user - */ - askUserPermission(method: MethodKey, message?: string): Promise; - /** - * Called by the engine when a plugin try to activate it - * @param from the profile of the plugin activating this plugin - * @param method method used to activate this plugin if any - */ - canActivate(from: Profile, method?: string): Promise; - /** - * Called by the engine when a plugin try to deactivate it - * @param from the profile of the plugin deactivating this plugin - */ - canDeactivate(from: Profile): Promise; - /** - * Create a service under the client node - * @param name The name of the service - * @param service The service - */ - createService>(name: string, service: S): Promise>; - /** - * Prepare a service to be lazy loaded - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): () => Promise>; - /** Listen on an event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen once an event from another plugin then remove event listener */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Stop listening on an event from another plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Call a method of another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise>; - /** Emit an event */ - emit>(key: Key, ...payload: EventParams): void; - } - -} -declare module 'dist/packages/engine/core/lib/connector' { - import type { ExternalProfile, Profile, Message } from '@remixproject/plugin-utils'; - import { Plugin, PluginOptions } from 'dist/packages/engine/core/lib/abstract'; - /** List of available gateways for decentralised storage */ - export const defaultGateways: { - 'ipfs://': (url: any, name: any) => string; - 'swarm://': (url: any, name: any) => string; - }; - /** Transform the URL to use a gateway if decentralised storage is specified */ - export function transformUrl({ url, name }: Profile & ExternalProfile): any; - export interface PluginConnectorOptions extends PluginOptions { - /** Usally used to reload the plugin on changes */ - devMode?: boolean; - transformUrl?: (profile: Profile & ExternalProfile) => string; - engine?: string; - } - export abstract class PluginConnector extends Plugin { - protected loaded: boolean; - protected id: number; - protected pendingRequest: Record void>; - protected options: PluginConnectorOptions; - profile: Profile & ExternalProfile; - constructor(profile: Profile & ExternalProfile); - /** - * Send a message to the external plugin - * @param message the message passed to the plugin - */ - protected abstract send(message: Partial): void; - /** - * Open connection with the plugin - * @param url The transformed url the plugin should connect to - */ - protected abstract connect(url: string): any | Promise; - /** Close connection with the plugin */ - protected abstract disconnect(): any | Promise; - activate(): Promise; - deactivate(): Promise; - /** Set options for an external plugin */ - setOptions(options?: Partial): void; - /** Call a method from this plugin */ - protected callPluginMethod(key: string, payload?: any[]): Promise; - /** Perform handshake with the client if not loaded yet */ - protected handshake(handshakeSpecificPayload?: string[]): Promise; - /** - * React when a message comes from client - * @param message The message sent by the client - */ - protected getMessage(message: Message): Promise; - } - -} -declare module 'dist/packages/engine/core/lib/engine' { - import type { Profile } from '@remixproject/plugin-utils'; - import { Plugin, PluginOptions } from 'dist/packages/engine/core/lib/abstract'; - export class Engine { - private plugins; - private events; - private listeners; - private eventMemory; - private manager; - onRegistration?(plugin: Plugin): void; - /** Update the options of the plugin when being registered */ - setPluginOption?(profile: Profile): PluginOptions; - /** - * Broadcast an event to the plugin listening - * @param emitter Plugin name that emits the event - * @param event The name of the event - * @param payload The content of the event - */ - private broadcast; - /** - * Start listening on an event from another plugin - * @param listener The name of the plugin that listen on the event - * @param emitter The name of the plugin that emit the event - * @param event The name of the event - * @param cb Callback function to trigger when the event is trigger - */ - private addListener; - /** - * Remove an event from the list of a listener's events - * @param listener The name of the plugin that was listening on the event - * @param emitter The name of the plugin that emitted the event - * @param event The name of the event - */ - private removeListener; - /** - * Create a listener that listen only once on an event - * @param listener The name of the plugin that listen on the event - * @param emitter The name of the plugin that emitted the event - * @param event The name of the event - * @param cb Callback function to trigger when event is triggered - */ - private listenOnce; - /** - * Call a method of a plugin from another - * @param caller The name of the plugin that calls the method - * @param path The path of the plugin that manages the method - * @param method The name of the method - * @param payload The argument to pass to the method - */ - private callMethod; - /** - * Create an object to easily access any registered plugin - * @param name Name of the caller plugin - * @note This method creates a snapshot at the time of activation - */ - private createApp; - /** - * Activate a plugin by making its method and event available - * @param name The name of the plugin - * @note This method is trigger by the plugin manager when a plugin has been activated - */ - private activatePlugin; - /** - * Deactivate a plugin by removing all its event listeners and making it inaccessible - * @param name The name of the plugin - * @note This method is trigger by the plugin manager when a plugin has been deactivated - */ - private deactivatePlugin; - /** - * Update error message when trying to call a method when not activated - * @param plugin The deactivated plugin to update the methods from - */ - private updateErrorHandler; - /** - * Register a plugin to the engine and update the manager - * @param plugin The plugin - */ - register(plugins: Plugin | Plugin[]): string | string[]; - /** Register the manager */ - private registerManager; - /** Remove plugin(s) from engine */ - remove(names: string | string[]): Promise | Promise; - /** - * Check is a name is already registered - * @param name Name of the plugin - */ - isRegistered(name: string): boolean; - } - -} -declare module 'dist/packages/engine/core/lib/library' { - import type { EventEmitter } from 'events'; - import type { Api, Profile, LibraryProfile, LocationProfile } from '@remixproject/plugin-utils'; - import { Plugin } from 'dist/packages/engine/core/lib/abstract'; - export type LibraryApi = { - [method in P['methods'][number]]: T['methods'][method]; - } & { - events?: EventEmitter; - } & { - render?(): Element; - }; type LibraryViewProfile = LocationProfile & LibraryProfile; - export function isViewLibrary(profile: any): profile is LibraryViewProfile; - export class LibraryPlugin extends Plugin { - protected library: LibraryApi; - profile: P; - private isView; - constructor(library: LibraryApi, profile: P); - activate(): Promise; - deactivate(): void; - /** Call a method from this plugin */ - protected callPluginMethod(key: string, payload: any[]): any; - } - export {}; - -} -declare module 'dist/packages/engine/core/lib/manager' { - import type { Profile } from '@remixproject/plugin-utils'; - import { Plugin } from 'dist/packages/engine/core/lib/abstract'; - export type BasePluginManager = { - getProfile(name: string): Promise; - updateProfile(profile: Partial): Promise; - activatePlugin(name: string): Promise; - deactivatePlugin(name: string): Promise; - isActive(name: string): Promise; - canCall(from: Profile, to: Profile, method: string): Promise; - toggleActive(name: string): any; - addProfile(profiles: Partial | Partial[]): any; - canActivatePlugin(from: Profile, to: Profile, method?: string): Promise; - canDeactivatePlugin(from: Profile, to: Profile): Promise; - } & Plugin; - interface ManagerProfile extends Profile { - name: 'manager'; - } - export class PluginManager extends Plugin implements BasePluginManager { - protected profiles: Record; - protected actives: string[]; - protected onPluginActivated?(profile: Profile): any; - protected onPluginDeactivated?(profile: Profile): any; - protected onProfileAdded?(profile: Profile): any; - constructor(profile?: ManagerProfile); - /** Return the name of the caller. If no request provided, this mean that the method has been called from the IDE so we use "manager" */ - get requestFrom(): string; - /** Run engine activation. Implemented by Engine */ - private engineActivatePlugin; - /** Run engine deactivation. Implemented by Engine */ - private engineDeactivatePlugin; - /** - * Get the profile if it's registered. - * @param name The name of the plugin - * @note This method can be overrided - */ - getProfile(name: string): Promise>; - /** Get all the profiles of the manager */ - getProfiles(): Profile[]; - /** Get all active profiles of the manager */ - getActiveProfiles(): Profile[]; - /** - * Update the profile of the plugin - * @param profile The Updated version of the plugin - * @note Only the caller plugin should be able to update its profile - */ - updateProfile(to: Partial): Promise; - /** - * Add a profile to the list of profile - * @param profile The profile to add - * @note This method should only be used by the engine - */ - addProfile(profiles: Profile | Profile[]): void | void[]; - /** - * Verify if a plugin is currently active - * @param name Name of the plugin - */ - isActive(name: string): Promise; - /** - * Check if caller can activate plugin and activate it if authorized - * @param name The name of the plugin to activate - */ - activatePlugin(names: string | string[]): Promise; - /** - * Check if caller can deactivate plugin and deactivate it if authorized - * @param name The name of the plugin to activate - */ - deactivatePlugin(names: string | string[]): Promise; - /** - * Activate or deactivate by bypassing permission - * @param name The name of the plugin to activate - * @note This method should ONLY be used by the IDE - */ - toggleActive(names: string | string[]): Promise; - /** - * Check if a plugin can activate another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @note This method should be overrided - */ - canActivatePlugin(from: Profile, to: Profile): Promise; - /** - * Check if a plugin can deactivate another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @note This method should be overrided - */ - canDeactivatePlugin(from: Profile, to: Profile): Promise; - /** - * Check if a plugin can call a method of another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @param method Method targetted by the caller - * @param message Method provided by the targetted method plugin - */ - canCall(from: Profile, to: Profile, method: string, message?: string): Promise; - /** - * Check if a plugin can update profile of another one - * @param from Profile of the caller plugin - * @param to Updates on the profile of the target plugin - * @note This method can be overrided - */ - canUpdateProfile(from: Profile, to: Partial): Promise; - } - export {}; - -} -declare module 'dist/packages/engine/core/index' { - export * from 'dist/packages/engine/core/lib/abstract'; - export * from 'dist/packages/engine/core/lib/connector'; - export * from 'dist/packages/engine/core/lib/engine'; - export * from 'dist/packages/engine/core/lib/library'; - export * from 'dist/packages/engine/core/lib/manager'; - -} -declare module 'packages/engine/core/src/lib/abstract' { - import type { Api, EventKey, EventParams, MethodKey, MethodParams, EventCallback, ApiMap, Profile, PluginRequest, PluginApi, PluginBase, IPluginService, PluginOptions } from '@remixproject/plugin-utils'; - import { PluginQueueItem } from '@remixproject/plugin-utils'; - export interface RequestParams { - name: string; - key: string; - payload: any[]; - } - export class Plugin implements PluginBase { - profile: Profile; - activateService: Record Promise>; - protected currentRequest: PluginRequest; - /** Give access to all the plugins registered by the engine */ - protected app: PluginApi; - protected options: PluginOptions; - protected queue: PluginQueueItem[]; - onRegistration?(): void; - onActivation?(): void; - onDeactivation?(): void; - constructor(profile: Profile); - get name(): string; - get methods(): Extract[]; - set methods(methods: Extract[]); - activate(): any | Promise; - deactivate(): any | Promise; - setOptions(options?: Partial): void; - /** Call a method on this plugin */ - protected callPluginMethod(key: string, args: any[]): any; - protected setCurrentRequest(request: PluginRequest): void; - protected letContinue(): void; - /** Add a request to the list of current requests */ - protected addRequest(request: PluginRequest, method: Profile['methods'][number], args: any[]): Promise; - protected cancelRequests(request: PluginRequest, method: Profile['methods'][number]): void; - /** - * Ask the plugin manager if current request can call a specific method - * @param method The method to call - * @param message An optional message to show to the user - */ - askUserPermission(method: MethodKey, message?: string): Promise; - /** - * Called by the engine when a plugin try to activate it - * @param from the profile of the plugin activating this plugin - * @param method method used to activate this plugin if any - */ - canActivate(from: Profile, method?: string): Promise; - /** - * Called by the engine when a plugin try to deactivate it - * @param from the profile of the plugin deactivating this plugin - */ - canDeactivate(from: Profile): Promise; - /** - * Create a service under the client node - * @param name The name of the service - * @param service The service - */ - createService>(name: string, service: S): Promise>; - /** - * Prepare a service to be lazy loaded - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): () => Promise>; - /** Listen on an event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen once an event from another plugin then remove event listener */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Stop listening on an event from another plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Call a method of another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise>; - /** Cancel a method of another plugin */ - cancel, Key extends MethodKey>(name: Name, key: Key): Promise>; - /** Emit an event */ - emit>(key: Key, ...payload: EventParams): void; - } - -} -declare module 'packages/engine/core/src/lib/connector' { - import type { ExternalProfile, Profile, Message, PluginOptions } from '@remixproject/plugin-utils'; - import { Plugin } from 'packages/engine/core/src/lib/abstract'; - /** List of available gateways for decentralised storage */ - export const defaultGateways: { - 'ipfs://': (url: any, name: any) => string; - 'swarm://': (url: any, name: any) => string; - }; - /** Transform the URL to use a gateway if decentralised storage is specified */ - export function transformUrl({ url, name }: Profile & ExternalProfile): any; - export interface PluginConnectorOptions extends PluginOptions { - /** Usally used to reload the plugin on changes */ - devMode?: boolean; - transformUrl?: (profile: Profile & ExternalProfile) => string; - engine?: string; - } - export abstract class PluginConnector extends Plugin { - protected loaded: boolean; - protected id: number; - protected pendingRequest: Record void>; - protected options: PluginConnectorOptions; - profile: Profile & ExternalProfile; - constructor(profile: Profile & ExternalProfile); - /** - * Send a message to the external plugin - * @param message the message passed to the plugin - */ - protected abstract send(message: Partial): void; - /** - * Open connection with the plugin - * @param url The transformed url the plugin should connect to - */ - protected abstract connect(url: string): any | Promise; - /** Close connection with the plugin */ - protected abstract disconnect(): any | Promise; - activate(): Promise; - deactivate(): Promise; - /** Set options for an external plugin */ - setOptions(options?: Partial): void; - /** Call a method from this plugin */ - protected callPluginMethod(key: string, payload?: any[]): Promise; - /** Perform handshake with the client if not loaded yet */ - protected handshake(): Promise; - /** - * React when a message comes from client - * @param message The message sent by the client - */ - protected getMessage(message: Message): Promise; - } - -} -declare module 'packages/api/src/lib/compiler/type/input' { - export interface CompilationInput { - /** Source code language */ - language: 'Solidity' | 'Vyper' | 'lll' | 'assembly' | 'yul'; - sources: SourcesInput; - settings?: CompilerSettings; - outputSelection?: CompilerOutputSelection; - } - export interface CondensedCompilationInput { - language: 'Solidity' | 'Vyper' | 'lll' | 'assembly' | 'yul'; - optimize: boolean; - /** e.g: 0.6.8+commit.0bbfe453 */ - version: string; - evmVersion?: 'istanbul' | 'petersburg' | 'constantinople' | 'byzantium' | 'spuriousDragon' | 'tangerineWhistle' | 'homestead'; - } - export interface SourceInputUrls { - /** Hash of the source file. It is used to verify the retrieved content imported via URLs */ - keccak256?: string; - /** - * URL(s) to the source file. - * URL(s) should be imported in this order and the result checked against the - * keccak256 hash (if available). If the hash doesn't match or none of the - * URL(s) result in success, an error should be raised. - */ - urls: string[]; - } - export interface SourceInputContent { - /** Hash of the source file. */ - keccak256?: string; - /** Literal contents of the source file */ - content: string; - } - export interface SourcesInput { - [contractName: string]: SourceInputContent | SourceInputUrls; - } - export interface CompilerSettings { - /** Sorted list of remappings */ - remappings?: string[]; - /** Optimizer settings */ - optimizer?: Partial; - /** Version of the EVM to compile for. Affects type checking and code generation */ - evmVersion: 'homestead' | 'tangerineWhistle' | 'spuriousDragon' | 'byzantium' | 'constantinople'; - /** Metadata settings */ - metadata?: CompilerMetadata; - /** Addresses of the libraries. If not all libraries are given here, it can result in unlinked objects whose output data is different. */ - libraries: CompilerLibraries; - } - export interface CompilerOptimizer { - /** disabled by default */ - enable: boolean; - /** - * Optimize for how many times you intend to run the code. - * Lower values will optimize more for initial deployment cost, higher values will optimize more for high-frequency usage. - */ - runs: number; - } - export interface CompilerMetadata { - /** Use only literal content and not URLs (false by default) */ - useLiteralContent: boolean; - } - /** - * The top level key is the the name of the source file where the library is used. - * If remappings are used, this source file should match the global path after remappings were applied. - * If this key is an empty string, that refers to a global level. - */ - export interface CompilerLibraries { - [contractName: string]: { - [libName: string]: string; - }; - } - export type OutputType = 'abi' | 'ast' | 'devdoc' | 'userdoc' | 'metadata' | 'ir' | 'evm.assembly' | 'evm.legacyAssembly' | 'evm.bytecode.object' | 'evm.bytecode.opcodes' | 'evm.bytecode.sourceMap' | 'evm.bytecode.linkReferences' | 'evm.deployedBytecode' | 'evm.methodIdentifiers' | 'evm.gasEstimates' | 'ewasm.wast' | 'ewasm.wasm'; - /** - * The following can be used to select desired outputs. - * If this field is omitted, then the compiler loads and does type checking, but will not generate any outputs apart from errors. - * The first level key is the file name and the second is the contract name, where empty contract name refers to the file itself, - * while the star refers to all of the contracts. - * Note that using a using evm, evm.bytecode, ewasm, etc. will select every - * target part of that output. Additionally, * can be used as a wildcard to request everything. - */ - export interface CompilerOutputSelection { - [file: string]: { - [contract: string]: OutputType[]; - }; - } - -} -declare module 'packages/api/src/lib/compiler/type/output' { - export interface CompilationFileSources { - [fileName: string]: { - keccak256?: string; - content: string; - urls?: string[]; - }; - } - export interface SourceWithTarget { - sources?: CompilationFileSources; - target?: string | null | undefined; - } - export interface CompilationResult { - /** not present if no errors/warnings were encountered */ - errors?: CompilationError[]; - /** This contains the file-level outputs. In can be limited/filtered by the outputSelection settings */ - sources: { - [contractName: string]: CompilationSource; - }; - /** This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings */ - contracts: { - /** If the language used has no contract names, this field should equal to an empty string. */ - [fileName: string]: { - [contract: string]: CompiledContract; - }; - }; - } - export interface lastCompilationResult { - data: CompilationResult | null; - source: SourceWithTarget | null | undefined; - } - export interface CompilationError { - /** Location within the source file */ - sourceLocation?: { - file: string; - start: number; - end: number; - }; - /** Error type */ - type: CompilationErrorType; - /** Component where the error originated, such as "general", "ewasm", etc. */ - component: 'general' | 'ewasm' | string; - severity: 'error' | 'warning'; - message: string; - /** the message formatted with source location */ - formattedMessage?: string; - } type CompilationErrorType = 'JSONError' | 'IOError' | 'ParserError' | 'DocstringParsingError' | 'SyntaxError' | 'DeclarationError' | 'TypeError' | 'UnimplementedFeatureError' | 'InternalCompilerError' | 'Exception' | 'CompilerError' | 'FatalError' | 'Warning'; - export interface CompilationSource { - /** Identifier of the source (used in source maps) */ - id: number; - /** The AST object */ - ast: AstNode; - /** The legacy AST object */ - legacyAST: AstNodeLegacy; - } - export interface AstNode { - absolutePath?: string; - exportedSymbols?: Object; - id: number; - nodeType: string; - nodes?: Array; - src: string; - literals?: Array; - file?: string; - scope?: number; - sourceUnit?: number; - symbolAliases?: Array; - [x: string]: any; - } - export interface AstNodeLegacy { - id: number; - name: string; - src: string; - children?: Array; - attributes?: AstNodeAtt; - } - export interface AstNodeAtt { - operator?: string; - string?: null; - type?: string; - value?: string; - constant?: boolean; - name?: string; - public?: boolean; - exportedSymbols?: Object; - argumentTypes?: null; - absolutePath?: string; - [x: string]: any; - } - export interface CompiledContract { - /** The Ethereum Contract ABI. If empty, it is represented as an empty array. */ - abi: ABIDescription[]; - metadata: string; - /** User documentation (natural specification) */ - userdoc: UserDocumentation; - /** Developer documentation (natural specification) */ - devdoc: DeveloperDocumentation; - /** Intermediate representation (string) */ - ir: string; - /** EVM-related outputs */ - evm: { - assembly: string; - legacyAssembly: {}; - /** Bytecode and related details. */ - bytecode: BytecodeObject; - deployedBytecode: BytecodeObject; - /** The list of function hashes */ - methodIdentifiers: { - [functionIdentifier: string]: string; - }; - gasEstimates: { - creation: { - codeDepositCost: string; - executionCost: 'infinite' | string; - totalCost: 'infinite' | string; - }; - external: { - [functionIdentifier: string]: string; - }; - internal: { - [functionIdentifier: string]: 'infinite' | string; - }; - }; - }; - /** eWASM related outputs */ - ewasm: { - /** S-expressions format */ - wast: string; - /** Binary format (hex string) */ - wasm: string; - }; - } - export type ABIDescription = FunctionDescription | EventDescription; - export interface FunctionDescription { - /** Type of the method. default is 'function' */ - type?: 'function' | 'constructor' | 'fallback'; - /** The name of the function. Constructor and fallback functions never have a name */ - name?: string; - /** List of parameters of the method. Fallback functions don’t have inputs. */ - inputs?: ABIParameter[]; - /** List of the output parameters for the method, if any */ - outputs?: ABIParameter[]; - /** State mutability of the method */ - stateMutability: 'pure' | 'view' | 'nonpayable' | 'payable'; - /** true if function accepts Ether, false otherwise. Default is false */ - payable?: boolean; - /** true if function is either pure or view, false otherwise. Default is false */ - constant?: boolean; - } - export interface EventDescription { - type: 'event'; - name: string; - inputs: ABIParameter & { - /** true if the field is part of the log’s topics, false if it one of the log’s data segment. */ - indexed: boolean; - }[]; - /** true if the event was declared as anonymous. */ - anonymous: boolean; - } - export interface ABIParameter { - /** The name of the parameter */ - name: string; - /** The canonical type of the parameter */ - type: ABITypeParameter; - /** Used for tuple types */ - components?: ABIParameter[]; - } - export type ABITypeParameter = 'uint' | 'uint[]' | 'int' | 'int[]' | 'address' | 'address[]' | 'bool' | 'bool[]' | 'fixed' | 'fixed[]' | 'ufixed' | 'ufixed[]' | 'bytes' | 'bytes[]' | 'function' | 'function[]' | 'tuple' | 'tuple[]' | string; - export interface UserDocumentation { - methods: UserMethodList; - notice: string; - } - export type UserMethodList = { - [functionIdentifier: string]: UserMethodDoc; - } & { - 'constructor'?: string; - }; - export interface UserMethodDoc { - notice: string; - } - export interface DeveloperDocumentation { - author: string; - title: string; - details: string; - methods: DevMethodList; - } - export interface DevMethodList { - [functionIdentifier: string]: DevMethodDoc; - } - export interface DevMethodDoc { - author: string; - details: string; - return: string; - returns: { - [param: string]: string; - }; - params: { - [param: string]: string; - }; - } - export interface BytecodeObject { - /** The bytecode as a hex string. */ - object: string; - /** Opcodes list */ - opcodes: string; - /** The source mapping as a string. See the source mapping definition. */ - sourceMap: string; - /** If given, this is an unlinked object. */ - linkReferences?: { - [contractName: string]: { - /** Byte offsets into the bytecode. */ - [library: string]: { - start: number; - length: number; - }[]; - }; - }; - } - export {}; - -} -declare module 'packages/api/src/lib/compiler/type/index' { - export * from 'packages/api/src/lib/compiler/type/input'; - export * from 'packages/api/src/lib/compiler/type/output'; - -} -declare module 'packages/api/src/lib/compiler/api' { - import { CompilationResult, CompilationFileSources, lastCompilationResult, CondensedCompilationInput, SourcesInput } from 'packages/api/src/lib/compiler/type'; - import { StatusEvents, Api } from '@remixproject/plugin-utils'; - export interface ICompiler extends Api { - events: { - compilationFinished: (fileName: string, source: CompilationFileSources, languageVersion: string, data: CompilationResult) => void; - } & StatusEvents; - methods: { - getCompilationResult(): lastCompilationResult; - compile(fileName: string): void; - setCompilerConfig(settings: CondensedCompilationInput): void; - compileWithParameters(targets: SourcesInput, settings: CondensedCompilationInput): lastCompilationResult; - }; - } - -} -declare module 'packages/api/src/lib/compiler/profile' { - import { ICompiler } from 'packages/api/src/lib/compiler/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const compilerProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/compiler/index' { - export * from 'packages/api/src/lib/compiler/api'; - export * from 'packages/api/src/lib/compiler/type'; - export * from 'packages/api/src/lib/compiler/profile'; - -} -declare module 'packages/api/src/lib/content-import/type' { - export interface ContentImport { - content: any; - cleanUrl: string; - type: 'github' | 'http' | 'https' | 'swarm' | 'ipfs'; - url: string; - } - -} -declare module 'packages/api/src/lib/content-import/api' { - import { ContentImport } from 'packages/api/src/lib/content-import/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IContentImport { - events: {} & StatusEvents; - methods: { - resolve(path: string): ContentImport; - resolveAndSave(url: string, targetPath: string): string; - }; - } - -} -declare module 'packages/api/src/lib/content-import/profile' { - import { IContentImport } from 'packages/api/src/lib/content-import/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const contentImportProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/content-import/index' { - export * from 'packages/api/src/lib/content-import/api'; - export * from 'packages/api/src/lib/content-import/type'; - export * from 'packages/api/src/lib/content-import/profile'; - -} -declare module 'packages/api/src/lib/editor/type' { - export interface HighlightPosition { - start: { - line: number; - column: number; - }; - end: { - line: number; - column: number; - }; - } - export interface HighLightOptions { - focus: boolean; - } - export interface Annotation { - row: number; - column: number; - text: string; - type: "error" | "warning" | "info"; - } - -} -declare module 'packages/api/src/lib/editor/api' { - import { HighlightPosition, Annotation } from 'packages/api/src/lib/editor/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - import { HighLightOptions } from '@remixproject/plugin-api'; - export interface IEditor { - events: StatusEvents; - methods: { - highlight(position: HighlightPosition, filePath: string, hexColor: string, opt?: HighLightOptions): void; - discardHighlight(): void; - discardHighlightAt(line: number, filePath: string): void; - addAnnotation(annotation: Annotation): void; - clearAnnotations(): void; - gotoLine(line: number, col: number): void; - }; - } - -} -declare module 'packages/api/src/lib/editor/profile' { - import { IEditor } from 'packages/api/src/lib/editor/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const editorProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/editor/index' { - export * from 'packages/api/src/lib/editor/type'; - export * from 'packages/api/src/lib/editor/api'; - export * from 'packages/api/src/lib/editor/profile'; - -} -declare module 'packages/api/src/lib/file-system/file-manager/type' { - export interface Folder { - [path: string]: { - isDirectory: boolean; - }; - } - -} -declare module 'packages/api/src/lib/file-system/file-manager/api' { - import { Folder } from 'packages/api/src/lib/file-system/file-manager/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IFileSystem { - events: { - currentFileChanged: (file: string) => void; - fileSaved: (file: string) => void; - fileAdded: (file: string) => void; - folderAdded: (file: string) => void; - fileRemoved: (file: string) => void; - fileClosed: (file: string) => void; - noFileSelected: () => void; - fileRenamed: (oldName: string, newName: string, isFolder: boolean) => void; - } & StatusEvents; - methods: { - /** Open the content of the file in the context (eg: Editor) */ - open(path: string): void; - /** Set the content of a specific file */ - writeFile(path: string, data: string): void; - /** Return the content of a specific file */ - readFile(path: string): string; - /** Change the path of a file */ - rename(oldPath: string, newPath: string): void; - /** Upsert a file with the content of the source file */ - copyFile(src: string, dest: string): void; - /** Create a directory */ - mkdir(path: string): void; - /** Get the list of files in the directory */ - readdir(path: string): string[]; - /** Removes a file or directory recursively */ - remove(path: string): void; - /** Get the name of the file currently focused if any */ - getCurrentFile(): string; - /** close all files */ - closeAllFiles(): void; - /** close a file */ - closeFile(): void; - /** @deprecated Use readdir */ - getFolder(path: string): Folder; - /** @deprecated Use readFile */ - getFile(path: string): string; - /** @deprecated Use writeFile */ - setFile(path: string, content: string): void; - /** @deprecated Use open */ - switchFile(path: string): void; - }; - } - -} -declare module 'packages/api/src/lib/file-system/file-manager/profile' { - import { IFileSystem } from 'packages/api/src/lib/file-system/file-manager/api'; - import { LocationProfile, Profile } from '@remixproject/plugin-utils'; - export const filSystemProfile: Profile & LocationProfile; - -} -declare module 'packages/api/src/lib/file-system/file-manager/index' { - export * from 'packages/api/src/lib/file-system/file-manager/api'; - export * from 'packages/api/src/lib/file-system/file-manager/type'; - export * from 'packages/api/src/lib/file-system/file-manager/profile'; - -} -declare module 'packages/api/src/lib/file-system/file-panel/type' { - export interface customAction { - id: string; - name: string; - type: customActionType[]; - path: string[]; - extension: string[]; - pattern: string[]; - sticky?: boolean; - label?: string; - } - export type customActionType = 'file' | 'folder'; - -} -declare module 'packages/api/src/lib/file-system/file-panel/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { customAction } from 'packages/api/src/lib/file-system/file-panel/type'; - export interface IFilePanel { - events: { - setWorkspace: (workspace: any) => void; - workspaceRenamed: (workspace: any) => void; - workspaceDeleted: (workspace: any) => void; - workspaceCreated: (workspace: any) => void; - customAction: (cmd: customAction) => void; - } & StatusEvents; - methods: { - getCurrentWorkspace(): { - name: string; - isLocalhost: boolean; - absolutePath: string; - }; - getWorkspaces(): string[]; - deleteWorkspace(name: string): void; - createWorkspace(name: string, isEmpty: boolean): void; - renameWorkspace(oldName: string, newName: string): void; - registerContextMenuItem(cmd: customAction): void; - }; - } - -} -declare module 'packages/api/src/lib/file-system/file-panel/profile' { - import { IFilePanel as IFilePanel } from 'packages/api/src/lib/file-system/file-panel/api'; - import { LocationProfile, Profile } from '@remixproject/plugin-utils'; - export const filePanelProfile: Profile & LocationProfile; - -} -declare module 'packages/api/src/lib/file-system/file-panel/index' { - export * from 'packages/api/src/lib/file-system/file-panel/api'; - export * from 'packages/api/src/lib/file-system/file-panel/profile'; - export * from 'packages/api/src/lib/file-system/file-panel/type'; - -} -declare module 'packages/api/src/lib/dgit/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IDgitSystem { - events: StatusEvents; - methods: { - init(): void; - add(cmd: any): string; - commit(cmd: any): string; - status(cmd: any): any[]; - rm(cmd: any): string; - log(cmd: any): any[]; - lsfiles(cmd: any): any[]; - readblob(cmd: any): { - oid: string; - blob: Uint8Array; - }; - resolveref(cmd: any): string; - branch(cmd: any): void; - checkout(cmd: any): void; - branches(): string[]; - currentbranch(): string; - push(cmd: any): string; - pull(cmd: any): void; - setIpfsConfig(config: any): boolean; - zip(): void; - setItem(name: string, content: string): void; - getItem(name: string): string; - import(cmd: any): void; - export(cmd: any): void; - remotes(): any[]; - addremote(cmd: any): void; - delremote(cmd: any): void; - clone(cmd: any): void; - localStorageUsed(): any; - }; - } - -} -declare module 'packages/api/src/lib/dgit/profile' { - import { IDgitSystem } from 'packages/api/src/lib/dgit/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const dGitProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/dgit/index' { - export * from 'packages/api/src/lib/dgit/api'; - export * from 'packages/api/src/lib/dgit/profile'; - -} -declare module 'packages/api/src/lib/git/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IGitSystem { - events: {} & StatusEvents; - methods: { - clone(url: string): string; - checkout(cmd: string): string; - init(): string; - add(cmd: string): string; - commit(cmd: string): string; - fetch(cmd: string): string; - pull(cmd: string): string; - push(cmd: string): string; - reset(cmd: string): string; - status(cmd: string): string; - remote(cmd: string): string; - log(): string; - }; - } - -} -declare module 'packages/api/src/lib/git/profile' { - import { IGitSystem } from 'packages/api/src/lib/git/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const gitProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/git/index' { - export * from 'packages/api/src/lib/git/api'; - export * from 'packages/api/src/lib/git/profile'; - -} -declare module 'packages/api/src/lib/network/type' { - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export interface CustomNetwork { - id?: string; - name: string; - url: string; - } - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export type NetworkProvider = 'vm' | 'injected' | 'web3'; - export type Network = { - id: '1'; - name: 'Main'; - } | { - id: '2'; - name: 'Morden (deprecated)'; - } | { - id: '3'; - name: 'Ropsten'; - } | { - id: '4'; - name: 'Rinkeby'; - } | { - id: '5'; - name: 'Goerli'; - } | { - id: '42'; - name: 'Kovan'; - }; - -} -declare module 'packages/api/src/lib/network/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { NetworkProvider, Network, CustomNetwork } from 'packages/api/src/lib/network/type'; - /** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ - export interface INetwork { - events: { - providerChanged: (provider: NetworkProvider) => void; - } & StatusEvents; - methods: { - getNetworkProvider(): NetworkProvider; - detectNetwork(): Network | Partial; - getEndpoint(): string; - addNetwork(network: CustomNetwork): void; - removeNetwork(name: string): void; - }; - } - -} -declare module 'packages/api/src/lib/network/profile' { - import { INetwork } from 'packages/api/src/lib/network/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const networkProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/network/index' { - export * from 'packages/api/src/lib/network/api'; - export * from 'packages/api/src/lib/network/type'; - export * from 'packages/api/src/lib/network/profile'; - -} -declare module 'packages/api/src/lib/plugin-manager/api' { - import { StatusEvents, Profile } from '@remixproject/plugin-utils'; - export interface IPluginManager { - events: { - profileUpdated(profile: Profile): void; - profileAdded(profile: Profile): void; - pluginDeactivated(profile: Profile): void; - pluginActivated(profile: Profile): void; - } & StatusEvents; - methods: { - getProfile(name: string): Promise; - updateProfile(profile: Partial): any; - activatePlugin(name: string): any; - deactivatePlugin(name: string): any; - isActive(name: string): boolean; - canCall(from: string, to: string, method: string, message?: string): any; - }; - } - -} -declare module 'packages/api/src/lib/plugin-manager/profile' { - import { IPluginManager } from 'packages/api/src/lib/plugin-manager/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const pluginManagerProfile: LibraryProfile & { - name: 'manager'; - }; - -} -declare module 'packages/api/src/lib/plugin-manager/index' { - export * from 'packages/api/src/lib/plugin-manager/api'; - export * from 'packages/api/src/lib/plugin-manager/profile'; - -} -declare module 'packages/api/src/lib/settings/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface ISettings { - events: {} & StatusEvents; - methods: { - getGithubAccessToken(): string; - }; - } - -} -declare module 'packages/api/src/lib/settings/profile' { - import { ISettings } from 'packages/api/src/lib/settings/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const settingsProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/settings/index' { - export * from 'packages/api/src/lib/settings/api'; - export * from 'packages/api/src/lib/settings/profile'; - -} -declare module 'packages/api/src/lib/theme/types' { - export interface Theme { - url?: string; - /** @deprecated Use brightness instead */ - quality?: 'dark' | 'light'; - brightness: 'dark' | 'light'; - colors: { - surface: string; - background: string; - foreground: string; - primary: string; - primaryContrast: string; - secondary?: string; - secondaryContrast?: string; - success?: string; - successContrast?: string; - warn: string; - warnContrast: string; - error: string; - errorContrast: string; - disabled: string; - }; - breakpoints: { - xs: number; - sm: number; - md: number; - lg: number; - xl: number; - }; - fontFamily: string; - /** A unit to multiply for margin & padding */ - space: number; - } - export interface ThemeUrls { - light: string; - dark: string; - } - -} -declare module 'packages/api/src/lib/theme/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { Theme } from 'packages/api/src/lib/theme/types'; - export interface ITheme { - events: { - themeChanged: (theme: Theme) => void; - } & StatusEvents; - methods: { - currentTheme(): Theme; - }; - } - -} -declare module 'packages/api/src/lib/theme/profile' { - import { ITheme } from 'packages/api/src/lib/theme/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const themeProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/theme/index' { - export * from 'packages/api/src/lib/theme/api'; - export * from 'packages/api/src/lib/theme/profile'; - export * from 'packages/api/src/lib/theme/types'; - -} -declare module 'packages/api/src/lib/udapp/type' { - export type RemixTxEvent = { - contractAddress: string; - data: string; - envMode: 'vm'; - executionCost: string; - from: string; - gas: string; - hash: string; - input: string; - logs: any[]; - returnValue: Uint8Array; - status: '0x01' | '0x00'; - transactionCost: string; - transactionHash: string; - value: string; - } | { - blockHash: string; - blockNumber: number; - envMod: 'injected' | 'web3'; - from: string; - gas: number; - gasPrice: { - c: number[]; - e: number; - s: number; - }; - hash: string; - input: string; - none: number; - r: string; - s: string; - v: string; - status: '0x01' | '0x00'; - to: string; - transactionCost: string; - transactionIndex: number; - value: { - c: number[]; - e: number; - s: number; - }; - }; - export interface RemixTx { - data: string; - from: string; - to?: string; - timestamp?: string; - gasLimit: string; - value: string; - useCall: boolean; - } - export interface RemixTxReceipt { - transactionHash: string; - status: 0 | 1; - gasUsed: string; - error: string; - return: string; - createdAddress?: string; - } - export interface VMAccount { - privateKey: string; - balance: string; - } - export interface UdappSettings { - selectedAccount: string; - selectedEnvMode: 'vm' | 'injected' | 'web3'; - networkEnvironment: string; - } - -} -declare module 'packages/api/src/lib/udapp/api' { - import { RemixTx, RemixTxReceipt, RemixTxEvent, VMAccount, UdappSettings } from 'packages/api/src/lib/udapp/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IUdapp { - events: { - newTransaction: (transaction: RemixTxEvent) => void; - } & StatusEvents; - methods: { - sendTransaction(tx: RemixTx): RemixTxReceipt; - getAccounts(): string[]; - createVMAccount(vmAccount: VMAccount): string; - getSettings(): UdappSettings; - setEnvironmentMode(env: 'vm' | 'injected' | 'web3'): void; - }; - } - -} -declare module 'packages/api/src/lib/udapp/profile' { - import { IUdapp } from 'packages/api/src/lib/udapp/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const udappProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/udapp/index' { - export * from 'packages/api/src/lib/udapp/api'; - export * from 'packages/api/src/lib/udapp/type'; - export * from 'packages/api/src/lib/udapp/profile'; - -} -declare module 'packages/api/src/lib/unit-testing/type' { - export interface UnitTestResult { - totalFailing: number; - totalPassing: number; - totalTime: number; - errors: UnitTestError[]; - } - export interface UnitTestError { - context: string; - value: string; - message: string; - } - -} -declare module 'packages/api/src/lib/unit-testing/api' { - import { UnitTestResult } from 'packages/api/src/lib/unit-testing/type'; - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IUnitTesting { - events: {} & StatusEvents; - methods: { - testFromPath(path: string): UnitTestResult; - testFromSource(sourceCode: string): UnitTestResult; - }; - } - -} -declare module 'packages/api/src/lib/unit-testing/profile' { - import { IUnitTesting } from 'packages/api/src/lib/unit-testing/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const unitTestProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/unit-testing/index' { - export * from 'packages/api/src/lib/unit-testing/api'; - export * from 'packages/api/src/lib/unit-testing/type'; - export * from 'packages/api/src/lib/unit-testing/profile'; - -} -declare module 'packages/api/src/lib/window/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IWindow { - events: {} & StatusEvents; - methods: { - /** Display an input window */ - prompt(message?: string): string; - /** Ask confirmation for an action */ - confirm(message: string): boolean; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): string | void; - }; - } - -} -declare module 'packages/api/src/lib/window/profile' { - import { IWindow } from 'packages/api/src/lib/window/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const windowProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/window/index' { - export * from 'packages/api/src/lib/window/api'; - export * from 'packages/api/src/lib/window/profile'; - -} -declare module 'packages/api/src/lib/vscextapi/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - export interface IVScodeExtAPI { - events: {} & StatusEvents; - methods: { - executeCommand(extension: string, command: string, payload?: any[]): any; - }; - } - -} -declare module 'packages/api/src/lib/vscextapi/profile' { - import { IVScodeExtAPI } from 'packages/api/src/lib/vscextapi/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const vscodeExtProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/vscextapi/index' { - export * from 'packages/api/src/lib/vscextapi/api'; - export * from 'packages/api/src/lib/vscextapi/profile'; - -} -declare module 'packages/api/src/lib/terminal/type' { - export type TerminalMessage = { - value: any; - type: 'html' | 'log' | 'info' | 'warn' | 'error'; - }; - -} -declare module 'packages/api/src/lib/terminal/api' { - import { StatusEvents } from '@remixproject/plugin-utils'; - import { TerminalMessage } from 'packages/api/src/lib/terminal/type'; - export interface ITerminal { - events: {} & StatusEvents; - methods: { - log(message: TerminalMessage): void; - }; - } - -} -declare module 'packages/api/src/lib/terminal/profile' { - import { ITerminal } from 'packages/api/src/lib/terminal/api'; - import { LibraryProfile } from '@remixproject/plugin-utils'; - export const terminalProfile: LibraryProfile; - -} -declare module 'packages/api/src/lib/terminal/index' { - export * from 'packages/api/src/lib/terminal/api'; - export * from 'packages/api/src/lib/terminal/type'; - export * from 'packages/api/src/lib/terminal/profile'; - -} -declare module 'packages/api/src/lib/remix-profile' { - import { ProfileMap } from '@remixproject/plugin-utils'; - import { ICompiler } from 'packages/api/src/lib/compiler'; - import { IFileSystem } from 'packages/api/src/lib/file-system/file-manager'; - import { IEditor } from 'packages/api/src/lib/editor'; - import { INetwork } from 'packages/api/src/lib/network'; - import { IUdapp } from 'packages/api/src/lib/udapp'; - import { ITheme } from 'packages/api/src/lib/theme'; - import { IUnitTesting } from 'packages/api/src/lib/unit-testing'; - import { IContentImport } from 'packages/api/src/lib/content-import'; - import { ISettings } from 'packages/api/src/lib/settings'; - import { IVScodeExtAPI } from 'packages/api/src/lib/vscextapi'; - import { IPluginManager } from 'packages/api/src/lib/plugin-manager'; - import { IFilePanel } from 'packages/api/src/lib/file-system/file-panel'; - import { IDgitSystem } from 'packages/api/src/lib/dgit'; - import { ITerminal } from 'packages/api/src/lib/terminal'; - export interface IRemixApi { - manager: IPluginManager; - solidity: ICompiler; - fileManager: IFileSystem; - filePanel: IFilePanel; - dGitProvider: IDgitSystem; - solidityUnitTesting: IUnitTesting; - editor: IEditor; - network: INetwork; - udapp: IUdapp; - contentImport: IContentImport; - settings: ISettings; - theme: ITheme; - vscodeExtAPI: IVScodeExtAPI; - terminal: ITerminal; - } - export type RemixApi = Readonly; - /** @deprecated Use remixProfiles instead. Will be remove in next version */ - export const remixApi: ProfileMap; - /** Profiles of all the remix's Native Plugins */ - export const remixProfiles: ProfileMap; - -} -declare module 'packages/api/src/lib/standard-profile' { - import { ProfileMap } from '@remixproject/plugin-utils'; - import { ICompiler } from 'packages/api/src/lib/compiler'; - import { IFileSystem } from 'packages/api/src/lib/file-system/file-manager'; - import { IEditor } from 'packages/api/src/lib/editor'; - import { INetwork } from 'packages/api/src/lib/network'; - import { IUdapp } from 'packages/api/src/lib/udapp'; - import { IPluginManager } from 'packages/api/src/lib/plugin-manager'; - export interface IStandardApi { - manager: IPluginManager; - solidity: ICompiler; - fileManager: IFileSystem; - editor: IEditor; - network: INetwork; - udapp: IUdapp; - } - export type StandardApi = Readonly; - /** Profiles of all the standard's Native Plugins */ - export const standardProfiles: ProfileMap; - -} -declare module 'packages/api/src/index' { - export * from 'packages/api/src/lib/compiler'; - export * from 'packages/api/src/lib/content-import'; - export * from 'packages/api/src/lib/editor'; - export * from 'packages/api/src/lib/file-system/file-manager'; - export * from 'packages/api/src/lib/file-system/file-panel'; - export * from 'packages/api/src/lib/dgit'; - export * from 'packages/api/src/lib/git'; - export * from 'packages/api/src/lib/network'; - export * from 'packages/api/src/lib/plugin-manager'; - export * from 'packages/api/src/lib/settings'; - export * from 'packages/api/src/lib/theme'; - export * from 'packages/api/src/lib/udapp'; - export * from 'packages/api/src/lib/unit-testing'; - export * from 'packages/api/src/lib/window'; - export * from 'packages/api/src/lib/remix-profile'; - export * from 'packages/api/src/lib/standard-profile'; - -} -declare module 'packages/engine/core/src/lib/manager' { - import type { Profile } from '@remixproject/plugin-utils'; - import { Plugin } from 'packages/engine/core/src/lib/abstract'; - export type BasePluginManager = { - getProfile(name: string): Promise; - updateProfile(profile: Partial): Promise; - activatePlugin(name: string): Promise; - deactivatePlugin(name: string): Promise; - isActive(name: string): Promise; - canCall(from: Profile, to: Profile, method: string): Promise; - toggleActive(name: string): any; - addProfile(profiles: Partial | Partial[]): any; - canActivatePlugin(from: Profile, to: Profile, method?: string): Promise; - canDeactivatePlugin(from: Profile, to: Profile): Promise; - } & Plugin; - interface ManagerProfile extends Profile { - name: 'manager'; - } - export class PluginManager extends Plugin implements BasePluginManager { - protected profiles: Record; - protected actives: string[]; - protected onPluginActivated?(profile: Profile): any; - protected onPluginDeactivated?(profile: Profile): any; - protected onProfileAdded?(profile: Profile): any; - constructor(profile?: ManagerProfile); - /** Return the name of the caller. If no request provided, this mean that the method has been called from the IDE so we use "manager" */ - get requestFrom(): string; - /** Run engine activation. Implemented by Engine */ - private engineActivatePlugin; - /** Run engine deactivation. Implemented by Engine */ - private engineDeactivatePlugin; - /** - * Get the profile if it's registered. - * @param name The name of the plugin - * @note This method can be overrided - */ - getProfile(name: string): Promise>; - /** Get all the profiles of the manager */ - getProfiles(): Profile[]; - /** Get all active profiles of the manager */ - getActiveProfiles(): Profile[]; - /** - * Update the profile of the plugin - * @param profile The Updated version of the plugin - * @note Only the caller plugin should be able to update its profile - */ - updateProfile(to: Partial): Promise; - /** - * Add a profile to the list of profile - * @param profile The profile to add - * @note This method should only be used by the engine - */ - addProfile(profiles: Profile | Profile[]): void | void[]; - /** - * Verify if a plugin is currently active - * @param name Name of the plugin - */ - isActive(name: string): Promise; - /** - * Check if caller can activate plugin and activate it if authorized - * @param name The name of the plugin to activate - */ - activatePlugin(names: string | string[]): Promise; - /** - * Check if caller can deactivate plugin and deactivate it if authorized - * @param name The name of the plugin to activate - */ - deactivatePlugin(names: string | string[]): Promise; - /** - * Activate or deactivate by bypassing permission - * @param name The name of the plugin to activate - * @note This method should ONLY be used by the IDE - */ - toggleActive(names: string | string[]): Promise; - /** - * Check if a plugin can activate another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @note This method should be overrided - */ - canActivatePlugin(from: Profile, to: Profile): Promise; - /** - * Check if a plugin can deactivate another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @note This method should be overrided - */ - canDeactivatePlugin(from: Profile, to: Profile): Promise; - /** - * Check if a plugin can call a method of another - * @param from Profile of the caller plugin - * @param to Profile of the target plugin - * @param method Method targetted by the caller - * @param message Method provided by the targetted method plugin - */ - canCall(from: Profile, to: Profile, method: string, message?: string): Promise; - /** - * Check if a plugin can update profile of another one - * @param from Profile of the caller plugin - * @param to Updates on the profile of the target plugin - * @note This method can be overrided - */ - canUpdateProfile(from: Profile, to: Partial): Promise; - } - export {}; - -} -declare module 'packages/engine/core/src/lib/engine' { - import type { Profile, PluginOptions } from '@remixproject/plugin-utils'; - import { Plugin } from 'packages/engine/core/src/lib/abstract'; - export class Engine { - private plugins; - private events; - private listeners; - private eventMemory; - private manager; - onRegistration?(plugin: Plugin): void; - /** Update the options of the plugin when being registered */ - setPluginOption?(profile: Profile): PluginOptions; - /** - * Broadcast an event to the plugin listening - * @param emitter Plugin name that emits the event - * @param event The name of the event - * @param payload The content of the event - */ - private broadcast; - /** - * Start listening on an event from another plugin - * @param listener The name of the plugin that listen on the event - * @param emitter The name of the plugin that emit the event - * @param event The name of the event - * @param cb Callback function to trigger when the event is trigger - */ - private addListener; - /** - * Remove an event from the list of a listener's events - * @param listener The name of the plugin that was listening on the event - * @param emitter The name of the plugin that emitted the event - * @param event The name of the event - */ - private removeListener; - /** - * Create a listener that listen only once on an event - * @param listener The name of the plugin that listen on the event - * @param emitter The name of the plugin that emitted the event - * @param event The name of the event - * @param cb Callback function to trigger when event is triggered - */ - private listenOnce; - /** - * Call a method of a plugin from another - * @param caller The name of the plugin that calls the method - * @param path The path of the plugin that manages the method - * @param method The name of the method - * @param payload The argument to pass to the method - */ - private callMethod; - /** - * Cancels calls from a plugin to another - * @param caller The name of the plugin that calls the method - * @param path The path of the plugin that manages the method - * @param method The name of the method to be cancelled, if is empty cancels all calls from plugin - */ - private cancelMethod; - /** - * Create an object to easily access any registered plugin - * @param name Name of the caller plugin - * @note This method creates a snapshot at the time of activation - */ - private createApp; - /** - * Activate a plugin by making its method and event available - * @param name The name of the plugin - * @note This method is trigger by the plugin manager when a plugin has been activated - */ - private activatePlugin; - /** - * Deactivate a plugin by removing all its event listeners and making it inaccessible - * @param name The name of the plugin - * @note This method is trigger by the plugin manager when a plugin has been deactivated - */ - private deactivatePlugin; - /** - * Update error message when trying to call a method when not activated - * @param plugin The deactivated plugin to update the methods from - */ - private updateErrorHandler; - /** - * Register a plugin to the engine and update the manager - * @param plugin The plugin - */ - register(plugins: Plugin | Plugin[]): string | string[]; - /** Register the manager */ - private registerManager; - /** Remove plugin(s) from engine */ - remove(names: string | string[]): Promise | Promise; - /** - * Check is a name is already registered - * @param name Name of the plugin - */ - isRegistered(name: string): boolean; - } - -} -declare module 'packages/engine/core/src/lib/library' { - /// - import type { EventEmitter } from 'events'; - import type { Api, Profile, LibraryProfile, LocationProfile } from '@remixproject/plugin-utils'; - import { Plugin } from 'packages/engine/core/src/lib/abstract'; - export type LibraryApi = { - [method in P['methods'][number]]: T['methods'][method]; - } & { - events?: EventEmitter; - } & { - render?(): Element; - }; type LibraryViewProfile = LocationProfile & LibraryProfile; - export function isViewLibrary(profile: any): profile is LibraryViewProfile; - export class LibraryPlugin extends Plugin { - protected library: LibraryApi; - profile: P; - private isView; - constructor(library: LibraryApi, profile: P); - activate(): Promise; - deactivate(): void; - /** Call a method from this plugin */ - protected callPluginMethod(key: string, payload: any[]): any; - } - export {}; - -} -declare module 'packages/engine/core/src/index' { - export * from 'packages/engine/core/src/lib/abstract'; - export * from 'packages/engine/core/src/lib/connector'; - export * from 'packages/engine/core/src/lib/engine'; - export * from 'packages/engine/core/src/lib/library'; - export * from 'packages/engine/core/src/lib/manager'; - -} -declare module 'dist/packages/engine/node/lib/child-process' { - /// - import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { PluginConnector } from '@remixproject/engine'; - import { ChildProcess } from 'child_process'; - export class ChildProcessPlugin extends PluginConnector { - private readonly listener; - process: ChildProcess; - constructor(profile: Profile & ExternalProfile); - protected send(message: Partial): void; - protected connect(url: string): void; - protected disconnect(): void; - } - -} -declare module 'dist/packages/engine/node/index' { - export * from 'dist/packages/engine/node/lib/child-process'; - -} -declare module 'dist/packages/engine/theia/lib/engine-theia' { - export function engineTheia(): string; - -} -declare module 'dist/packages/engine/theia/index' { - export * from 'dist/packages/engine/theia/lib/engine-theia'; - -} -declare module 'dist/packages/engine/vscode/lib/command' { - import { Plugin, PluginOptions } from '@remixproject/engine'; - import { Profile } from '@remixproject/plugin-utils'; - import { Disposable } from 'vscode'; - export const transformCmd: (name: string, method: string) => string; - export interface CommandOptions extends PluginOptions { - transformCmd: (name: string, method: string) => string; - } - /** - * Connect methods of the plugins with a command depending on the transformCmd function pass as option - */ - export class CommandPlugin extends Plugin { - subscriptions: Disposable[]; - options: CommandOptions; - constructor(profile: Profile); - setOptions(options: Partial): void; - activate(): void; - deactivate(): void; - } - -} -declare module 'dist/packages/engine/vscode/lib/dynamic-list' { - import { Plugin, PluginOptions } from '@remixproject/engine'; - import { TreeDataProvider, EventEmitter, TreeView, TreeItem } from 'vscode'; type ID = string | number; - export class Item extends TreeItem { - private item; - constructor(label: string, pluginName: string, item: I); - } - export class List implements TreeDataProvider { - private name; - private list; - private options; - render: EventEmitter; - onDidChangeTreeData: import("vscode").Event; - constructor(name: string, initial?: I[]); - setOptions(options: Partial): void; - reset(list: I[]): void; - getParent(): any; - getTreeItem(element: I): Item; - getChildren(): I[]; - } - export interface ListOptions { - idKey: string; - labelKey: string; - } - export type ListPluginOptions = PluginOptions & ListOptions; - export class DynamicListPlugin = List> extends Plugin { - private listeners; - protected options: ListPluginOptions; - protected treeView: TreeView; - protected entities: Record; - protected selected: ID; - list: T; - constructor(name: string, options?: Partial); - setOptions(options: Partial): void; - activate(): void; - deactivate(): void; - getIds(): string[]; - getItem(id: ID): I; - getAll(): I[]; - /** Select on element of the list */ - select(idOrItem: ID | I): void; - /** Reset the entire list */ - reset(items: I[]): void; - /** Add a new item to the list */ - add(item: I): void; - /** Remove one item from the list */ - remove(id: ID): void; - /** Update one item in the list */ - update(id: ID, item: Partial): void; - } - export {}; - -} -declare module 'dist/packages/engine/vscode/lib/extension' { - import { PluginConnector } from '@remixproject/engine'; - import { Profile, ExternalProfile, Message } from '@remixproject/plugin-utils'; - export class ExtensionPlugin extends PluginConnector { - private extension; - private connector; - constructor(profile: Profile & ExternalProfile); - protected send(message: Partial): void; - protected connect(url: string): Promise; - protected disconnect(): void; - } - -} -declare module 'dist/packages/engine/vscode/lib/theme' { - import { Plugin, PluginOptions } from '@remixproject/engine'; - import { API } from '@remixproject/plugin-utils'; - import { ITheme, Theme, ThemeUrls } from '@remixproject/plugin-api'; - import { Disposable, ColorTheme } from 'vscode'; - export interface ThemeOptions extends PluginOptions { - urls?: Partial; - } - export function getVscodeTheme(color: ColorTheme, urls?: Partial): Theme; - export class ThemePlugin extends Plugin implements API { - protected getTheme: typeof getVscodeTheme; - protected options: ThemeOptions; - listener: Disposable; - constructor(options?: Partial); - setOptions(options: Partial): void; - onActivation(): void; - onDeactivation(): void; - currentTheme(): Theme; - } - -} -declare module 'dist/packages/engine/vscode/lib/webview' { - import { PluginConnector, PluginConnectorOptions } from '@remixproject/engine'; - import { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { ExtensionContext, ViewColumn, WebviewPanel } from 'vscode'; - interface WebviewOptions extends PluginConnectorOptions { - /** Extension Path */ - context: ExtensionContext; - relativeTo?: 'workspace' | 'extension'; - column?: ViewColumn; - devMode?: boolean; - } - export class WebviewPlugin extends PluginConnector { - private listeners; - panel?: WebviewPanel; - options: WebviewOptions; - constructor(profile: Profile & ExternalProfile, options: WebviewOptions); - setOptions(options: Partial): void; - protected send(message: Partial): void; - protected connect(url: string): Promise; - getMessage(message: Message): Promise; - protected disconnect(): void; - } - /** Create a webview */ - export function createWebview(profile: Profile, url: string, options: WebviewOptions): Promise; - export {}; - -} -declare module 'dist/packages/engine/vscode/lib/window' { - import { Plugin, PluginOptions } from '@remixproject/engine'; - import { Profile } from '@remixproject/plugin-utils'; - import { QuickPickOptions, InputBoxOptions } from 'vscode'; - export const windowProfile: Profile; - interface IWindowPlugin { - /** Display an input window */ - prompt(): Thenable; - /** Display a select window */ - select(options: string[]): Thenable; - /** Display a select window with local file system: can only select a file */ - selectFile(): Thenable; - /** Display a select window with local file system: can only select a folder */ - selectFolder(): Thenable; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): Thenable; - /** Display a warning message with actions button. Returned the button clicked if any */ - warning(message: string, actions?: string[]): Thenable; - /** Display an error message with actions button. Returned the button clicked if any */ - error(message: string, actions?: string[]): Thenable; - } - export class WindowPlugin extends Plugin implements IWindowPlugin { - constructor(options?: PluginOptions); - prompt(options?: InputBoxOptions): Thenable; - select(items: string[], options?: QuickPickOptions): Thenable; - selectFile(): Thenable; - selectFolder(): Thenable; - alert(message: string, actions?: string[]): Thenable; - error(message: string, actions?: string[]): Thenable; - warning(message: string, actions?: string[]): Thenable; - } - export {}; - -} -declare module 'dist/packages/engine/vscode/lib/filemanager' { - import { IFileSystem } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin } from 'dist/packages/engine/vscode/lib/command'; - export class FileManagerPlugin extends CommandPlugin implements MethodApi { - constructor(); - /** Open the content of the file in the context (eg: Editor) */ - open(path: string): Promise; - /** Set the content of a specific file */ - writeFile(path: string, data: string): Promise; - /** Return the content of a specific file */ - readFile(path: string): Promise; - /** Remove a file */ - remove(path: string): Promise; - /** Change the path of a file */ - rename(oldPath: string, newPath: string): Promise; - /** Upsert a file with the content of the source file */ - copyFile(src: string, dest: string): Promise; - /** Create a directory */ - mkdir(path: string): Promise; - /** Get the list of files in the directory */ - readdir(path: string): Promise; - getCurrentFile(): Promise; - getFile: (path: string) => Promise; - setFile: (path: string, data: string) => Promise; - switchFile: (path: string) => Promise; - /** @deprecated Use readdir instead */ - getFolder(path: string): Promise; - } - -} -declare module 'dist/packages/engine/vscode/lib/editor' { - import { IEditor, Annotation, HighlightPosition } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin, CommandOptions } from 'dist/packages/engine/vscode/lib/command'; - export interface EditorOptions extends CommandOptions { - language: string; - } - export class EditorPlugin extends CommandPlugin implements MethodApi { - private decoration; - private decorations; - private diagnosticCollection; - options: EditorOptions; - constructor(options: EditorOptions); - setOptions(options: EditorOptions): void; - onActivation(): void; - onDeactivation(): void; - highlight(position: HighlightPosition, filePath: string, themeColor: string): Promise; - discardDecorations(): Promise; - discardHighlight(): Promise; - /** - * Alisas of discardHighlight - * Required to match the standard interface of editor - */ - discardHighlightAt(): Promise; - addAnnotation(annotation: Annotation, filePath?: string): Promise; - clearAnnotations(): Promise; - } - -} -declare module 'dist/packages/engine/vscode/lib/terminal' { - import { Plugin } from '@remixproject/engine'; - export interface TerminalOptions { - name?: string; - open: boolean; - } - export class TerminalPlugin extends Plugin { - private terminals; - private outputs; - private activeOutput; - constructor(); - onDeactivation(): void; - private get active(); - private getTerminal; - private getOutput; - /** Open specific terminal (doesn't work with output) */ - open(name?: string): string; - /** Kill a terminal */ - kill(name?: string): void; - /** Write on the current terminal and execute command */ - exec(command: string, options?: Partial): void; - /** Write on the current output */ - write(text: string, options?: Partial): void; - } - -} -declare module 'dist/packages/engine/vscode/lib/contentimport' { - import { IContentImport } from '@remixproject/plugin-api'; - import { ContentImport } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin } from 'dist/packages/engine/vscode/lib/command'; - import { RemixURLResolver } from '@remix-project/remix-url-resolver'; - export class ContentImportPlugin extends CommandPlugin implements MethodApi { - urlResolver: RemixURLResolver; - constructor(); - resolve(path: string): Promise; - resolveAndSave(url: string, targetPath: string): Promise; - } - -} -declare module 'dist/packages/engine/vscode/lib/appmanager' { - import { PluginManager } from '@remixproject/engine'; - export class VscodeAppManager extends PluginManager { - pluginsDirectory: string; - target: string; - constructor(); - registeredPluginData(): Promise; - } - -} -declare module 'dist/packages/engine/vscode/index' { - export * from 'dist/packages/engine/vscode/lib/command'; - export * from 'dist/packages/engine/vscode/lib/dynamic-list'; - export * from 'dist/packages/engine/vscode/lib/extension'; - export * from 'dist/packages/engine/vscode/lib/theme'; - export * from 'dist/packages/engine/vscode/lib/webview'; - export * from 'dist/packages/engine/vscode/lib/window'; - export * from 'dist/packages/engine/vscode/lib/filemanager'; - export * from 'dist/packages/engine/vscode/lib/editor'; - export * from 'dist/packages/engine/vscode/lib/terminal'; - export * from 'dist/packages/engine/vscode/lib/contentimport'; - export * from 'dist/packages/engine/vscode/lib/appmanager'; - -} -declare module 'dist/packages/engine/vscode/util/editor' { - import { TextEditor } from 'vscode'; - export function getOpenedTextEditor(): TextEditor; - export function getTextEditorWithDocumentType(type: string): TextEditor; - -} -declare module 'dist/packages/engine/vscode/util/path' { - export function absolutePath(path: string): string; - export function relativePath(path: any): any; - -} -declare module 'dist/packages/engine/web/lib/iframe' { - import type { Message, Profile, ExternalProfile, LocationProfile } from '@remixproject/plugin-utils'; - import { PluginConnector } from '@remixproject/engine'; - export type IframeProfile = Profile & LocationProfile & ExternalProfile; - /** - * Connect an Iframe client to the engine. - * @dev This implements the ViewPlugin as it cannot extends two class. Maybe use a mixin at some point - */ - export class IframePlugin extends PluginConnector { - profile: IframeProfile; - private readonly listener; - private iframe; - private origin; - private source; - private url; - constructor(profile: IframeProfile); - /** Implement "activate" of the ViewPlugin */ - connect(url: string): Promise; - /** Implement "deactivate" of the ViewPlugin */ - disconnect(): Promise; - /** Get message from the iframe */ - private getEvent; - /** - * Post a message to the iframe of this plugin - * @param message The message to post - */ - protected send(message: Partial): void; - /** Create and return the iframe */ - render(): HTMLIFrameElement; - } - -} -declare module 'dist/packages/engine/web/lib/ws' { - import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { PluginConnector, PluginConnectorOptions } from '@remixproject/engine'; - export interface WebsocketOptions extends PluginConnectorOptions { - /** Time (in ms) to wait before reconnection after connection closed */ - reconnectDelay: number; - } - export class WebsocketPlugin extends PluginConnector { - private account; - private readonly listeners; - private url; - protected socket: WebSocket; - protected options: WebsocketOptions; - constructor(profile: Profile & ExternalProfile, options?: Partial); - private getEvent; - /** Try to reconnect to net websocket if closes */ - private onclose; - /** Open a connection with the server (also used for reconnection) */ - protected open(): void; - protected send(message: Partial): void; - protected connect(url: string): void; - protected disconnect(): void; - } - -} -declare module 'dist/packages/engine/web/lib/theme' { - import { Plugin } from '@remixproject/engine'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { ITheme, Theme } from '@remixproject/plugin-api'; type DeepPartial = { - [P in keyof T]?: DeepPartial; - }; - /** - * Utils function to create a theme with default value - * Default values are taken from material design with colors - * - primary: indigo - * - secondary: pink - * - warn: orange - * - error: red - */ - export function createTheme(params?: DeepPartial): Theme; - export class ThemePlugin extends Plugin implements MethodApi { - protected getTheme: typeof createTheme; - protected theme: Theme; - constructor(); - /** Internal API to set the current theme */ - setTheme(theme: DeepPartial): void; - /** External API to get the current theme */ - currentTheme(): Promise; - } - export {}; - -} -declare module 'dist/packages/engine/web/lib/window' { - import { Plugin, PluginOptions } from '@remixproject/engine'; - import { IWindow } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - export class WindowPlugin extends Plugin implements MethodApi { - constructor(options?: PluginOptions); - /** Display an input window */ - prompt(message?: string): Promise; - /** Ask confirmation for an action */ - confirm(message: string): Promise; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): Promise; - } - -} -declare module 'dist/packages/engine/web/lib/web-worker' { - import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { PluginConnector, PluginOptions } from '@remixproject/engine'; type WebworkerOptions = WorkerOptions & PluginOptions; - export class WebWorkerPlugin extends PluginConnector { - profile: Profile & ExternalProfile; - private worker; - protected options: WebworkerOptions; - constructor(profile: Profile & ExternalProfile, options?: WebworkerOptions); - setOptions(options: Partial): void; - connect(url: string): Promise; - disconnect(): void; - /** Get message from the iframe */ - private getEvent; - /** - * Post a message to the webview of this plugin - * @param message The message to post - */ - protected send(message: Partial): void; - } - export {}; - -} -declare module 'dist/packages/engine/web/lib/host' { - import type { Profile } from '@remixproject/plugin-utils'; - import { Plugin } from '@remixproject/engine'; - export abstract class HostPlugin extends Plugin { - constructor(profile: Profile); - /** Give the name of the current focus plugin */ - abstract currentFocus(): string; - /** Display the view inside the host */ - abstract focus(name: string): void; - /** Add the view of a plugin into the DOM */ - abstract addView(profile: Profile, view: Element): void; - /** Remove the plugin from the view from the DOM */ - abstract removeView(profile: Profile): void; - } - -} -declare module 'dist/packages/engine/web/lib/view' { - import type { Profile, LocationProfile } from '@remixproject/plugin-utils'; - import { Plugin } from '@remixproject/engine'; - export function isView

(profile: Profile): profile is (ViewProfile & P); - export type ViewProfile = Profile & LocationProfile; - export abstract class ViewPlugin extends Plugin { - profile: ViewProfile; - abstract render(): Element; - constructor(profile: ViewProfile); - activate(): Promise; - deactivate(): void; - } - -} -declare module 'dist/packages/engine/web/index' { - export * from 'dist/packages/engine/web/lib/iframe'; - export * from 'dist/packages/engine/web/lib/ws'; - export * from 'dist/packages/engine/web/lib/theme'; - export * from 'dist/packages/engine/web/lib/window'; - export * from 'dist/packages/engine/web/lib/web-worker'; - export * from 'dist/packages/engine/web/lib/host'; - export * from 'dist/packages/engine/web/lib/view'; - -} -declare module 'packages/plugin/core/src/lib/client' { - /// - import { EventEmitter } from 'events'; - import { RemixApi } from 'packages/api/src/lib/remix-profile'; - import { GetPluginService, Profile } from 'dist/packages/utils/lib/types/service'; - import type { Api, PluginRequest, ApiMap, EventKey, EventCallback, MethodParams, MethodKey, EventParams, ProfileMap, IPluginService, PluginBase } from 'dist/packages/utils/lib/types/plugin'; - export interface PluginDevMode { - /** Port for localhost */ - port: number | string; - origins: string | string[]; - } - /** Options of the plugin client */ - export interface PluginOptions { - customTheme: boolean; - /** define a set of custom apis to implements on the client */ - customApi: ProfileMap; - /** - * Allow a set of origins - * You can either a list of origin or a url with a link of origins - */ - allowOrigins: string | string[]; - /** - * options only available for dev mode - * @deprecated use allowOrigins instead if you want to limit the parent origin - */ - devMode: Partial; - } - export const defaultOptions: Partial>; - /** Throw an error if client try to send a message before connection */ - export function handleConnectionError(devMode?: Partial): void; - export class PluginClient implements PluginBase { - private id; - isLoaded: boolean; - events: EventEmitter; - currentRequest: PluginRequest; - options: PluginOptions; - name: string; - methods: string[]; - activateService: Record Promise>; - onActivation?(): void; - constructor(options?: Partial>); - onload(cb?: () => void): Promise; - /** - * Ask the plugin manager if current request can call a specific method - * @param method The method to call - * @param message An optional message to show to the user - */ - askUserPermission(method: MethodKey, message?: string): Promise; - /** - * Called before deactivating the plugin - * @param from profile of plugin asking to deactivate - * @note PluginManager will always be able to deactivate - */ - canDeactivate(from: Profile): boolean; - /** Make a call to another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise>; - cancel, Key extends MethodKey>(name: Name, key?: Key | ''): void; - /** Listen on event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen once on event from another plugin */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Remove all listeners on an event from an external plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Expose an event for the IDE */ - emit>(key: Key, ...payload: EventParams): void; - /** - * Create a service under the client node - * @param name The name of the service - * @param service The service - */ - createService, Service extends IPluginService>(name: string, service: Service): Promise>; - /** - * Prepare a service to be lazy loaded - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): () => Promise>; - } - -} -declare module 'packages/plugin/core/src/lib/api' { - import type { Profile, Api, CustomApi, ProfileMap, ApiMapFromProfileMap, PluginApi, ApiMap } from '@remixproject/plugin-utils'; - import { PluginClient } from 'packages/plugin/core/src/lib/client'; - /** - * Create an Api - * @param profile The profile of the api - */ - export function createApi(client: PluginClient, profile: Profile): CustomApi; - /** - * Transform a list of profile into a map of API - * @deprecated Use applyApi from connector instead - */ - export function getApiMap, App extends ApiMap>(client: PluginClient, profiles: T): PluginApi>; - -} -declare module 'packages/plugin/core/src/lib/connector' { - import type { Message, Api, ApiMap, PluginApi } from '@remixproject/plugin-utils'; - import type { IRemixApi } from 'packages/api/src/lib/remix-profile'; - import { PluginClient } from 'packages/plugin/core/src/lib/client'; - export interface ClientConnector { - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** Check if a message is an handshake */ - export function isHandshake(message: Partial): boolean; - /** Check if an event.data is a plugin message is an handshake */ - export function isPluginMessage(message: any): message is Message; - /** - * Connect a plugin to the engine for a specific connector - * @param connector The connector for this plugin - * @param client The client instance of the plugin - * @example With a client - * typescript - * const client = new PluginClient() - * connectClient(new IframeConnector(client), client); - * - */ - export function connectClient(connector: ClientConnector, client?: PluginClient): PluginClient>; - export type Client

= PluginApi & PluginClient; - /** - * Add shortcut to the api requested by the client on it. - * @description - * Once applied, the client can do client.solidity.compile(x) instead of client.call('solidity', 'compile', x) - * @param client The client on which we apply the api - */ - export function applyApi(client: PluginClient): void; - /** - * Create & connect a client with a connector. - * @param connector A communication layer connector - * @param client The plugin client - */ - export const createConnectorClient:

> = Readonly>(connector: ClientConnector, client?: PluginClient) => Client; - -} -declare module 'packages/plugin/core/src/lib/node' { - import { PluginClient } from 'packages/plugin/core/src/lib/client'; - /** - * Access a service of an external plugin - */ - export class PluginNode { - private path; - private client; - /** - * @param path Path to external plugin - * @param client The main client used in this plugin - */ - constructor(path: string, client: PluginClient); - get(name: string): PluginNode; - /** Call a method of the node */ - call(method: string, ...payload: any[]): Promise; - /** - * Listen to an event from the plugin - * @note Event are trigger at the root level yet, not on a specific node - */ - on(method: string, cb: Function): void; - } - -} -declare module 'packages/plugin/core/src/lib/origin' { - import { PluginOptions } from 'packages/plugin/core/src/lib/client'; - export const remixOrgins = "https://gist.githubusercontent.com/EthereumRemix/091ccc57986452bbb33f57abfb13d173/raw/3367e019335746b73288e3710af2922d4c8ef5a3/origins.json"; - /** Fetch the default origins for remix */ - export function getOriginsFromUrl(url: string): Promise; - export function getDevmodeOrigins({ devMode }: Partial>): string[]; - /** - * Check if the sender has the right origin - * @param origin The origin of the incoming message - * @param options client plugin options - */ - export function checkOrigin(origin: string, options?: Partial>): Promise; - -} -declare module 'packages/plugin/core/src/index' { - export * from 'packages/plugin/core/src/lib/api'; - export * from 'packages/plugin/core/src/lib/client'; - export * from 'packages/plugin/core/src/lib/connector'; - export * from 'packages/plugin/core/src/lib/node'; - export * from 'packages/plugin/core/src/lib/origin'; - -} -declare module 'dist/packages/plugin/child-process/lib/connector' { - import { ClientConnector, Client, PluginClient } from '@remixproject/plugin'; - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export interface WS { - send(data: string): void; - on(type: 'message', cb: (event: string) => any): this; - } - /** - * This Websocket connector works with the library ws - */ - export class WebsocketConnector implements ClientConnector { - private websocket; - constructor(websocket: WS); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - * - * --------- - * @example - * typescript - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws) - * }) - * - * --------- - * @example - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws, new MyPlugin()) - * }) - * - */ - export const createClient:

> = Readonly>(websocket: WS, client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/child-process/index' { - export * from 'dist/packages/plugin/child-process/lib/connector'; - -} -declare module 'dist/packages/plugin/core/lib/client' { - /// - import { EventEmitter } from 'events'; - import { RemixApi } from 'packages/api/src/lib/remix-profile'; - import { GetPluginService, Profile } from 'dist/packages/utils/lib/types/service'; - import type { Api, PluginRequest, ApiMap, EventKey, EventCallback, MethodParams, MethodKey, EventParams, ProfileMap, IPluginService, PluginBase } from 'dist/packages/utils/lib/types/plugin'; - export interface PluginDevMode { - /** Port for localhost */ - port: number | string; - origins: string | string[]; - } - /** Options of the plugin client */ - export interface PluginOptions { - customTheme: boolean; - /** define a set of custom apis to implements on the client */ - customApi: ProfileMap; - /** - * Allow a set of origins - * You can either a list of origin or a url with a link of origins - */ - allowOrigins: string | string[]; - /** - * options only available for dev mode - * @deprecated use allowOrigins instead if you want to limit the parent origin - */ - devMode: Partial; - } - export const defaultOptions: Partial>; - /** Throw an error if client try to send a message before connection */ - export function handleConnectionError(devMode?: Partial): void; - export class PluginClient implements PluginBase { - private id; - isLoaded: boolean; - events: EventEmitter; - currentRequest: PluginRequest; - options: PluginOptions; - name: string; - methods: string[]; - activateService: Record Promise>; - onActivation?(): void; - constructor(options?: Partial>); - onload(cb?: () => void): Promise; - /** - * Ask the plugin manager if current request can call a specific method - * @param method The method to call - * @param message An optional message to show to the user - */ - askUserPermission(method: MethodKey, message?: string): Promise; - /** - * Called before deactivating the plugin - * @param from profile of plugin asking to deactivate - * @note PluginManager will always be able to deactivate - */ - canDeactivate(from: Profile): boolean; - /** Make a call to another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise>; - /** Listen on event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen once on event from another plugin */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Remove all listeners on an event from an external plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Expose an event for the IDE */ - emit>(key: Key, ...payload: EventParams): void; - /** - * Create a service under the client node - * @param name The name of the service - * @param service The service - */ - createService, Service extends IPluginService>(name: string, service: Service): Promise>; - /** - * Prepare a service to be lazy loaded - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): () => Promise>; - } - -} -declare module 'dist/packages/plugin/core/lib/api' { - import type { Profile, Api, CustomApi, ProfileMap, ApiMapFromProfileMap, PluginApi, ApiMap } from '@remixproject/plugin-utils'; - import { PluginClient } from 'dist/packages/plugin/core/lib/client'; - /** - * Create an Api - * @param profile The profile of the api - */ - export function createApi(client: PluginClient, profile: Profile): CustomApi; - /** - * Transform a list of profile into a map of API - * @deprecated Use applyApi from connector instead - */ - export function getApiMap, App extends ApiMap>(client: PluginClient, profiles: T): PluginApi>; - -} -declare module 'dist/packages/plugin/core/lib/connector' { - import type { Message, Api, ApiMap, PluginApi } from '@remixproject/plugin-utils'; - import type { IRemixApi } from '@remixproject/plugin-api'; - import { PluginClient } from 'dist/packages/plugin/core/lib/client'; - export interface ClientConnector { - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** Check if a message is an handshake */ - export function isHandshake(message: Partial): boolean; - /** Check if an event.data is a plugin message is an handshake */ - export function isPluginMessage(message: any): message is Message; - /** - * Connect a plugin to the engine for a specific connector - * @param connector The connector for this plugin - * @param client The client instance of the plugin - * @example With a client - * typescript - * const client = new PluginClient() - * connectClient(new IframeConnector(client), client); - * - */ - export function connectClient(connector: ClientConnector, client?: PluginClient): PluginClient>; - export type Client

= PluginApi & PluginClient; - /** - * Add shortcut to the api requested by the client on it. - * @description - * Once applied, the client can do client.solidity.compile(x) instead of client.call('solidity', 'compile', x) - * @param client The client on which we apply the api - */ - export function applyApi(client: PluginClient): void; - /** - * Create & connect a client with a connector. - * @param connector A communication layer connector - * @param client The plugin client - */ - export const createConnectorClient:

> = Readonly>(connector: ClientConnector, client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/core/lib/node' { - import { PluginClient } from 'dist/packages/plugin/core/lib/client'; - /** - * Access a service of an external plugin - */ - export class PluginNode { - private path; - private client; - /** - * @param path Path to external plugin - * @param client The main client used in this plugin - */ - constructor(path: string, client: PluginClient); - get(name: string): PluginNode; - /** Call a method of the node */ - call(method: string, ...payload: any[]): Promise; - /** - * Listen to an event from the plugin - * @note Event are trigger at the root level yet, not on a specific node - */ - on(method: string, cb: Function): void; - } - -} -declare module 'dist/packages/plugin/core/lib/origin' { - import { PluginOptions } from 'dist/packages/plugin/core/lib/client'; - export const remixOrgins = "https://gist.githubusercontent.com/EthereumRemix/091ccc57986452bbb33f57abfb13d173/raw/3367e019335746b73288e3710af2922d4c8ef5a3/origins.json"; - /** Fetch the default origins for remix */ - export function getOriginsFromUrl(url: string): Promise; - export function getDevmodeOrigins({ devMode }: Partial>): string[]; - /** - * Check if the sender has the right origin - * @param origin The origin of the incoming message - * @param options client plugin options - */ - export function checkOrigin(origin: string, options?: Partial>): Promise; - -} -declare module 'dist/packages/plugin/core/index' { - export * from 'dist/packages/plugin/core/lib/api'; - export * from 'dist/packages/plugin/core/lib/client'; - export * from 'dist/packages/plugin/core/lib/connector'; - export * from 'dist/packages/plugin/core/lib/node'; - export * from 'dist/packages/plugin/core/lib/origin'; - -} -declare module 'dist/packages/plugin/iframe/lib/connector' { - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - import { ClientConnector, Client, PluginClient, PluginOptions } from '@remixproject/plugin'; - export class IframeConnector implements ClientConnector { - private options; - source: Window; - origin: string; - constructor(options: PluginOptions); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect an Iframe client to a web engine - * @param client An optional iframe client to connect to the engine - * @example Let the function create a client - * typescript - * const client = createClient() - * - * @example With a custom client - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const client = createClient(new MyPlugin()) - * - */ - export const createClient:

> = Readonly>(client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/iframe/lib/theme' { - import { PluginClient, PluginOptions } from '@remixproject/plugin'; - /** Start listening on theme changed */ - export function listenOnThemeChanged(client: PluginClient, options?: Partial>): Promise; - -} -declare module 'dist/packages/plugin/iframe/index' { - export * from 'dist/packages/plugin/iframe/lib/connector'; - export * from 'dist/packages/plugin/iframe/lib/theme'; - -} -declare module 'dist/packages/plugin/vscode/lib/webview' { - import type { Message, Api } from '@remixproject/plugin-utils'; - import { ClientConnector, Client, PluginClient, PluginOptions } from '@remixproject/plugin'; - /** - * This Webview connector - */ - export class WebviewConnector implements ClientConnector { - private options; - source: { - postMessage: (message: any, origin?: string) => void; - }; - origin: string; - isVscode: boolean; - constructor(options?: Partial>); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Webview plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

>>(client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/vscode/lib/extension' { - export {}; - -} -declare module 'dist/packages/plugin/vscode/index' { - export * from 'dist/packages/plugin/vscode/lib/webview'; - export * from 'dist/packages/plugin/vscode/lib/extension'; - -} -declare module 'dist/packages/plugin/webview/lib/connector' { - import type { Message, Api, PluginApi } from '@remixproject/plugin-utils'; - import { ClientConnector, PluginClient, PluginOptions } from '@remixproject/plugin'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; global { - function acquireTheiaApi(): any; - } - /** - * This Webview connector - */ - export class WebviewConnector implements ClientConnector { - private options; - source: { - postMessage: (message: any, origin?: string) => void; - }; - origin: string; - isVscode: boolean; - constructor(options: PluginOptions); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - forwardEvents(): void; - } - /** - * Connect a Webview plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

> = Readonly, C extends PluginClient = any>(client: C) => C & PluginApi; - -} -declare module 'dist/packages/plugin/webview/index' { - export * from 'dist/packages/plugin/webview/lib/connector'; - -} -declare module 'dist/packages/plugin/webworker/lib/connector' { - /// - import { ClientConnector, Client, PluginClient } from '@remixproject/plugin'; - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export class WebworkerConnector implements ClientConnector { - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

> = Readonly>(client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/webworker/index' { - export * from 'dist/packages/plugin/webworker/lib/connector'; - -} -declare module 'dist/packages/plugin/ws/lib/ws' { - import type { Message, Api } from '@remixproject/plugin-utils'; - import { PluginClient, ClientConnector, Client } from '@remixproject/plugin'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export interface WS { - send(data: string): void; - on(type: 'message', cb: (event: string) => any): this; - } - /** - * This Websocket connector works with the library ws - */ - export class WebsocketConnector implements ClientConnector { - private websocket; - account: string; - constructor(websocket: WS); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - * - * --------- - * @example - * typescript - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws) - * }) - * - * --------- - * @example - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws, new MyPlugin()) - * }) - * - */ - export const createClient:

> = Readonly>(websocket: WS, client?: PluginClient) => Client; - -} -declare module 'dist/packages/plugin/ws/index' { - export * from 'dist/packages/plugin/ws/lib/ws'; - -} -declare module 'dist/packages/utils/lib/tools/event-name' { - /** Create the name of the event for a call */ - export function callEvent(name: string, key: string, id: number): string; - /** Create the name of the event for a listen */ - export function listenEvent(name: string, key: string): string; - -} -declare module 'dist/packages/utils/lib/tools/method-path' { - /** Create a method path based on the method name and the path */ - export function getMethodPath(method: string, path?: string): string; - /** Get the root name of a path */ - export function getRootPath(path: string): string; - -} -declare module 'dist/packages/utils/lib/types/service' { - export type IPluginService = any> = { - methods: string[]; - readonly path: string; - } & T; - export type GetPluginService> = S extends IPluginService ? S : IPluginService; - -} -declare module 'dist/packages/utils/lib/types/status' { - export interface Status { - /** Display an icon or number */ - key: number | 'edited' | 'succeed' | 'loading' | 'failed' | 'none'; - /** Bootstrap css color */ - type?: 'success' | 'info' | 'warning' | 'error'; - /** Describe the status on mouseover */ - title?: string; - } - export type StatusEvents = { - statusChanged: (status: Status) => void; - }; - -} -declare module 'dist/packages/utils/lib/types/api' { - import { StatusEvents } from 'dist/packages/utils/lib/types/status'; - export interface Api { - events: { - [key: string]: (...args: any[]) => void; - } & StatusEvents; - methods: { - [key: string]: (...args: any[]) => void; - }; - } - export type EventKey = Extract; - export type EventParams> = T extends Api ? Parameters : any[]; - export type EventCallback> = T extends Api ? T['events'][K] : (...payload: any[]) => void; - export type MethodKey = Extract; - export type MethodParams> = T extends Api ? Parameters : any[]; - export interface EventApi { - on: >(name: event, cb: T['events'][event]) => void; - } - export type MethodApi = { - [m in Extract]: (...args: Parameters) => Promise>; - }; - export type CustomApi = EventApi & MethodApi; - /** A map of Api used to describe all the plugin's api in the project */ - export type ApiMap = Readonly>; - /** A map of plugin based on the ApiMap. It enforces the PluginEngine */ - export type PluginApi = { - [name in keyof T]: CustomApi; - }; - export type API = { - [M in keyof T['methods']]: T['methods'][M] | Promise; - }; - -} -declare module 'dist/packages/utils/lib/types/plugin' { - import type { IPluginService } from 'dist/packages/utils/lib/types/service'; - import { EventCallback, MethodParams, MethodKey, EventKey, Api, ApiMap, EventParams } from 'dist/packages/utils/lib/types/api'; - export interface PluginBase { - methods: string[]; - activateService: Record Promise>; - /** Listen on an event from another plugin */ - on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Listen one time on an event from another plugin, then remove event listener */ - once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; - /** Stop listening on an event from another plugin */ - off, Key extends EventKey>(name: Name, key: Key): void; - /** Call a method of another plugin */ - call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise; - /** Emit an event */ - emit>(key: Key, ...payload: EventParams): void; - } - export { EventCallback, MethodParams, MethodKey, EventKey, Api, ApiMap, EventParams } -} -declare module 'dist/packages/utils/lib/tools/service' { - import type { IPluginService, GetPluginService } from 'dist/packages/utils/lib/types/service'; - import type { Api, ApiMap } from 'dist/packages/utils/lib/types/api'; - import type { PluginBase } from 'dist/packages/utils/lib/types/plugin'; - /** Check if the plugin is an instance of PluginService */ - export const isPluginService: (service: any) => service is PluginService; - /** - * Return the methods of a service, except "constructor" and methods starting with "_" - * @param instance The instance of a class to get the method from - */ - export function getMethods(service: IPluginService): any; - /** - * Create a plugin service - * @param path The path of the service separated by '.' (ex: 'box.profile') - * @param service The service template - * @note If the service doesn't provide a property "methods" then all methods are going to be exposed by default - */ - export function createService>(path: string, service: T): GetPluginService; - /** - * Connect the service to the plugin client - * @param client The main client of the plugin - * @param service A service to activate - */ - export function activateService(client: PluginBase, service: IPluginService): any; - /** - * A node that forward the call to the right path - */ - export abstract class PluginService implements IPluginService { - methods: string[]; - abstract readonly path: string; - protected abstract plugin: PluginBase; - emit(key: string, ...payload: any[]): void; - /** - * Create a subservice under this service - * @param name The name of the subservice inside this service - * @param service The subservice to add - */ - createService>(name: string, service: S): Promise>; - /** - * Prepare a service to be lazy loaded. - * Service can be activated by doing client.activateService(path) - * @param name The name of the subservice inside this service - * @param factory A function to create the service on demand - */ - prepareService>(name: string, factory: () => S): void; - } - -} -declare module 'dist/packages/utils/lib/types/message' { - export interface PluginRequest { - /** The name of the plugin making the request */ - from: string; - /** @deprecated Will be remove in the next version */ - isFromNative?: boolean; - /** - * The path to access the request inside the plugin - * @example 'remixd.cmd.git' - */ - path?: string; - } type MessageActions = 'on' | 'off' | 'once' | 'call' | 'response' | 'emit'; type OldMessageActions = 'notification' | 'request' | 'response' | 'listen'; - export interface Message { - id: number; - action: MessageActions | OldMessageActions; - name: string; - key: string; - payload: any; - requestInfo: PluginRequest; - error?: Error | string; - signature?: string; - verifier?: string; - } - export {}; - -} -declare module 'dist/packages/utils/lib/types/profile' { - import { MethodKey, Api, ApiMap, EventKey } from 'dist/packages/utils/lib/types/api'; - /** Describe a plugin */ - export interface Profile { - name: string; - displayName?: string; - methods?: MethodKey[]; - permission?: boolean; - hash?: string; - description?: string; - documentation?: string; - version?: string; - } - export interface LocationProfile { - location: string; - } - export interface ExternalProfile { - url: string; - } - export interface HostProfile extends Profile { - methods: ('addView' | 'removeView' | 'focus' | string)[]; - } - export interface LibraryProfile extends Profile { - events?: EventKey[]; - notifications?: { - [name: string]: string[]; - }; - } - /** A map of profile */ - export type ProfileMap = Partial<{ - [name in keyof T]: Profile; - }>; - /** Extract the API of a profile */ - export type ApiFromProfile = T extends Profile ? I : never; - /** Create an ApiMap from a Profile Map */ - export type ApiMapFromProfileMap> = { - [name in keyof T]: ApiFromProfile; - }; - /** Transform an ApiMap into a profile map */ - export type ProfileMapFromApiMap = Readonly<{ - [name in keyof T]: Profile; - }>; - -} -declare module 'dist/packages/utils/index' { - export * from 'dist/packages/utils/lib/tools/event-name'; - export * from 'dist/packages/utils/lib/tools/method-path'; - export * from 'dist/packages/utils/lib/tools/service'; - export * from 'dist/packages/utils/lib/types/api'; - export * from 'dist/packages/utils/lib/types/message'; - export * from 'dist/packages/utils/lib/types/plugin'; - export * from 'dist/packages/utils/lib/types/profile'; - export * from 'dist/packages/utils/lib/types/service'; - export * from 'dist/packages/utils/lib/types/status'; - -} -declare module 'examples/example/engine/web/src/app/engine' { - import { Engine as PluginEngine } from '@remixproject/engine'; - export class Engine extends PluginEngine { - constructor(); - } - -} -declare module 'examples/example/engine/web/src/app/plugins/manager' { - import { PluginManager } from '@remixproject/engine'; - import { Profile } from '@remixproject/plugin-utils'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - export class Manager extends PluginManager { - private activeProfiles; - private idleProfiles; - activeProfiles$: import("rxjs").Observable[]>; - idleProfiles$: import("rxjs").Observable[]>; - constructor(engine: Engine); - private updateProfiles; - onProfileAdded(): void; - onPluginActivated(profile: Profile): void; - onPluginDeactivated(): void; - canDeactivatePlugin(from: Profile, to: Profile): Promise; - } - -} -declare module 'examples/example/engine/web/src/app/plugins/theme' { - import { ThemePlugin } from '@remixproject/engine-web'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - export class Theme extends ThemePlugin { - private engine; - private themes; - constructor(engine: Engine); - selectTheme(brightness: 'dark' | 'light'): void; - onActivation(): void; - } - -} -declare module 'examples/example/engine/web/src/app/plugins/window' { - import { WindowPlugin } from '@remixproject/engine-web'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - import { Theme } from 'examples/example/engine/web/src/app/plugins/theme'; - export class Window extends WindowPlugin { - private engine; - private theme; - constructor(engine: Engine, theme: Theme); - onActivation(): Promise; - } - -} -declare module 'examples/example/engine/web/src/app/plugins/library' { - /// - import { LibraryPlugin } from '@remixproject/engine'; - import { EventEmitter } from 'events'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - interface Transaction { - id: string; - } class TransactionLibrary { - private transactions; - events: EventEmitter; - sendTransaction(tx: Transaction): void; - } - export class Library extends LibraryPlugin { - library: TransactionLibrary; - constructor(engine: Engine); - onActivation(): void; - } - export {}; - -} -declare module 'examples/example/engine/web/src/app/plugins/terminal' { - import { Plugin } from '@remixproject/engine'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - export class Terminal extends Plugin { - private engine; - constructor(engine: Engine); - onActivation(): void; - run(text: string): void; - } - -} -declare module 'examples/example/engine/web/src/app/plugins/index' { - export * from 'examples/example/engine/web/src/app/plugins/manager'; - export * from 'examples/example/engine/web/src/app/plugins/theme'; - export * from 'examples/example/engine/web/src/app/plugins/window'; - export * from 'examples/example/engine/web/src/app/plugins/library'; - export * from 'examples/example/engine/web/src/app/plugins/terminal'; - -} -declare module 'examples/example/engine/web/src/app/app.component' { - import { Theme, Manager, Window, Library } from 'examples/example/engine/web/src/app/plugins'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - export class AppComponent { - private engine; - private manager; - private window; - private theme; - private library; - actives$: import("rxjs").Observable[]>; - idles$: import("rxjs").Observable[]>; - constructor(engine: Engine, manager: Manager, window: Window, theme: Theme, library: Library); - ngAfterViewInit(): void; - deactivate(name: string): void; - activate(name: string): void; - } - -} -declare module 'examples/example/engine/web/src/app/host.directive' { - import { ElementRef, Renderer2 } from '@angular/core'; - import { Manager } from 'examples/example/engine/web/src/app/plugins'; - import { Engine } from 'examples/example/engine/web/src/app/engine'; - export class HostDirective { - private engine; - private manager; - private el; - private renderer; - private plugin; - host: string; - constructor(engine: Engine, manager: Manager, el: ElementRef, renderer: Renderer2); - get name(): string; - ngAfterViewInit(): void; - ngOnDestroy(): Promise; - } - -} -declare module 'examples/example/engine/web/src/app/terminal/terminal.component' { - import { FormControl } from '@angular/forms'; - import { Manager, Terminal } from 'examples/example/engine/web/src/app/plugins'; - export class TerminalComponent { - private manager; - private terminal; - form: FormControl; - constructor(manager: Manager, terminal: Terminal); - submit(): Promise; - } - -} -declare module 'examples/example/engine/web/src/app/app.module' { - export class AppModule { - } - -} -declare module 'examples/example/engine/web/src/environments/environment' { - export const environment: { - production: boolean; - }; - -} -declare module 'examples/example/engine/web/src/main' { - export {}; - -} -declare module 'examples/example/engine/web/src/polyfills' { - /** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - /*************************************************************************************************** - * BROWSER POLYFILLS - */ - /** IE10 and IE11 requires the following for NgClass support on SVG elements */ - /** - * Web Animations @angular/platform-browser/animations - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ - /** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before zone.js being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass zone.js patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - /*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ - import 'zone.js/dist/zone'; - /*************************************************************************************************** - * APPLICATION IMPORTS - */ - -} -declare module 'examples/example/engine/web/src/test-setup' { - import 'jest-preset-angular'; - -} -declare module 'examples/example/engine/web/src/environments/environment.prod' { - export const environment: { - production: boolean; - }; - -} -declare module 'examples/example/engine/web-e2e/src/support/app.po' { - export const pluginList: () => any; - -} -declare module 'examples/example/engine/web-e2e/src/integration/app.spec' { - export {}; - -} -declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; +export const remixTypes = ` +/// + +import { EventEmitter } from 'events'; + +declare type ABIDescription = FunctionDescription | EventDescription + +declare interface ABIParameter { + /** The name of the parameter */ + name: string + /** The canonical type of the parameter */ + type: ABITypeParameter + /** Used for tuple types */ + components?: ABIParameter[] +} + +declare type ABITypeParameter = +| 'uint' +| 'uint[]' // TODO : add +| 'int' +| 'int[]' // TODO : add +| 'address' +| 'address[]' +| 'bool' +| 'bool[]' +| 'fixed' +| 'fixed[]' // TODO : add +| 'ufixed' +| 'ufixed[]' // TODO : add +| 'bytes' +| 'bytes[]' // TODO : add +| 'function' +| 'function[]' +| 'tuple' +| 'tuple[]' +| string + +declare interface Annotation { + row: number; + column: number; + text: string; + type: "error" | "warning" | "info"; +} + +declare interface Api { + events: { + [key: string]: (...args: any[]) => void + } & StatusEvents + methods: { + [key: string]: (...args: any[]) => void } } -declare module 'examples/example/engine/web-e2e/src/support/index' { - import 'examples/example/engine/web-e2e/src/support/commands'; - -} -declare module 'examples/example/plugin/webview/src/app/client' { - import { InjectionToken } from '@angular/core'; - import { PluginClient } from '@remixproject/plugin'; - export class Client extends PluginClient { - methods: string[]; - constructor(); - execute(value: string): void; - onActivation(): void; - } - export const CLIENT: InjectionToken; - -} -declare module 'examples/example/plugin/webview/src/app/app.component' { - import { Client } from 'examples/example/plugin/webview/src/app/client'; - export class AppComponent { - private client; - title: string; - constructor(client: Client); - } - -} -declare module 'examples/example/plugin/webview/src/app/app.module' { - export class AppModule { - } - -} -declare module 'examples/example/plugin/webview/src/environments/environment' { - export const environment: { - production: boolean; - }; - -} -declare module 'examples/example/plugin/webview/src/main' { - export {}; - -} -declare module 'examples/example/plugin/webview/src/polyfills' { - /** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - /*************************************************************************************************** - * BROWSER POLYFILLS - */ - /** IE10 and IE11 requires the following for NgClass support on SVG elements */ - /** - * Web Animations @angular/platform-browser/animations - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ - /** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before zone.js being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass zone.js patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - /*************************************************************************************************** - * Zone JS is required by default for Angular itself. - */ - import 'zone.js/dist/zone'; - /*************************************************************************************************** - * APPLICATION IMPORTS - */ - -} -declare module 'examples/example/plugin/webview/src/test-setup' { - import 'jest-preset-angular'; - -} -declare module 'examples/example/plugin/webview/src/environments/environment.prod' { - export const environment: { - production: boolean; - }; - -} -declare module 'examples/example/plugin/webview-e2e/src/support/app.po' { - export const getGreeting: () => any; - -} -declare module 'examples/example/plugin/webview-e2e/src/integration/app.spec' { - export {}; -} -declare namespace Cypress { - interface Chainable { - login(email: string, password: string): void; +/** A map of Api used to describe all the plugin's api in the project */ +declare type ApiMap = Readonly> + +declare interface AstNode { + absolutePath?: string + exportedSymbols?: Object + id: number + nodeType: string + nodes?: Array + src: string + literals?: Array + file?: string + scope?: number + sourceUnit?: number + symbolAliases?: Array + [x: string]: any +} + +declare interface AstNodeAtt { + operator?: string + string?: null + type?: string + value?: string + constant?: boolean + name?: string + public?: boolean + exportedSymbols?: Object + argumentTypes?: null + absolutePath?: string + [x: string]: any +} + +declare interface AstNodeLegacy { + id: number + name: string + src: string + children?: Array + attributes?: AstNodeAtt +} + +declare interface BytecodeObject { + /** The bytecode as a hex string. */ + object: string + /** Opcodes list */ + opcodes: string + /** The source mapping as a string. See the source mapping definition. */ + sourceMap: string + /** If given, this is an unlinked object. */ + linkReferences?: { + [contractName: string]: { + /** Byte offsets into the bytecode. */ + [library: string]: { start: number; length: number }[] + } } } -declare module 'examples/example/plugin/webview-e2e/src/support/index' { - import 'examples/example/plugin/webview-e2e/src/support/commands'; - -} -declare module 'packages/engine/core/tests/abstract.spec' { - export {}; - -} -declare module 'packages/engine/core/tests/connector.spec' { - export {}; - -} -declare module 'packages/engine/core/tests/engine.spec' { - /// - import { Engine, Plugin, PluginManager } from 'packages/engine/core/src'; - export class MockEngine extends Engine { - onRegistration: jest.Mock; - setPluginOption: jest.Mock<{ - queueTimeout: number; - }, []>; - } - export class MockManager extends PluginManager { - activatePlugin: jest.Mock, [names: string | string[]]>; - deactivatePlugin: jest.Mock, [names: string | string[]]>; - onRegistration: jest.Mock; - onActivation: jest.Mock; - onDeactivation: jest.Mock; - onPluginActivated: jest.Mock; - onPluginDeactivated: jest.Mock; - onProfileAdded: jest.Mock; - canActivatePlugin: jest.Mock, []>; - canDeactivatePlugin: jest.Mock, [from: any]>; - canCall: jest.Mock, []>; - constructor(); - } - export class MockSolidity extends Plugin { - onActivation: jest.Mock; - onDeactivation: jest.Mock; - onRegistration: jest.Mock; - compile: jest.Mock; - slowMockMethod: jest.Mock, [num: number]>; - getCompilationResult: jest.Mock; - constructor(); - } - export class MockFileManager extends Plugin { - private files; - private active; - constructor(); - getCurrentFile: jest.Mock; - getFile: jest.Mock; - getFolder: jest.Mock<{}, []>; - setFile: jest.Mock; - switchFile: jest.Mock; - } - -} -declare module 'packages/engine/core/tests/manager.spec' { - export {}; - -} -declare module 'packages/engine/node/src/lib/child-process' { - /// - import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { PluginConnector } from '@remixproject/engine'; - import { ChildProcess } from 'child_process'; - export class ChildProcessPlugin extends PluginConnector { - private readonly listener; - process: ChildProcess; - constructor(profile: Profile & ExternalProfile); - protected send(message: Partial): void; - protected connect(url: string): void; - protected disconnect(): void; - } - -} -declare module 'packages/engine/node/src/index' { - export * from 'packages/engine/node/src/lib/child-process'; - -} -declare module 'packages/engine/node/tests/child-process.spec' { - export {}; - -} -declare module 'packages/engine/theia/src/lib/engine-theia' { - export function engineTheia(): string; - -} -declare module 'packages/engine/theia/src/index' { - export * from 'packages/engine/theia/src/lib/engine-theia'; - -} -declare module 'packages/engine/theia/src/lib/engine-theia.spec' { - export {}; - -} -declare module 'packages/engine/vscode/src/lib/command' { - import { Plugin } from '@remixproject/engine'; - import { Profile, PluginOptions } from '@remixproject/plugin-utils'; - import { Disposable } from 'vscode'; - export const transformCmd: (name: string, method: string) => string; - export interface CommandOptions extends PluginOptions { - transformCmd: (name: string, method: string) => string; - } - /** - * Connect methods of the plugins with a command depending on the transformCmd function pass as option - */ - export class CommandPlugin extends Plugin { - subscriptions: Disposable[]; - options: CommandOptions; - constructor(profile: Profile); - setOptions(options: Partial): void; - activate(): void; - deactivate(): void; - } - -} -declare module 'packages/engine/vscode/src/lib/dynamic-list' { - import { Plugin } from '@remixproject/engine'; - import { PluginOptions } from '@remixproject/plugin-utils'; - import { TreeDataProvider, EventEmitter, TreeView, TreeItem } from 'vscode'; type ID = string | number; - export class Item extends TreeItem { - private item; - constructor(label: string, pluginName: string, item: I); - } - export class List implements TreeDataProvider { - private name; - private list; - private options; - render: EventEmitter; - onDidChangeTreeData: import("vscode").Event; - constructor(name: string, initial?: I[]); - setOptions(options: Partial): void; - reset(list: I[]): void; - getParent(): any; - getTreeItem(element: I): Item; - getChildren(): I[]; - } - export interface ListOptions { - idKey: string; - labelKey: string; - } - export type ListPluginOptions = PluginOptions & ListOptions; - export class DynamicListPlugin = List> extends Plugin { - private listeners; - protected options: ListPluginOptions; - protected treeView: TreeView; - protected entities: Record; - protected selected: ID; - list: T; - constructor(name: string, options?: Partial); - setOptions(options: Partial): void; - activate(): void; - deactivate(): void; - getIds(): string[]; - getItem(id: ID): I; - getAll(): I[]; - /** Select on element of the list */ - select(idOrItem: ID | I): void; - /** Reset the entire list */ - reset(items: I[]): void; - /** Add a new item to the list */ - add(item: I): void; - /** Remove one item from the list */ - remove(id: ID): void; - /** Update one item in the list */ - update(id: ID, item: Partial): void; - } - export {}; - -} -declare module 'packages/engine/vscode/src/lib/extension' { - import { PluginConnector } from '@remixproject/engine'; - import { Profile, ExternalProfile, Message } from '@remixproject/plugin-utils'; - export class ExtensionPlugin extends PluginConnector { - private extension; - private connector; - constructor(profile: Profile & ExternalProfile); - protected send(message: Partial): void; - protected connect(url: string): Promise; - protected disconnect(): void; - } - -} -declare module 'packages/engine/vscode/src/lib/theme' { - import { Plugin } from '@remixproject/engine'; - import { API, PluginOptions } from '@remixproject/plugin-utils'; - import { ITheme, Theme, ThemeUrls } from '@remixproject/plugin-api'; - import { Disposable, ColorTheme } from 'vscode'; - export interface ThemeOptions extends PluginOptions { - urls?: Partial; - } - export function getVscodeTheme(color: ColorTheme, urls?: Partial): Theme; - export class ThemePlugin extends Plugin implements API { - protected getTheme: typeof getVscodeTheme; - protected options: ThemeOptions; - listener: Disposable; - constructor(options?: Partial); - setOptions(options: Partial): void; - onActivation(): void; - onDeactivation(): void; - currentTheme(): Theme; - } +declare interface CompilationError { + /** Location within the source file */ + sourceLocation?: { + file: string + start: number + end: number + } + /** Error type */ + type: CompilationErrorType + /** Component where the error originated, such as "general", "ewasm", etc. */ + component: 'general' | 'ewasm' | string + severity: 'error' | 'warning' + message: string + /** the message formatted with source location */ + formattedMessage?: string +} + +declare type CompilationErrorType = +| 'JSONError' +| 'IOError' +| 'ParserError' +| 'DocstringParsingError' +| 'SyntaxError' +| 'DeclarationError' +| 'TypeError' +| 'UnimplementedFeatureError' +| 'InternalCompilerError' +| 'Exception' +| 'CompilerError' +| 'FatalError' +| 'Warning' + +declare interface CompilationFileSources { + [fileName: string]: + { + // Optional: keccak256 hash of the source file + keccak256?: string, + // Required (unless "urls" is used): literal contents of the source file + content: string, + urls?: string[] + } } -declare module 'packages/engine/vscode/src/lib/webview' { - import { PluginConnector, PluginConnectorOptions } from '@remixproject/engine'; - import { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { ExtensionContext, ViewColumn, WebviewPanel } from 'vscode'; - interface WebviewOptions extends PluginConnectorOptions { - /** Extension Path */ - context: ExtensionContext; - relativeTo?: 'workspace' | 'extension'; - column?: ViewColumn; - devMode?: boolean; - } - export class WebviewPlugin extends PluginConnector { - private listeners; - panel?: WebviewPanel; - options: WebviewOptions; - constructor(profile: Profile & ExternalProfile, options: WebviewOptions); - setOptions(options: Partial): void; - protected send(message: Partial): void; - protected connect(url: string): Promise; - getMessage(message: Message): Promise; - protected disconnect(): void; - } - /** Create a webview */ - export function createWebview(profile: Profile, url: string, options: WebviewOptions): Promise; - export {}; +declare interface CompilationResult { + /** not present if no errors/warnings were encountered */ + errors?: CompilationError[] + /** This contains the file-level outputs. In can be limited/filtered by the outputSelection settings */ + sources: { + [contractName: string]: CompilationSource + } + /** This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings */ + contracts: { + /** If the language used has no contract names, this field should equal to an empty string. */ + [fileName: string]: { + [contract: string]: CompiledContract + } + } } -declare module 'packages/engine/vscode/src/lib/window' { - import { Plugin } from '@remixproject/engine'; - import { Profile, PluginOptions } from '@remixproject/plugin-utils'; - import { QuickPickOptions, InputBoxOptions } from 'vscode'; - export const windowProfile: Profile; - interface IWindowPlugin { - /** Display an input window */ - prompt(): Thenable; - /** Display a select window */ - select(options: string[]): Thenable; - /** Display a select window with local file system: can only select a file */ - selectFile(): Thenable; - /** Display a select window with local file system: can only select a folder */ - selectFolder(): Thenable; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): Thenable; - /** Display a warning message with actions button. Returned the button clicked if any */ - warning(message: string, actions?: string[]): Thenable; - /** Display an error message with actions button. Returned the button clicked if any */ - error(message: string, actions?: string[]): Thenable; - } - export class WindowPlugin extends Plugin implements IWindowPlugin { - constructor(options?: PluginOptions); - prompt(options?: InputBoxOptions): Thenable; - select(items: string[], options?: QuickPickOptions): Thenable; - selectFile(): Thenable; - selectFolder(): Thenable; - alert(message: string, actions?: string[]): Thenable; - error(message: string, actions?: string[]): Thenable; - warning(message: string, actions?: string[]): Thenable; - } - export {}; +declare interface CompilationSource { + /** Identifier of the source (used in source maps) */ + id: number + /** The AST object */ + ast: AstNode + /** The legacy AST object */ + legacyAST: AstNodeLegacy +} + +declare interface CompiledContract { + /** The Ethereum Contract ABI. If empty, it is represented as an empty array. */ + abi: ABIDescription[] + // See the Metadata Output documentation (serialised JSON string) + metadata: string + /** User documentation (natural specification) */ + userdoc: UserDocumentation + /** Developer documentation (natural specification) */ + devdoc: DeveloperDocumentation + /** Intermediate representation (string) */ + ir: string + /** EVM-related outputs */ + evm: { + assembly: string + legacyAssembly: {} + /** Bytecode and related details. */ + bytecode: BytecodeObject + deployedBytecode: BytecodeObject + /** The list of function hashes */ + methodIdentifiers: { + [functionIdentifier: string]: string + } + // Function gas estimates + gasEstimates: { + creation: { + codeDepositCost: string + executionCost: 'infinite' | string + totalCost: 'infinite' | string + } + external: { + [functionIdentifier: string]: string + } + internal: { + [functionIdentifier: string]: 'infinite' | string + } + } + } + /** eWASM related outputs */ + ewasm: { + /** S-expressions format */ + wast: string + /** Binary format (hex string) */ + wasm: string + } } -declare module 'packages/engine/vscode/src/util/path' { - export function absolutePath(path: string): string; - export function relativePath(path: any): any; +declare interface CondensedCompilationInput { + language: 'Solidity' | 'Vyper' | 'lll' | 'assembly' | 'yul' + optimize: boolean + /** e.g: 0.6.8+commit.0bbfe453 */ + version: string + evmVersion?: 'berlin' | 'istanbul' | 'petersburg' | 'constantinople' | 'byzantium' | 'spuriousDragon' | 'tangerineWhistle' | 'homestead' } -declare module 'packages/engine/vscode/src/util/editor' { - import { TextEditor } from 'vscode'; - export function getOpenedTextEditor(): TextEditor; - export function getTextEditorWithDocumentType(type: string): TextEditor; +declare interface ContentImport { + content: any + cleanUrl: string + type: 'github' | 'http' | 'https' | 'swarm' | 'ipfs' + url: string } -declare module 'packages/engine/vscode/src/lib/filemanager' { - import { IFileSystem } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin } from 'packages/engine/vscode/src/lib/command'; - export class FileManagerPlugin extends CommandPlugin implements MethodApi { - constructor(); - /** Open the content of the file in the context (eg: Editor) */ - open(path: string): Promise; - /** Set the content of a specific file */ - writeFile(path: string, data: string): Promise; - /** Return the content of a specific file */ - readFile(path: string): Promise; - /** Remove a file */ - remove(path: string): Promise; - /** Change the path of a file */ - rename(oldPath: string, newPath: string): Promise; - /** Upsert a file with the content of the source file */ - copyFile(src: string, dest: string): Promise; - /** Create a directory */ - mkdir(path: string): Promise; - /** Get the list of files in the directory */ - readdir(path: string): Promise; - getCurrentFile(): Promise; - closeFile(): Promise; - closeAllFiles(): Promise; - logMessage(message: any): void; - getFile: (path: string) => Promise; - setFile: (path: string, data: string) => Promise; - switchFile: (path: string) => Promise; - /** @deprecated Use readdir instead */ - getFolder(path: string): Promise; - } +declare interface customAction { + id: string, + name: string, + type: customActionType[], + path: string[], + extension: string[], + pattern: string[], + sticky?: boolean, + label?: string } -declare module 'packages/engine/vscode/src/lib/editor' { - import { IEditor, Annotation, HighlightPosition } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin, CommandOptions } from 'packages/engine/vscode/src/lib/command'; - export interface EditorOptions extends CommandOptions { - language: string; - } - export class EditorPlugin extends CommandPlugin implements MethodApi { - private decoration; - private decorations; - private diagnosticCollection; - options: EditorOptions; - constructor(options: EditorOptions); - setOptions(options: EditorOptions): void; - onActivation(): void; - onDeactivation(): void; - highlight(position: HighlightPosition, filePath: string, themeColor: string): Promise; - discardDecorations(): Promise; - discardHighlight(): Promise; - /** - * Alisas of discardHighlight - * Required to match the standard interface of editor - */ - discardHighlightAt(): Promise; - addAnnotation(annotation: Annotation, filePath?: string): Promise; - clearAnnotations(): Promise; - gotoLine(line: number, col: number): Promise; - } -} -declare module 'packages/engine/vscode/src/lib/terminal' { - import { Plugin } from '@remixproject/engine'; - export interface TerminalOptions { - name?: string; - open: boolean; - } - export class TerminalPlugin extends Plugin { - private terminals; - private outputs; - private activeOutput; - constructor(); - onDeactivation(): void; - private get active(); - private getTerminal; - private getOutput; - /** Open specific terminal (doesn't work with output) */ - open(name?: string): string; - /** Kill a terminal */ - kill(name?: string): void; - /** Write on the current terminal and execute command */ - exec(command: string, options?: Partial): void; - /** Write on the current output */ - write(text: string, options?: Partial): void; - } +declare type customActionType = 'file' | 'folder' +/** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ +declare interface CustomNetwork { + id?: string + name: string + url: string } -declare module 'packages/engine/vscode/src/lib/contentimport' { - import { IContentImport } from '@remixproject/plugin-api'; - import { ContentImport } from '@remixproject/plugin-api'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { CommandPlugin } from 'packages/engine/vscode/src/lib/command'; - import { RemixURLResolver } from '@remix-project/remix-url-resolver'; - export class ContentImportPlugin extends CommandPlugin implements MethodApi { - urlResolver: RemixURLResolver; - constructor(); - resolve(path: string): Promise; - resolveAndSave(url: string, targetPath: string): Promise; - } -} -declare module 'packages/engine/vscode/src/lib/appmanager' { - import { PluginManager } from '@remixproject/engine'; - export class VscodeAppManager extends PluginManager { - pluginsDirectory: string; - target: string; - constructor(); - registeredPluginData(): Promise; - } +export declare const defaultOptions: Partial>; +declare interface DeveloperDocumentation { + author: string + title: string + details: string + methods: DevMethodList } -declare module 'packages/engine/vscode/src/index' { - export * from 'packages/engine/vscode/src/lib/command'; - export * from 'packages/engine/vscode/src/lib/dynamic-list'; - export * from 'packages/engine/vscode/src/lib/extension'; - export * from 'packages/engine/vscode/src/lib/theme'; - export * from 'packages/engine/vscode/src/lib/webview'; - export * from 'packages/engine/vscode/src/lib/window'; - export * from 'packages/engine/vscode/src/lib/filemanager'; - export * from 'packages/engine/vscode/src/lib/editor'; - export * from 'packages/engine/vscode/src/lib/terminal'; - export * from 'packages/engine/vscode/src/lib/contentimport'; - export * from 'packages/engine/vscode/src/lib/appmanager'; +declare interface DevMethodDoc { + author: string + details: string + return: string + returns: { + [param: string]: string + } + params: { + [param: string]: string + } } -declare module 'packages/engine/web/src/lib/iframe' { - import type { Message, Profile, ExternalProfile, LocationProfile } from '@remixproject/plugin-utils'; - import { PluginConnector } from '@remixproject/engine'; - export type IframeProfile = Profile & LocationProfile & ExternalProfile; - /** - * Connect an Iframe client to the engine. - * @dev This implements the ViewPlugin as it cannot extends two class. Maybe use a mixin at some point - */ - export class IframePlugin extends PluginConnector { - profile: IframeProfile; - private readonly listener; - private iframe; - private origin; - private source; - private url; - constructor(profile: IframeProfile); - /** Implement "activate" of the ViewPlugin */ - connect(url: string): Promise; - /** Implement "deactivate" of the ViewPlugin */ - disconnect(): Promise; - /** Get message from the iframe */ - private getEvent; - /** - * Post a message to the iframe of this plugin - * @param message The message to post - */ - protected send(message: Partial): void; - /** Create and return the iframe */ - render(): HTMLIFrameElement; - } +declare interface DevMethodList { + [functionIdentifier: string]: DevMethodDoc } -declare module 'packages/engine/web/src/lib/ws' { - import type { Message, Profile, ExternalProfile } from '@remixproject/plugin-utils'; - import { PluginConnector, PluginConnectorOptions } from '@remixproject/engine'; - export interface WebsocketOptions extends PluginConnectorOptions { - /** Time (in ms) to wait before reconnection after connection closed */ - reconnectDelay: number; - } - export class WebsocketPlugin extends PluginConnector { - private readonly listeners; - private url; - protected socket: WebSocket; - protected options: WebsocketOptions; - constructor(profile: Profile & ExternalProfile, options?: Partial); - private getEvent; - /** Try to reconnect to net websocket if closes */ - private onclose; - /** Open a connection with the server (also used for reconnection) */ - protected open(): void; - protected send(message: Partial): void; - protected connect(url: string): void; - protected disconnect(): void; - } -} -declare module 'packages/engine/web/src/lib/theme' { - import { Plugin } from '@remixproject/engine'; - import { MethodApi } from '@remixproject/plugin-utils'; - import { ITheme, Theme } from '@remixproject/plugin-api'; type DeepPartial = { - [P in keyof T]?: DeepPartial; - }; - /** - * Utils function to create a theme with default value - * Default values are taken from material design with colors - * - primary: indigo - * - secondary: pink - * - warn: orange - * - error: red - */ - export function createTheme(params?: DeepPartial): Theme; - export class ThemePlugin extends Plugin implements MethodApi { - protected getTheme: typeof createTheme; - protected theme: Theme; - constructor(); - /** Internal API to set the current theme */ - setTheme(theme: DeepPartial): void; - /** External API to get the current theme */ - currentTheme(): Promise; - } - export {}; +declare type EventCallback> = T extends Api +? T['events'][K] +: (...payload: any[]) => void +declare interface EventDescription { + type: 'event' + name: string + inputs: ABIParameter & + { + /** true if the field is part of the log’s topics, false if it one of the log’s data segment. */ + indexed: boolean + }[] + /** true if the event was declared as anonymous. */ + anonymous: boolean } -declare module 'packages/engine/web/src/lib/window' { - import { Plugin } from '@remixproject/engine'; - import { IWindow } from '@remixproject/plugin-api'; - import { MethodApi, PluginOptions } from '@remixproject/plugin-utils'; - export class WindowPlugin extends Plugin implements MethodApi { - constructor(options?: PluginOptions); - /** Display an input window */ - prompt(message?: string): Promise; - /** Ask confirmation for an action */ - confirm(message: string): Promise; - /** Display a message with actions button. Returned the button clicked if any */ - alert(message: string, actions?: string[]): Promise; - } -} -declare module 'packages/engine/web/src/lib/web-worker' { - import type { Message, Profile, ExternalProfile, PluginOptions } from '@remixproject/plugin-utils'; - import { PluginConnector } from '@remixproject/engine'; type WebworkerOptions = WorkerOptions & PluginOptions; - export class WebWorkerPlugin extends PluginConnector { - profile: Profile & ExternalProfile; - private worker; - protected options: WebworkerOptions; - constructor(profile: Profile & ExternalProfile, options?: WebworkerOptions); - setOptions(options: Partial): void; - connect(url: string): Promise; - disconnect(): void; - /** Get message from the iframe */ - private getEvent; - /** - * Post a message to the webview of this plugin - * @param message The message to post - */ - protected send(message: Partial): void; - } - export {}; +declare type EventKey = Extract -} -declare module 'packages/engine/web/src/lib/host' { - import type { Profile } from '@remixproject/plugin-utils'; - import { Plugin } from '@remixproject/engine'; - export abstract class HostPlugin extends Plugin { - constructor(profile: Profile); - /** Give the name of the current focus plugin */ - abstract currentFocus(): string; - /** Display the view inside the host */ - abstract focus(name: string): void; - /** Add the view of a plugin into the DOM */ - abstract addView(profile: Profile, view: Element): void; - /** Remove the plugin from the view from the DOM */ - abstract removeView(profile: Profile): void; - } +declare type EventParams> = T extends Api +? Parameters +: any[] +declare interface Folder { + [path: string]: { + isDirectory: boolean + } } -declare module 'packages/engine/web/src/lib/view' { - import type { Profile, LocationProfile } from '@remixproject/plugin-utils'; - import { Plugin } from '@remixproject/engine'; - export function isView

(profile: Profile): profile is (ViewProfile & P); - export type ViewProfile = Profile & LocationProfile; - export abstract class ViewPlugin extends Plugin { - profile: ViewProfile; - abstract render(): Element; - constructor(profile: ViewProfile); - activate(): Promise; - deactivate(): void; - } +declare interface FunctionDescription { + /** Type of the method. default is 'function' */ + type?: 'function' | 'constructor' | 'fallback' + /** The name of the function. Constructor and fallback functions never have a name */ + name?: string + /** List of parameters of the method. Fallback functions don’t have inputs. */ + inputs?: ABIParameter[] + /** List of the output parameters for the method, if any */ + outputs?: ABIParameter[] + /** State mutability of the method */ + stateMutability: 'pure' | 'view' | 'nonpayable' | 'payable' + /** true if function accepts Ether, false otherwise. Default is false */ + payable?: boolean + /** true if function is either pure or view, false otherwise. Default is false */ + constant?: boolean } -declare module 'packages/engine/web/src/index' { - export * from 'packages/engine/web/src/lib/iframe'; - export * from 'packages/engine/web/src/lib/ws'; - export * from 'packages/engine/web/src/lib/theme'; - export * from 'packages/engine/web/src/lib/window'; - export * from 'packages/engine/web/src/lib/web-worker'; - export * from 'packages/engine/web/src/lib/host'; - export * from 'packages/engine/web/src/lib/view'; -} -declare module 'packages/engine/web/tests/iframe.spec' { - export {}; +declare type GetPluginService> = S extends IPluginService ? S : IPluginService -} -declare module 'packages/engine/web/tests/view.spec' { - /// - import { Engine } from 'packages/engine/core/src'; - export class MockEngine extends Engine { - onRegistration: jest.Mock; - } +/** Throw an error if client try to send a message before connection */ +export declare function handleConnectionError(devMode?: Partial): void; +declare interface HighLightOptions { + focus: boolean } -declare module 'packages/engine/web/tests/websocket.spec' { - export {}; +declare interface HighlightPosition { + start: { + line: number + column: number + } + end: { + line: number + column: number + } } -declare module 'packages/plugin/child-process/src/lib/connector' { - import { ClientConnector, Client, PluginClient } from '@remixproject/plugin'; - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export interface WS { - send(data: string): void; - on(type: 'message', cb: (event: string) => any): this; - } - /** - * This Websocket connector works with the library ws - */ - export class WebsocketConnector implements ClientConnector { - private websocket; - constructor(websocket: WS); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - * - * --------- - * @example - * typescript - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws) - * }) - * - * --------- - * @example - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws, new MyPlugin()) - * }) - * - */ - export const createClient:

> = Readonly>(websocket: WS, client?: PluginClient) => Client; +declare interface ICompiler extends Api { + events: { + compilationFinished: ( + fileName: string, + source: CompilationFileSources, + languageVersion: string, + data: CompilationResult + ) => void + } & StatusEvents + methods: { + getCompilationResult(): lastCompilationResult + compile(fileName: string): void + setCompilerConfig(settings: CondensedCompilationInput): void + compileWithParameters(targets: SourcesInput, settings: CondensedCompilationInput): lastCompilationResult + } } -declare module 'packages/plugin/child-process/src/index' { - export * from 'packages/plugin/child-process/src/lib/connector'; +declare interface IContentImport { + events: {} & StatusEvents + methods: { + resolve(path: string): ContentImport + resolveAndSave (url:string, targetPath: string): string + } } -declare module 'packages/plugin/core/tests/api.spec' { - export {}; -} -declare module 'packages/plugin/core/tests/client.spec' { - export {}; +declare interface IDgitSystem { + events: StatusEvents + methods: { + init(): void; + add(cmd: any): string; + commit(cmd: any): string; + status(cmd: any): any[]; + rm(cmd: any): string; + log(cmd: any): any[]; + lsfiles(cmd: any): any[]; + readblob(cmd: any): { oid: string, blob: Uint8Array } + resolveref(cmd: any): string + branch(cmd: any): void + checkout(cmd: any): void + branches(): string[] + currentbranch(): string + push(cmd: any): string + pull(cmd: any): void + setIpfsConfig(config:any): boolean + zip():void + setItem(name:string, content:string):void + getItem(name: string): string + import(cmd: any): void + export(cmd: any): void + remotes(): any[] + addremote(cmd: any): void + delremote(cmd: any): void + clone(cmd: any): void + localStorageUsed(): any + }; +} + +declare interface IEditor { + events: StatusEvents + methods: { + highlight( + position: HighlightPosition, + filePath: string, + hexColor: string, + opt?: HighLightOptions + ): void + discardHighlight(): void + discardHighlightAt(line: number, filePath: string): void + addAnnotation(annotation: Annotation): void + clearAnnotations(): void + gotoLine(line:number, col:number): void + } } -declare module 'packages/plugin/core/tests/node.spec' { - export {}; +declare interface IFilePanel { + events: { + setWorkspace: (workspace:any) => void + workspaceRenamed: (workspace:any) => void + workspaceDeleted: (workspace:any) => void + workspaceCreated: (workspace:any) => void + customAction: (cmd: customAction) => void + } & StatusEvents + methods: { + getCurrentWorkspace(): { name: string, isLocalhost: boolean, absolutePath: string } + getWorkspaces(): string[] + deleteWorkspace(name:string): void + createWorkspace(name:string, isEmpty:boolean): void + renameWorkspace(oldName:string, newName:string): void + registerContextMenuItem(cmd: customAction): void + } } -declare module 'packages/plugin/core/tests/origin.spec' { - export {}; +declare interface IFileSystem { + events: { + currentFileChanged: (file: string) => void + fileSaved: (file: string) => void + fileAdded: (file: string) => void + folderAdded: (file: string) => void + fileRemoved: (file: string) => void + fileClosed: (file: string) => void + noFileSelected: ()=> void + fileRenamed: (oldName: string, newName:string, isFolder: boolean) => void + } & StatusEvents + methods: { + /** Open the content of the file in the context (eg: Editor) */ + open(path: string): void + /** Set the content of a specific file */ + writeFile(path: string, data: string): void + /** Return the content of a specific file */ + readFile(path: string): string + /** Change the path of a file */ + rename(oldPath: string, newPath: string): void + /** Upsert a file with the content of the source file */ + copyFile(src: string, dest: string): void + /** Create a directory */ + mkdir(path: string): void + /** Get the list of files in the directory */ + readdir(path: string): string[] + /** Removes a file or directory recursively */ + remove(path: string): void + /** Get the name of the file currently focused if any */ + getCurrentFile(): string + /** close all files */ + closeAllFiles(): void + /** close a file */ + closeFile(): void + // Old API + /** @deprecated Use readdir */ + getFolder(path: string): Folder + /** @deprecated Use readFile */ + getFile(path: string): string + /** @deprecated Use writeFile */ + setFile(path: string, content: string): void + /** @deprecated Use open */ + switchFile(path: string): void + } } -declare module 'packages/plugin/core/tests/remix-api.spec' { - export {}; +/** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ +declare interface INetwork { + events: { + providerChanged: (provider: NetworkProvider) => void + } & StatusEvents + methods: { + getNetworkProvider(): NetworkProvider + detectNetwork(): Network | Partial + getEndpoint(): string + addNetwork(network: CustomNetwork): void + removeNetwork(name: string): void + } } -declare module 'packages/plugin/core/tests/service.spec' { - export {}; +declare interface IPluginManager { + events: { + profileUpdated(profile: Profile): void + profileAdded(profile: Profile): void + pluginDeactivated(profile: Profile): void + pluginActivated(profile: Profile): void + } & StatusEvents + methods: { + getProfile(name: string): Promise + updateProfile(profile: Partial): any + activatePlugin(name: string): any + deactivatePlugin(name: string): any + isActive(name: string): boolean + canCall(from: string, to: string, method: string, message?: string): any + } } -declare module 'packages/plugin/iframe/src/lib/theme' { - import { PluginClient, PluginOptions } from '@remixproject/plugin'; - /** Start listening on theme changed */ - export function listenOnThemeChanged(client: PluginClient, options?: Partial>): Promise; +declare type IPluginService = any> = { + methods: string[] + readonly path: string +} & T + +declare interface IRemixApi { + manager: IPluginManager, + solidity: ICompiler + fileManager: IFileSystem + filePanel: IFilePanel + dGitProvider: IDgitSystem + solidityUnitTesting: IUnitTesting + editor: IEditor + network: INetwork + udapp: IUdapp + contentImport: IContentImport + settings: ISettings + theme: ITheme + vscodeExtAPI: IVScodeExtAPI + terminal: ITerminal +} + +declare interface ISettings { + events: {} & StatusEvents + methods: { + getGithubAccessToken(): string + } } -declare module 'packages/plugin/iframe/src/lib/connector' { - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - import { ClientConnector, Client, PluginClient, PluginOptions } from '@remixproject/plugin'; - export class IframeConnector implements ClientConnector { - private options; - source: Window; - origin: string; - constructor(options: PluginOptions); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect an Iframe client to a web engine - * @param client An optional iframe client to connect to the engine - * @example Let the function create a client - * typescript - * const client = createClient() - * - * @example With a custom client - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const client = createClient(new MyPlugin()) - * - */ - export const createClient:

> = Readonly>(client?: PluginClient) => Client; +declare interface ITerminal { + events: { + } & StatusEvents + methods: { + log(message: TerminalMessage): void + } } -declare module 'packages/plugin/iframe/src/index' { - export * from 'packages/plugin/iframe/src/lib/connector'; - export * from 'packages/plugin/iframe/src/lib/theme'; +declare interface ITheme { + events: { + themeChanged: (theme: Theme) => void + } & StatusEvents + methods: { + currentTheme(): Theme + } } -declare module 'packages/plugin/iframe/tests/iframe.spec' { - export {}; +declare interface IUdapp { + events: { + newTransaction: (transaction: RemixTxEvent) => void + } & StatusEvents + methods: { + sendTransaction(tx: RemixTx): RemixTxReceipt + getAccounts(): string[] + createVMAccount(vmAccount: VMAccount): string + getSettings(): UdappSettings + setEnvironmentMode(env: 'vm' | 'injected' | 'web3'): void + } } -declare module 'packages/plugin/vscode/src/lib/webview' { - import type { Message, Api } from '@remixproject/plugin-utils'; - import { ClientConnector, Client, PluginClient, PluginOptions } from '@remixproject/plugin'; - /** - * This Webview connector - */ - export class WebviewConnector implements ClientConnector { - private options; - source: { - postMessage: (message: any, origin?: string) => void; - }; - origin: string; - isVscode: boolean; - constructor(options?: Partial>); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Webview plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

>>(client?: PluginClient) => Client; +declare interface IUnitTesting { + events: {} & StatusEvents + methods: { + testFromPath(path: string): UnitTestResult + testFromSource(sourceCode: string): UnitTestResult + } } -declare module 'packages/plugin/vscode/src/lib/extension' { - export {}; +declare interface IVScodeExtAPI { + events: { + } & StatusEvents + methods: { + executeCommand(extension: string, command: string, payload?: any[]): any + } } -declare module 'packages/plugin/vscode/src/index' { - export * from 'packages/plugin/vscode/src/lib/webview'; - export * from 'packages/plugin/vscode/src/lib/extension'; +declare interface lastCompilationResult { + data: CompilationResult | null + source: SourceWithTarget | null | undefined +} + +declare type MethodKey = Extract + +declare type MethodParams> = T extends Api +? Parameters +: any[] + +declare type Network = +| { id: '1', name: 'Main' } +| { id: '2', name: 'Morden (deprecated)' } +| { id: '3', name: 'Ropsten' } +| { id: '4', name: 'Rinkeby' } +| { id: '5', name: 'Goerli' } +| { id: '42', name: 'Kovan' } + +/** @deprecated: current version in Remix IDE. To improve to match standard JSON RPC methods */ +declare type NetworkProvider = 'vm' | 'injected' | 'web3' + +declare interface PluginBase { + methods: string[], + activateService: Record Promise> + /** Listen on an event from another plugin */ + on, Key extends EventKey>( + name: Name, + key: Key, + cb: EventCallback, + ): void + + /** Listen one time on an event from another plugin, then remove event listener */ + once, Key extends EventKey>( + name: Name, + key: Key, + cb: EventCallback, + ): void + + /** Stop listening on an event from another plugin */ + off, Key extends EventKey>( + name: Name, + key: Key, + ): void + + /** Call a method of another plugin */ + call, Key extends MethodKey>( + name: Name, + key: Key, + ...payload: MethodParams + ): Promise + + /** Clear calls in queue of a plugin called by plugin */ + cancel, Key extends MethodKey>( + name: Name, + key: Key, + ): void + + /** Emit an event */ + emit>(key: Key, ...payload: EventParams): void +} + +export declare class PluginClient implements PluginBase { + private id; + isLoaded: boolean; + events: EventEmitter; + currentRequest: PluginRequest; + options: PluginOptions; + name: string; + methods: string[]; + activateService: Record Promise>; + onActivation?(): void; + constructor(options?: Partial>); + onload(cb?: () => void): Promise; + /** + * Ask the plugin manager if current request can call a specific method + * @param method The method to call + * @param message An optional message to show to the user + */ + askUserPermission(method: MethodKey, message?: string): Promise; + /** + * Called before deactivating the plugin + * @param from profile of plugin asking to deactivate + * @note PluginManager will always be able to deactivate + */ + canDeactivate(from: Profile): boolean; + /** Make a call to another plugin */ + call, Key extends MethodKey>(name: Name, key: Key, ...payload: MethodParams): Promise>; + /** Listen on event from another plugin */ + on, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; + /** Listen once on event from another plugin */ + once, Key extends EventKey>(name: Name, key: Key, cb: EventCallback): void; + /** Remove all listeners on an event from an external plugin */ + off, Key extends EventKey>(name: Name, key: Key): void; + /** Expose an event for the IDE */ + emit>(key: Key, ...payload: EventParams): void; + /** + * Create a service under the client node + * @param name The name of the service + * @param service The service + */ + createService, Service extends IPluginService>(name: string, service: Service): Promise>; + /** + * Prepare a service to be lazy loaded + * @param name The name of the subservice inside this service + * @param factory A function to create the service on demand + */ + prepareService>(name: string, factory: () => S): () => Promise>; +} + +export declare interface PluginDevMode { + /** Port for localhost */ + port: number | string; + origins: string | string[]; +} + +/** Options of the plugin client */ +export declare interface PluginOptions { + customTheme: boolean; + /** define a set of custom apis to implements on the client */ + customApi: ProfileMap; + /** + * Allow a set of origins + * You can either a list of origin or a url with a link of origins + */ + allowOrigins: string | string[]; + /** + * options only available for dev mode + * @deprecated use allowOrigins instead if you want to limit the parent origin + */ + devMode: Partial; +} + +declare interface PluginRequest { + /** The name of the plugin making the request */ + from: string, + /** @deprecated Will be remove in the next version */ + isFromNative?: boolean, + /** + * The path to access the request inside the plugin + * @example 'remixd.cmd.git' + */ + path?: string +} + +/** Describe a plugin */ +declare interface Profile { + name: string + displayName?: string + methods?: MethodKey[] + events?: EventKey[] + permission?: boolean + hash?: string + description?: string + documentation?: string + version?: string + kind?: string, + canActivate?: string[], + icon?: string +} + +/** A map of profile */ +declare type ProfileMap = Partial<{ + [name in keyof T]: Profile +}> + +declare type RemixApi = Readonly + +declare interface RemixTx { + data: string + from: string + to?: string + timestamp?: string + gasLimit: string + value: string + useCall: boolean +} + +declare type RemixTxEvent = { + contractAddress: string + data: string + envMode: 'vm' + executionCost: string + from: string + gas: string + hash: string + input: string + logs: any[] + returnValue: Uint8Array + status: '0x01' | '0x00' + transactionCost: string + transactionHash: string + value: string +} | { + blockHash: string + blockNumber: number + envMod: 'injected' | 'web3' + from: string + gas: number + gasPrice: { c: number[], e: number, s: number } + hash: string + input: string + none: number + r: string + s: string + v: string + status: '0x01' | '0x00' + to: string + transactionCost: string + transactionIndex: number + value: { c: number[], e: number, s: number } +} + +declare interface RemixTxReceipt { + transactionHash: string + status: 0 | 1 + gasUsed: string + error: string + return: string + createdAddress?: string +} + +declare interface SourceInputContent { + /** Hash of the source file. */ + keccak256?: string + /** Literal contents of the source file */ + content: string +} + +declare interface SourceInputUrls { + /** Hash of the source file. It is used to verify the retrieved content imported via URLs */ + keccak256?: string + /** + * URL(s) to the source file. + * URL(s) should be imported in this order and the result checked against the + * keccak256 hash (if available). If the hash doesn't match or none of the + * URL(s) result in success, an error should be raised. + */ + urls: string[] +} + +declare interface SourcesInput { + [contractName: string]: SourceInputContent | SourceInputUrls +} + +declare interface SourceWithTarget { + sources?: CompilationFileSources, + target?: string | null | undefined +} + +declare interface Status { + /** Display an icon or number */ + key: number | 'edited' | 'succeed' | 'loading' | 'failed' | 'none' + /** Bootstrap css color */ + type?: 'success' | 'info' | 'warning' | 'error' + /** Describe the status on mouseover */ + title?: string +} + +declare type StatusEvents = { + statusChanged: (status: Status) => void +} + +declare type TerminalMessage = { + value: any, + type: 'html' | 'log' | 'info' | 'warn' | 'error' +} + +declare interface Theme { + url?: string + /** @deprecated Use brightness instead */ + quality?: 'dark' | 'light' + brightness: 'dark' | 'light' + colors: { + surface: string + background: string + foreground: string + primary: string + primaryContrast: string + secondary?: string + secondaryContrast?: string + success?: string + successContrast?: string + warn: string + warnContrast: string + error: string + errorContrast: string + disabled: string + } + breakpoints: { + xs: number + sm: number + md: number + lg: number + xl: number + } + fontFamily: string + /** A unit to multiply for margin & padding */ + space: number } -declare module 'packages/plugin/webview/src/lib/connector' { - import type { Message, Api, PluginApi } from '@remixproject/plugin-utils'; - import { ClientConnector, PluginClient, PluginOptions } from '@remixproject/plugin'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; global { - function acquireTheiaApi(): any; - } - /** - * This Webview connector - */ - export class WebviewConnector implements ClientConnector { - private options; - source: { - postMessage: (message: any, origin?: string) => void; - }; - origin: string; - isVscode: boolean; - constructor(options: PluginOptions); - /** Send a message to the engine */ - send(message: Partial): void; - /** Get messae from the engine */ - on(cb: (message: Partial) => void): void; - pasteClipBoard(event: any): void; - insertAtCursor(element: any, value: any): void; - forwardEvents(): void; - } - /** - * Connect a Webview plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

> = Readonly, C extends PluginClient = any>(client: C) => C & PluginApi; +declare interface UdappSettings { + selectedAccount:string + selectedEnvMode: 'vm' | 'injected' | 'web3' + networkEnvironment: string } -declare module 'packages/plugin/webview/src/index' { - export * from 'packages/plugin/webview/src/lib/connector'; +declare interface UnitTestError { + context: string + value: string + message: string } -declare module 'packages/plugin/webworker/src/lib/connector' { - /// - import { ClientConnector, Client, PluginClient } from '@remixproject/plugin'; - import type { Message, Api } from '@remixproject/plugin-utils'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export class WebworkerConnector implements ClientConnector { - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - */ - export const createClient:

> = Readonly>(client?: PluginClient) => Client; +declare interface UnitTestResult { + totalFailing: number + totalPassing: number + totalTime: number + errors: UnitTestError[] } -declare module 'packages/plugin/webworker/src/index' { - export * from 'packages/plugin/webworker/src/lib/connector'; +declare interface UserDocumentation { + methods: UserMethodList + notice: string } -declare module 'packages/plugin/ws/src/lib/ws' { - import { Message, Api } from '@remixproject/plugin-utils'; - import { PluginClient, ClientConnector, Client } from '@remixproject/plugin'; - import { IRemixApi } from 'packages/api/src/lib/remix-profile'; - export interface WS { - send(data: string): void; - on(type: 'message', cb: (event: string) => any): this; - } - /** - * This Websocket connector works with the library ws - */ - export class WebsocketConnector implements ClientConnector { - private websocket; - private client; - constructor(websocket: WS); - setClient(client: PluginClient): void; - /** Send a message to the engine */ - send(message: Partial): void; - /** Get message from the engine */ - on(cb: (message: Partial) => void): void; - } - /** - * Connect a Websocket plugin client to a web engine - * @param client An optional websocket plugin client to connect to the engine. - * - * --------- - * @example - * typescript - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws) - * }) - * - * --------- - * @example - * typescript - * class MyPlugin extends PluginClient { - * methods = ['hello'] - * hello() { - * console.log('Hello World') - * } - * } - * const wss = new WebSocket.Server({ port: 8080 }); - * wss.on('connection', (ws) => { - * const client = createClient(ws, new MyPlugin()) - * }) - * - */ - export const createClient:

> = Readonly>(websocket: WS, client?: PluginClient) => Client; +declare interface UserMethodDoc { + notice: string } -declare module 'packages/plugin/ws/src/index' { - export * from 'packages/plugin/ws/src/lib/ws'; +declare type UserMethodList = { + [functionIdentifier: string]: UserMethodDoc +} & { + 'constructor'?: string } -declare module 'packages/utils/tests/event-name.spec' { - export {}; +declare interface VMAccount { + privateKey: string + balance: string } -declare module 'packages/utils/tests/method-path.spec' { - export {}; -} -` +export { } +` \ No newline at end of file diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 0c718a8865..7787daeddf 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -75,6 +75,25 @@ export interface EditorUIProps { export const EditorUI = (props: EditorUIProps) => { const [, setCurrentBreakpoints] = useState({}) + const defaultEditorValue = ` + \t\t\t\t\t\t\t ____ _____ __ __ ___ __ __ ___ ____ _____ + \t\t\t\t\t\t\t| _ \\ | ____| | \\/ | |_ _| \\ \\/ / |_ _| | _ \\ | ____| + \t\t\t\t\t\t\t| |_) | | _| | |\\/| | | | \\ / | | | | | | | _| + \t\t\t\t\t\t\t| _ < | |___ | | | | | | / \\ | | | |_| | | |___ + \t\t\t\t\t\t\t|_| \\_\\ |_____| |_| |_| |___| /_/\\_\\ |___| |____/ |_____|\n\n + \t\t\t\t\t\t\tKeyboard Shortcuts:\n + \t\t\t\t\t\t\t\tCTRL + S: Compile the current contract\n + \t\t\t\t\t\t\t\tCtrl + Shift + F : Open the File Explorer\n + \t\t\t\t\t\t\t\tCtrl + Shift + A : Open the Plugin Manager\n + \t\t\t\t\t\t\t\tCTRL + SHIFT + S: Compile the current contract & Run an associated script\n\n + \t\t\t\t\t\t\tImportant Links:\n + \t\t\t\t\t\t\t\tOfficial website about the Remix Project: https://remix-project.org/\n + \t\t\t\t\t\t\t\tOfficial documentation: https://remix-ide.readthedocs.io/en/latest/\n + \t\t\t\t\t\t\t\tGithub: https://github.com/ethereum/remix-project\n + \t\t\t\t\t\t\t\tGitter: https://gitter.im/ethereum/remix\n + \t\t\t\t\t\t\t\tMedium: https://medium.com/remix-ide\n + \t\t\t\t\t\t\t\tTwitter: https://twitter.com/ethereumremix\n + ` const editorRef = useRef(null) const monacoRef = useRef(null) const currentFileRef = useRef('') @@ -422,7 +441,8 @@ export const EditorUI = (props: EditorUIProps) => { language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'} onMount={handleEditorDidMount} beforeMount={handleEditorWillMount} - options={{ glyphMargin: true }} + options={{ glyphMargin: true, readOnly: true}} + defaultValue={defaultEditorValue} />

{ // ethers.js // @ts-ignore const ethersAbi = await import('raw-loader!@ethersproject/abi/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbi.default, `file:///node_modules/@types/@ethersproject/abi/index.d.ts`) + ethersAbi.default = ethersAbi.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbi.default, `file:///node_modules/@types/@ethersproject_abi/index.d.ts`) // @ts-ignore const ethersAbstract = await import('raw-loader!@ethersproject/abstract-provider/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbstract.default, `file:///node_modules/@types/@ethersproject/abstract-provider/index.d.ts`) + ethersAbstract.default = ethersAbstract.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbstract.default, `file:///node_modules/@types/@ethersproject_abstract-provider/index.d.ts`) // @ts-ignore const ethersSigner = await import('raw-loader!@ethersproject/abstract-signer/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSigner.default, `file:///node_modules/@types/@ethersproject/abstract-signer/index.d.ts`) + ethersSigner.default = ethersSigner.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSigner.default, `file:///node_modules/@types/@ethersproject_abstract-signer/index.d.ts`) // @ts-ignore const ethersAddress = await import('raw-loader!@ethersproject/address/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAddress.default, `file:///node_modules/@types/@ethersproject/address/index.d.ts`) + ethersAddress.default = ethersAddress.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAddress.default, `file:///node_modules/@types/@ethersproject_address/index.d.ts`) // @ts-ignore const ethersBase64 = await import('raw-loader!@ethersproject/base64/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBase64.default, `file:///node_modules/@types/@ethersproject/base64/index.d.ts`) + ethersBase64.default = ethersBase64.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBase64.default, `file:///node_modules/@types/@ethersproject_base64/index.d.ts`) // @ts-ignore const ethersBasex = await import('raw-loader!@ethersproject/basex/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBasex.default, `file:///node_modules/@types/@ethersproject/basex/index.d.ts`) + ethersBasex.default = ethersBasex.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBasex.default, `file:///node_modules/@types/@ethersproject_basex/index.d.ts`) // @ts-ignore const ethersBignumber = await import('raw-loader!@ethersproject/bignumber/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBignumber.default, `file:///node_modules/@types/@ethersproject/bignumber/index.d.ts`) + ethersBignumber.default = ethersBignumber.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBignumber.default, `file:///node_modules/@types/@ethersproject_bignumber/index.d.ts`) // @ts-ignore const ethersBytes = await import('raw-loader!@ethersproject/bytes/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBytes.default, `file:///node_modules/@types/@ethersproject/bytes/index.d.ts`) + ethersBytes.default = ethersBytes.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBytes.default, `file:///node_modules/@types/@ethersproject_bytes/index.d.ts`) // @ts-ignore const ethersConstants = await import('raw-loader!@ethersproject/constants/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersConstants.default, `file:///node_modules/@types/@ethersproject/constants/index.d.ts`) + ethersConstants.default = ethersConstants.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersConstants.default, `file:///node_modules/@types/@ethersproject_constants/index.d.ts`) // @ts-ignore const ethersContracts = await import('raw-loader!@ethersproject/contracts/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersContracts.default, `file:///node_modules/@types/@ethersproject/contracts/index.d.ts`) + ethersContracts.default = ethersContracts.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersContracts.default, `file:///node_modules/@types/@ethersproject_contracts/index.d.ts`) // @ts-ignore const ethersHash = await import('raw-loader!@ethersproject/hash/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHash.default, `file:///node_modules/@types/@ethersproject/lib/index.d.ts`) + ethersHash.default = ethersHash.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHash.default, `file:///node_modules/@types/@ethersproject_hash/index.d.ts`) // @ts-ignore const ethersHdnode = await import('raw-loader!@ethersproject/hdnode/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHdnode.default, `file:///node_modules/@types/@ethersproject/hdnode/index.d.ts`) + ethersHdnode.default = ethersHdnode.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHdnode.default, `file:///node_modules/@types/@ethersproject_hdnode/index.d.ts`) // @ts-ignore const ethersJsonWallets = await import('raw-loader!@ethersproject/json-wallets/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersJsonWallets.default, `file:///node_modules/@types/@ethersproject/json-wallets/index.d.ts`) + ethersJsonWallets.default = ethersJsonWallets.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersJsonWallets.default, `file:///node_modules/@types/@ethersproject_json-wallets/index.d.ts`) // @ts-ignore const ethersKeccak256 = await import('raw-loader!@ethersproject/keccak256/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersKeccak256.default, `file:///node_modules/@types/@ethersproject/keccak256/index.d.ts`) + ethersKeccak256.default = ethersKeccak256.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersKeccak256.default, `file:///node_modules/@types/@ethersproject_keccak256/index.d.ts`) // @ts-ignore const ethersLogger = await import('raw-loader!@ethersproject/logger/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersLogger.default, `file:///node_modules/@types/@ethersproject/logger/index.d.ts`) + ethersLogger.default = ethersLogger.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersLogger.default, `file:///node_modules/@types/@ethersproject_logger/index.d.ts`) // @ts-ignore const ethersNetworks = await import('raw-loader!@ethersproject/networks/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersNetworks.default, `file:///node_modules/@types/@ethersproject/networks/index.d.ts`) + ethersNetworks.default = ethersNetworks.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersNetworks.default, `file:///node_modules/@types/@ethersproject_networks/index.d.ts`) // @ts-ignore const ethersPbkdf2 = await import('raw-loader!@ethersproject/pbkdf2/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPbkdf2.default, `file:///node_modules/@types/@ethersproject/pbkdf2/index.d.ts`) + ethersPbkdf2.default = ethersPbkdf2.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPbkdf2.default, `file:///node_modules/@types/@ethersproject_pbkdf2/index.d.ts`) // @ts-ignore const ethersProperties = await import('raw-loader!@ethersproject/properties/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProperties.default, `file:///node_modules/@types/@ethersproject/properties/index.d.ts`) + ethersProperties.default = ethersProperties.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProperties.default, `file:///node_modules/@types/@ethersproject_properties/index.d.ts`) // @ts-ignore const ethersProviders = await import('raw-loader!@ethersproject/providers/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProviders.default, `file:///node_modules/@types/@ethersproject/providers/index.d.ts`) + ethersProviders.default = ethersProviders.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProviders.default, `file:///node_modules/@types/@ethersproject_providers/index.d.ts`) // @ts-ignore const ethersRandom = await import('raw-loader!@ethersproject/random/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRandom.default, `file:///node_modules/@types/@ethersproject/random/index.d.ts`) + ethersRandom.default = ethersRandom.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRandom.default, `file:///node_modules/@types/@ethersproject_random/index.d.ts`) // @ts-ignore const ethersRlp = await import('raw-loader!@ethersproject/rlp/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRlp.default, `file:///node_modules/@types/@ethersproject/rlp/index.d.ts`) + ethersRlp.default = ethersRlp.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRlp.default, `file:///node_modules/@types/@ethersproject_rlp/index.d.ts`) // @ts-ignore const ethersSha2 = await import('raw-loader!@ethersproject/sha2/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSha2.default, `file:///node_modules/@types/@ethersproject/sha2/index.d.ts`) + ethersSha2.default = ethersSha2.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSha2.default, `file:///node_modules/@types/@ethersproject_sha2/index.d.ts`) // @ts-ignore const ethersSingningkey = await import('raw-loader!@ethersproject/signing-key/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSingningkey.default, `file:///node_modules/@types/@ethersproject/signing-key/index.d.ts`) + ethersSingningkey.default = ethersSingningkey.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSingningkey.default, `file:///node_modules/@types/@ethersproject_signing-key/index.d.ts`) // @ts-ignore const ethersSolidity = await import('raw-loader!@ethersproject/solidity/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSolidity.default, `file:///node_modules/@types/@ethersproject/solidity/index.d.ts`) + ethersSolidity.default = ethersSolidity.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSolidity.default, `file:///node_modules/@types/@ethersproject_solidity/index.d.ts`) // @ts-ignore const ethersStrings = await import('raw-loader!@ethersproject/strings/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersStrings.default, `file:///node_modules/@types/@ethersproject/strings/index.d.ts`) + ethersStrings.default = ethersStrings.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersStrings.default, `file:///node_modules/@types/@ethersproject_strings/index.d.ts`) // @ts-ignore const ethersTransactions = await import('raw-loader!@ethersproject/transactions/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersTransactions.default, `file:///node_modules/@types/@ethersproject/transactions/index.d.ts`) + ethersTransactions.default = ethersTransactions.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersTransactions.default, `file:///node_modules/@types/@ethersproject_transactions/index.d.ts`) // @ts-ignore const ethersUnits = await import('raw-loader!@ethersproject/units/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersUnits.default, `file:///node_modules/@types/@ethersproject/units/index.d.ts`) + ethersUnits.default = ethersUnits.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersUnits.default, `file:///node_modules/@types/@ethersproject_units/index.d.ts`) // @ts-ignore const ethersWallet = await import('raw-loader!@ethersproject/wallet/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWallet.default, `file:///node_modules/@types/@ethersproject/wallet/index.d.ts`) + ethersWallet.default = ethersWallet.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWallet.default, `file:///node_modules/@types/@ethersproject_wallet/index.d.ts`) // @ts-ignore const ethersWeb = await import('raw-loader!@ethersproject/web/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWeb.default, `file:///node_modules/@types/@ethersproject/web/index.d.ts`) + ethersWeb.default = ethersWeb.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWeb.default, `file:///node_modules/@types/@ethersproject_web/index.d.ts`) // @ts-ignore const ethersWordlists = await import('raw-loader!@ethersproject/wordlists/lib/index.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWordlists.default, `file:///node_modules/@types/@ethersproject/wordlists/index.d.ts`) + ethersWordlists.default = ethersWordlists.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWordlists.default, `file:///node_modules/@types/@ethersproject_wordlists/index.d.ts`) + + // @ts-ignore + const versionEthers = await import('raw-loader!ethers/lib/_version.d.ts') + versionEthers.default = versionEthers.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(versionEthers.default, `file:///node_modules/@types/_version-ethers-lib/index.d.ts`) + + // @ts-ignore + const utilEthers = await import('raw-loader!ethers/lib/utils.d.ts') + utilEthers.default = utilEthers.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(utilEthers.default, `file:///node_modules/@types/utils-ethers-lib/index.d.ts`) // @ts-ignore const ethers = await import('raw-loader!ethers/lib/ethers.d.ts') - monaco.languages.typescript.typescriptDefaults.addExtraLib(ethers.default, `file:///node_modules/@types/ethers/ethers.d.ts`) + ethers.default = ethers.default.replace(/.\/utils/g, 'utils-ethers-lib') + ethers.default = ethers.default.replace(/.\/_version/g, '_version-ethers-lib') + ethers.default = ethers.default.replace(/.\/ethers/g, 'ethers-lib') + ethers.default = ethers.default.replace(/@ethersproject\//g, '@ethersproject_') + monaco.languages.typescript.typescriptDefaults.addExtraLib(ethers.default, `file:///node_modules/@types/ethers-lib/index.d.ts`) // @ts-ignore const indexEthers = await import('raw-loader!ethers/lib/index.d.ts') + indexEthers.default = indexEthers.default.replace(/.\/ethers/g, 'ethers-lib') + indexEthers.default = indexEthers.default.replace(/@ethersproject\//g, '@ethersproject_') monaco.languages.typescript.typescriptDefaults.addExtraLib(indexEthers.default, `file:///node_modules/@types/ethers/index.d.ts`) // Web3 @@ -151,6 +199,10 @@ export const loadTypes = async (monaco) => { const indexWeb3Personal = await import('raw-loader!web3-eth-personal/types/index.d.ts') monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Personal.default, `file:///node_modules/@types/web3-eth-personal/index.d.ts`) + // @ts-ignore + const indexWeb3Contract = await import('raw-loader!web3-eth-contract/types/index.d.ts') + monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Contract.default, `file:///node_modules/@types/web3-eth-contract/index.d.ts`) + // @ts-ignore const indexWeb3Net = await import('raw-loader!web3-net/types/index.d.ts') monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Net.default, `file:///node_modules/@types/web3-net/index.d.ts`) @@ -162,20 +214,13 @@ export const loadTypes = async (monaco) => { // @ts-ignore const indexWeb3Util = await import('raw-loader!web3-utils/types/index.d.ts') monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Util.default, `file:///node_modules/@types/web3-utils/index.d.ts`) - - - /* // remix - - // @ts-ignore - const indexRemixApi = await import('./remix-plugin-types') - monaco.languages.typescript.typescriptDefaults.addExtraLib(indexRemixApi.types) - */ - - monaco.languages.typescript.typescriptDefaults.addExtraLib(` - import { PluginClient } from 'packages/plugin/core/src/lib/client' - declare const remix: PluginClient - `) - + const indexRemixApi = remixTypes + `\n + declare global { + const remix: PluginClient; + const web3Provider; + } + ` + monaco.languages.typescript.typescriptDefaults.addExtraLib(indexRemixApi) console.log('loaded monaco types') } \ No newline at end of file diff --git a/libs/remix-ui/helper/src/lib/helper-components.tsx b/libs/remix-ui/helper/src/lib/helper-components.tsx index e04e162ffc..c290f7bdf9 100644 --- a/libs/remix-ui/helper/src/lib/helper-components.tsx +++ b/libs/remix-ui/helper/src/lib/helper-components.tsx @@ -78,3 +78,9 @@ export const storageFullMessage = () => (
) + +export const recursivePasteToastMsg = () => ( +
+ File(s) to paste is an ancestor of the destination folder +
+) diff --git a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts index 9ebf87741a..71abad338d 100644 --- a/libs/remix-ui/helper/src/lib/remix-ui-helper.ts +++ b/libs/remix-ui/helper/src/lib/remix-ui-helper.ts @@ -56,15 +56,15 @@ export const joinPath = (...paths) => { export const getPathIcon = (path: string) => { return path.endsWith('.txt') ? 'far fa-file-alt' : path.endsWith('.md') - ? 'far fa-file-alt' : path.endsWith('.sol') + ? 'fab fa-markdown' : path.endsWith('.sol') ? 'fak fa-solidity-mono' : path.endsWith('.js') ? 'fab fa-js' : path.endsWith('.json') - ? 'fas fa-brackets-curly' : path.endsWith('.vy') - ? 'fak fa-vyper-mono' : path.endsWith('.lex') + ? 'small fas fa-brackets-curly' : path.endsWith('.vy') + ? 'small fak fa-vyper2' : path.endsWith('.lex') ? 'fak fa-lexon' : path.endsWith('ts') - ? 'fad fa-brackets-curly' : path.endsWith('.contract') - ? 'fab fa-ethereum' : path.endsWith('.cairo') - ? 'fab fa-ethereum' : 'far fa-file' // TODO: add cairo icon + ? 'small fak fa-ts-logo' : path.endsWith('.tsc') + ? 'fad fa-brackets-curly' : path.endsWith('.cairo') + ? 'small fak fa-cairo' : 'far fa-file' } export const isNumeric = (value) => { diff --git a/libs/remix-ui/home-tab/src/lib/components/rssFeed.css b/libs/remix-ui/home-tab/src/lib/components/rssFeed.css new file mode 100644 index 0000000000..22e231c0e0 --- /dev/null +++ b/libs/remix-ui/home-tab/src/lib/components/rssFeed.css @@ -0,0 +1,12 @@ +.RSSFeed-item img { + width: 100%; +} + +.RSSFeed-item .truncate { + max-height: 500px; + overflow: hidden; +} + +.RSSFeed-item .more-button { + +} \ No newline at end of file diff --git a/libs/remix-ui/home-tab/src/lib/components/rssFeed.tsx b/libs/remix-ui/home-tab/src/lib/components/rssFeed.tsx new file mode 100644 index 0000000000..71df031d2f --- /dev/null +++ b/libs/remix-ui/home-tab/src/lib/components/rssFeed.tsx @@ -0,0 +1,42 @@ +import React, { useState, useEffect } from "react"; +import Parser from "rss-parser"; +import './rssFeed.css'; + +interface RSSFeedProps { + feedUrl: string, + maxItems: number, +} + +export function RSSFeed({ feedUrl, maxItems }: RSSFeedProps) { + const [feed, setFeed] = useState(null); + + useEffect(() => { + const fetchData = async () => { + const parser = new Parser() + const feed = await parser.parseURL(feedUrl); + for (const item of feed.items) { + item.content = item['content:encoded'] + item.date = new Date(item.pubDate).toLocaleDateString('en-US', { + month: 'short', + day: 'numeric' + }) + } + setFeed(feed); + }; + fetchData(); + }, [feedUrl]); + + + return (<> + {feed && feed.items.slice(0, maxItems).map((item: any, index: any) => ( +
+

{item.title}

+

Author: {item.creator}

+

{item.date}

+
+ READ MORE +
+
+ ))} + ) +} \ No newline at end of file diff --git a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx index 52c50c6dba..2690dfc840 100644 --- a/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx +++ b/libs/remix-ui/home-tab/src/lib/remix-ui-home-tab.tsx @@ -4,8 +4,8 @@ import './remix-ui-home-tab.css' import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line import { Toaster } from '@remix-ui/toaster' // eslint-disable-line import PluginButton from './components/pluginButton' // eslint-disable-line -import { QueryParams } from '@remix-project/remix-lib' import { ThemeContext, themes } from './themeContext' +import { RSSFeed } from './components/rssFeed' declare global { interface Window { _paq: any @@ -54,13 +54,16 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => { contentImport.import( state.importSource, (loadingMsg) => dispatch({ tooltip: loadingMsg }), - (error, content, cleanUrl, type, url) => { + async (error, content, cleanUrl, type, url) => { if (error) { toast(error.message || error) } else { try { - workspace.addExternal(type + '/' + cleanUrl, content, url) - plugin.call('menuicons', 'select', 'filePanel') + if (await workspace.exists(type + '/' + cleanUrl)) toast('File already exists in workspace') + else { + workspace.addExternal(type + '/' + cleanUrl, content, url) + plugin.call('menuicons', 'select', 'filePanel') + } } catch (e) { toast(e.message) } @@ -108,14 +111,8 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => { scriptTwitter.src = 'https://platform.twitter.com/widgets.js' scriptTwitter.async = true document.body.appendChild(scriptTwitter) - // to retrieve medium publications - const scriptMedium = document.createElement('script') - scriptMedium.src = 'https://www.twilik.com/assets/retainable/rss-embed/retainable-rss-embed.js' - scriptMedium.async = true - document.body.appendChild(scriptMedium) return () => { document.body.removeChild(scriptTwitter) - document.body.removeChild(scriptMedium) } }, []) @@ -285,7 +282,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => {

- +
@@ -341,17 +338,7 @@ export const RemixUiHomeTab = (props: RemixUiHomeTabProps) => { >