Merge branch 'pluginupdate' of https://github.com/ethereum/remix-project into pluginupdate

pull/3370/head
bunsenstraat 2 years ago
commit 9e60fff348
  1. 128
      .circleci/config.yml
  2. 13
      apps/debugger/.babelrc
  3. 2
      apps/debugger/src/app/debugger.ts
  4. 1
      apps/debugger/src/index.ts
  5. 1
      apps/debugger/tsconfig.app.json
  6. 109
      apps/debugger/webpack.config.js
  7. 3
      apps/etherscan/project.json
  8. 1
      apps/etherscan/tsconfig.app.json
  9. 4
      apps/etherscan/webpack.config.js
  10. 23
      apps/remix-ide-e2e/package.json
  11. 16
      apps/remix-ide-e2e/src/commands/journalLastChildIncludes.ts
  12. 9
      apps/remix-ide-e2e/src/local-plugin/.babelrc
  13. 1
      apps/remix-ide-e2e/src/local-plugin/.eslintrc
  14. 15
      apps/remix-ide-e2e/src/local-plugin/project.json
  15. 21
      apps/remix-ide-e2e/src/local-plugin/webpack.config.js
  16. 2
      apps/remix-ide-e2e/src/tests/etherscan_api.ts
  17. 2
      apps/remix-ide-e2e/src/tests/plugin_api.ts
  18. 8
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  19. 2
      apps/remix-ide-e2e/src/tests/remixd.test.ts
  20. 1
      apps/remix-ide-e2e/src/tests/runAndDeploy.test.ts
  21. 8
      apps/remix-ide-e2e/src/tests/specialFunctions.test.ts
  22. 1
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  23. 2
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  24. 2
      apps/remix-ide-e2e/src/tests/vyper_api.ts
  25. 3936
      apps/remix-ide-e2e/yarn.lock
  26. 2
      apps/remix-ide/.babelrc
  27. 3
      apps/remix-ide/ci/browser_test.sh
  28. 6
      apps/remix-ide/ci/browser_test_plugin.sh
  29. 26
      apps/remix-ide/ci/browser_tests_etherscan_plugin.sh
  30. 26
      apps/remix-ide/ci/browser_tests_vyper_plugin.sh
  31. 5
      apps/remix-ide/ci/flaky.sh
  32. 23
      apps/remix-ide/project.json
  33. 13
      apps/remix-ide/src/app.js
  34. 25
      apps/remix-ide/src/app/plugins/code-format.ts
  35. 11
      apps/remix-ide/src/app/plugins/parser/services/code-parser-compiler.ts
  36. 3
      apps/remix-ide/src/app/providers/abstract-provider.tsx
  37. 16
      apps/remix-ide/src/app/providers/injected-provider.tsx
  38. 2
      apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx
  39. 2
      apps/remix-ide/src/app/tabs/compile-and-run.ts
  40. 2
      apps/remix-ide/src/app/tabs/compile-tab.js
  41. 2
      apps/remix-ide/src/app/tabs/debugger-tab.js
  42. 14
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  43. 1
      apps/remix-ide/src/app/tabs/locales/zh/filePanel.json
  44. BIN
      apps/remix-ide/src/assets/img/remix-logo-blue.png
  45. 2
      apps/remix-ide/src/index.html
  46. 45
      apps/remix-ide/src/webpack.index.html
  47. 1
      apps/remix-ide/tsconfig.app.json
  48. 2
      apps/remix-ide/tsconfig.json
  49. 2
      apps/remix-ide/tsconfig.spec.json
  50. 3
      apps/remix-ide/webpack.config.js
  51. 9
      apps/solidity-compiler/.babelrc
  52. 2
      apps/solidity-compiler/src/app/compiler.ts
  53. 1
      apps/solidity-compiler/src/index.ts
  54. 1
      apps/solidity-compiler/tsconfig.app.json
  55. 127
      apps/solidity-compiler/webpack.config.js
  56. 3
      apps/vyper/project.json
  57. 108
      apps/vyper/webpack.config.js
  58. 2
      babel.config.js
  59. 4
      jest.preset.js
  60. 2
      libs/ghaction-helper/tsconfig.json
  61. 1
      libs/remix-core-plugin/package.json
  62. 5
      libs/remix-core-plugin/tsconfig.lib.json
  63. 2
      libs/remix-debug/src/index.ts
  64. 26
      libs/remix-solidity/jest.config.js
  65. 2
      libs/remix-solidity/tsconfig.json
  66. 2
      libs/remix-tests/tsconfig.spec.json
  67. 1
      libs/remix-ui/debugger-ui/src/index.ts
  68. 0
      libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts
  69. 1
      libs/remix-ui/editor/src/index.ts
  70. 4
      libs/remix-ui/editor/src/lib/actions/editor.ts
  71. 45
      libs/remix-ui/editor/src/lib/providers/completion/completionGlobals.ts
  72. 12
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts
  73. 6
      libs/remix-ui/editor/src/lib/providers/hoverProvider.ts
  74. 30
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  75. 23
      libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
  76. 1
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  77. 3
      libs/remix-ui/settings/src/lib/github-settings.tsx
  78. 1
      libs/remix-ui/solidity-compiler/src/index.ts
  79. 0
      libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts
  80. 2
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  81. 14
      libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx
  82. 2
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  83. 90
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  84. 51
      libs/remix-ui/workspace/src/lib/components/file-explorer-menu.tsx
  85. 9
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
  86. 2
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  87. 1
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  88. 7
      libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
  89. 4
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  90. 2
      libs/remix-ui/workspace/src/lib/types/index.ts
  91. 1
      libs/remix-ws-templates/package.json
  92. 2
      libs/remixd/tsconfig.spec.json
  93. 41
      package.json
  94. 3307
      yarn.lock

@ -24,23 +24,55 @@ jobs:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run: NX_BIN_URL=http://127.0.0.1:8080/assets/js NX_WASM_URL=http://127.0.0.1:8080/assets/js NPM_URL=http://localhost:9090/ yarn build:production
- run: yarn nx build remix-ide-e2e-src-local-plugin & yarn run build:libs
- run: yarn nx run debugger:build:production
- run: yarn nx run solidity-compiler:build:production
- run: yarn nx run remixd:build
- run:
name: Build
command: |
if [ "${CIRCLE_BRANCH}" == "master" ]; then
NX_BIN_URL=http://127.0.0.1:8080/assets/js NX_WASM_URL=http://127.0.0.1:8080/assets/js NPM_URL=http://localhost:9090/ yarn build:production
else
NX_BIN_URL=http://127.0.0.1:8080/assets/js NX_WASM_URL=http://127.0.0.1:8080/assets/js NPM_URL=http://localhost:9090/ yarn build
fi
- run: yarn run build:e2e
- run: mkdir persist && zip -0 -r persist/dist.zip dist
- persist_to_workspace:
root: .
paths:
- "persist"
build-plugin:
docker:
- image: cimg/node:14.17.6-browsers
resource_class:
xlarge
working_directory: ~/remix-project
parameters:
plugin:
type: string
steps:
- checkout
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- save_cache:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run: yarn build << parameters.plugin >>
- run: mkdir persist && zip -0 -r persist/plugin-<< parameters.plugin >>.zip dist
- persist_to_workspace:
root: .
paths:
- "persist"
lint:
docker:
- image: cimg/node:14.17.6-browsers
resource_class:
xlarge
working_directory: ~/remix-project
parallelism: 1
steps:
- checkout
- restore_cache:
@ -62,11 +94,11 @@ jobs:
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run: yarn build:libs
- run: cd dist/libs/remix-tests && yarn
- run: cd dist/libs/remix-tests && yarn add @remix-project/remix-url-resolver ../../libs/remix-url-resolver
- run: cd dist/libs/remix-tests && yarn add @remix-project/remix-lib ../../libs/remix-lib
@ -119,12 +151,8 @@ jobs:
- checkout
- attach_workspace:
at: .
- run: unzip ./persist/dist.zip
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run: unzip ./persist/dist.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- run: yarn run downloadsolc_assets_e2e && yarn run downloadsolc_assets_dist
- run: ls -la ./dist/apps/remix-ide/assets/js
- run: yarn run selenium-install || yarn run selenium-install
@ -151,9 +179,12 @@ jobs:
xlarge
working_directory: ~/remix-project
parameters:
script:
plugin:
type: string
parallelism: 4
parallelism:
type: integer
default: 1
parallelism: << parameters.parallelism >>
steps:
- browser-tools/install-browser-tools:
install-firefox: false
@ -166,19 +197,16 @@ jobs:
- checkout
- attach_workspace:
at: .
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run: unzip ./persist/dist.zip
- run: unzip ./persist/plugin-<< parameters.plugin >>.zip
- run: yarn install --cwd ./apps/remix-ide-e2e --modules-folder ../../node_modules
- run: yarn run downloadsolc_assets_e2e && yarn run downloadsolc_assets_dist
- run: yarn run selenium-install || yarn run selenium-install
- run:
name: Start Selenium
command: yarn run selenium
background: true
- run: ./apps/remix-ide/ci/<< parameters.script >>
- run: ./apps/remix-ide/ci/browser_test_plugin.sh << parameters.plugin >>
- store_test_results:
path: ./reports/tests
- store_artifacts:
@ -193,12 +221,19 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
- checkout
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- save_cache:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
@ -217,12 +252,19 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
- checkout
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- save_cache:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
@ -241,13 +283,19 @@ jobs:
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/*.css dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/index.html dist/apps/remix-ide/404.html dist/apps/remix-ide/*.js dist/apps/remix-ide/assets dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
- checkout
- restore_cache:
keys:
- v1-deps-{{ checksum "yarn.lock" }}
- run: yarn
- run: yarn run build:libs
- save_cache:
key: v1-deps-{{ checksum "yarn.lock" }}
paths:
- node_modules
- run: yarn run downloadsolc_assets
- run: yarn run build:production
- run:
@ -275,18 +323,32 @@ workflows:
unless: << pipeline.parameters.run_flaky_tests >>
jobs:
- build
- build-plugin:
matrix:
parameters:
plugin: ["etherscan", "vyper", "plugin_api"]
- lint:
requires:
- build
- remix-libs:
requires:
- build
- remix-libs
- remix-test-plugins:
name: test-plugin-<< matrix.plugin >>
requires:
- build
- build-plugin
matrix:
alias: plugins
parameters:
script: ["browser_tests_plugin_api.sh", "browser_tests_etherscan_plugin.sh", "browser_tests_vyper_plugin.sh"]
plugin: ["etherscan", "vyper", "plugin_api"]
parallelism: [1, 9]
exclude:
- plugin: plugin_api
parallelism: 1
- plugin: etherscan
parallelism: 9
- plugin: vyper
parallelism: 9
- remix-ide-browser:
requires:
- build
@ -301,13 +363,13 @@ workflows:
- lint
- remix-libs
- remix-ide-browser
- remix-test-plugins
- plugins
- deploy-remix-live:
requires:
- lint
- remix-libs
- remix-ide-browser
- remix-test-plugins
- plugins
filters:
branches:
only: remix_live
@ -316,7 +378,7 @@ workflows:
- lint
- remix-libs
- remix-ide-browser
- remix-test-plugins
- plugins
filters:
branches:
only: master
@ -325,7 +387,7 @@ workflows:
- lint
- remix-libs
- remix-ide-browser
- remix-test-plugins
- plugins
filters:
branches:
only: remix_beta

@ -0,0 +1,13 @@
{
"presets": [
[
"@nrwl/react/babel", {
"runtime": "automatic"
}
]
],
"plugins": [
]
}

@ -2,7 +2,7 @@ import { PluginClient } from "@remixproject/plugin";
import { createClient } from "@remixproject/plugin-webview";
import { IDebuggerApi, LineColumnLocation,
onBreakpointClearedListener, onBreakpointAddedListener, onEditorContentChanged, onEnvChangedListener, TransactionReceipt } from '@remix-ui/debugger-ui'
import { DebuggerApiMixin } from './debugger-api'
import { DebuggerApiMixin } from '@remix-ui/debugger-ui'
import { CompilerAbstract } from '@remix-project/remix-solidity'
export class DebuggerClientApi extends DebuggerApiMixin(PluginClient) {

@ -1 +0,0 @@
export * from './app/debugger-api';

@ -9,7 +9,6 @@
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",

@ -1,32 +1,83 @@
const nxWebpack = require('@nrwl/react/plugins/webpack')
module.exports = config => {
const nxWebpackConfig = nxWebpack(config)
const webpackConfig = {
...nxWebpackConfig,
resolve : {
...nxWebpackConfig.resolve,
fallback: {
...nxWebpackConfig.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"http" : require.resolve("stream-http"),
"https" : require.resolve("https-browserify"),
"path" : require.resolve("path-browserify"),
"module": false,
"fs" : false
},
}
const { composePlugins, withNx } = require('@nrwl/webpack')
const webpack = require('webpack')
const TerserPlugin = require("terser-webpack-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
// add fallback for node modules
config.resolve.fallback = {
...config.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"path": require.resolve("path-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"constants": require.resolve("constants-browserify"),
"os": false, //require.resolve("os-browserify/browser"),
"timers": false, // require.resolve("timers-browserify"),
"zlib": require.resolve("browserify-zlib"),
"fs": false,
"module": false,
"tls": false,
"net": false,
"readline": false,
"child_process": false,
"buffer": require.resolve("buffer/"),
"vm": require.resolve('vm-browserify'),
}
if (process.env.NODE_ENV === 'production') {
return {
...webpackConfig,
mode: 'production',
devtool: 'source-map',
}
} else {
return webpackConfig
// add externals
config.externals = {
...config.externals,
solc: 'solc',
}
}
// add public path
config.output.publicPath = '/'
// add copy & provide plugin
config.plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
url: ['url', 'URL'],
process: 'process/browser',
})
)
// souce-map loader
config.module.rules.push({
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
// set minimizer
config.optimization.minimizer = [
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 2015,
compress: false,
mangle: false,
format: {
comments: false,
},
},
extractComments: false,
}),
new CssMinimizerPlugin(),
];
return config;
});

@ -3,9 +3,6 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/etherscan/src",
"projectType": "application",
"implicitDependencies": [
"remix-debug"
],
"targets": {
"build": {
"executor": "@nrwl/webpack:webpack",

@ -9,7 +9,6 @@
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",

@ -29,7 +29,7 @@ module.exports = composePlugins(withNx(), (config) => {
"buffer": require.resolve("buffer/"),
"vm": require.resolve('vm-browserify'),
}
// add externals
config.externals = {
@ -79,4 +79,4 @@ module.exports = composePlugins(withNx(), (config) => {
];
return config;
});
});

@ -0,0 +1,23 @@
{
"name": "remix-ide-e2e",
"license": "MIT",
"engines": {
"node": "^14.17.6",
"npm": "^6.14.15"
},
"dependencies": {
"@openzeppelin/contracts": "^4.7.3",
"@openzeppelin/contracts-upgradeable": "^4.8.1",
"@openzeppelin/upgrades-core": "^1.22.0",
"@openzeppelin/wizard": "^0.1.1",
"@remix-project/remixd": "../../dist/libs/remixd",
"deep-equal": "^1.0.1",
"ganache-cli": "^6.8.1",
"selenium-standalone": "^8.2.3",
"tree-kill": "^1.2.2"
},
"devDependencies": {
"http-server": "^14.1.1",
"nightwatch": "2.3"
}
}

@ -5,14 +5,14 @@ import EventEmitter from 'events'
Check if the last log in the console contains a specific text
*/
class JournalLastChildIncludes extends EventEmitter {
command (this: NightwatchBrowser, val: string): NightwatchBrowser {
this.api
.waitForElementVisible('*[data-id="terminalJournal"]', 10000)
.pause(1000)
.getText('*[data-id="terminalJournal"]', (result) => {
console.log('JournalLastChildIncludes', result.value)
if (typeof result.value === 'string' && result.value.indexOf(val) === -1) return this.api.assert.fail(`wait for ${val} in ${result.value}`)
else this.api.assert.ok(true, `<*[data-id="terminalJournal"]> contains ${val}.`)
command(this: NightwatchBrowser, val: string): NightwatchBrowser {
this.api
.waitForElementPresent({
selector: `//*[@data-id='terminalJournal' and contains(.,'${val}')]`,
timeout: 10000,
locateStrategy: 'xpath'
}).perform((done) => {
done()
this.emit('complete')
})
return this

@ -1,4 +1,9 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
"presets": ["@babel/preset-env", ["@babel/preset-react",
{"runtime": "automatic"}
]],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", "@babel/plugin-proposal-nullish-coalescing-operator"],
"ignore": [
"**/node_modules/**"
]
}

@ -238,7 +238,6 @@
"browser": true,
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"settings": { "react": { "version": "detect" } },

@ -1,11 +1,8 @@
{
"name": "remix-ide-e2e-src-local-plugin",
"name": "plugin_api",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/remix-ide-e2e/src/local-plugin/src/",
"projectType": "application",
"implicitDependencies": [
"remix-debug"
],
"targets": {
"build": {
"executor": "@nrwl/webpack:webpack",
@ -13,7 +10,7 @@
"defaultConfiguration": "development",
"options": {
"compiler": "babel",
"outputPath": "dist/apps/remix-ide-e2e-src-local-plugin",
"outputPath": "dist/apps/plugin_api",
"index": "apps/remix-ide-e2e/src/local-plugin/src/index.html",
"baseHref": "/",
"main": "apps/remix-ide-e2e/src/local-plugin/src/main.tsx",
@ -25,7 +22,7 @@
"apps/remix-ide-e2e/src/local-plugin/src/styles.css"
],
"scripts": [],
"webpackConfig": "@nrwl/react/plugins/webpack"
"webpackConfig": "apps/remix-ide-e2e/src/local-plugin/webpack.config.js"
},
"configurations": {
"development": {
@ -44,16 +41,16 @@
"executor": "@nrwl/webpack:dev-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "remix-ide-e2e-src-local-plugin:build",
"buildTarget": "plugin_api:build",
"hmr": true
},
"configurations": {
"development": {
"buildTarget": "remix-ide-e2e-src-local-plugin:build:development",
"buildTarget": "plugin_api:build:development",
"port": 2020
},
"production": {
"buildTarget": "remix-ide-e2e-src-local-plugin:build:production"
"buildTarget": "plugin_api:build:production"
}
}
}

@ -0,0 +1,21 @@
const { composePlugins, withNx } = require('@nrwl/webpack')
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
// add public path
config.output.publicPath = '/'
// souce-map loader
config.module.rules.push({
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
return config;
});

@ -9,7 +9,7 @@ declare global {
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, null, true, { name: 'etherscan', url: 'http://127.0.0.1:5003'})
init(browser, done, null, true, { name: 'etherscan', url: 'http://127.0.0.1:9999'})
},
'Should load etherscan plugin #group1': function (browser: NightwatchBrowser) {

@ -11,7 +11,7 @@ const localPluginData: Profile & LocationProfile & ExternalProfile = {
name: 'localPlugin',
displayName: 'Local Plugin',
canActivate: ['dGitProvider', 'flattener', 'solidityUnitTesting', 'udapp', 'hardhat-provider'],
url: 'http://localhost:2020',
url: 'http://localhost:9999',
location: 'sidePanel'
}

@ -68,10 +68,9 @@ module.exports = {
})
},
'Record more than one contract #group1': function (browser: NightwatchBrowser) {
'Record more than one contract #group2': function (browser: NightwatchBrowser) {
// deploy 2 contracts (2 different ABIs), save the record, reexecute and test one of the function.
browser
.click('*[data-id="deployAndRunClearInstances"]')
.testContracts('multipleContracts.sol', sources[1]['multipleContracts.sol'], ['t1est', 't2est'])
.clickLaunchIcon('udapp')
.selectContract('t1est')
@ -81,6 +80,7 @@ module.exports = {
.selectContract('t2est')
.pause(1000)
.createContract('')
.click('[data-id="udappRecorderTitleExpander"]')
.click('.savetransaction')
.waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]')
.execute(function () {
@ -92,7 +92,7 @@ module.exports = {
.click('*[data-id="deployAndRunClearInstances"]') // clear udapp
.click('*[data-id="terminalClearConsole"]') // clear terminal
.click('[data-id="runtransaction"]')
.clickInstance(2)
.clickInstance(1)
.pause(1000)
.clickFunction('set2 - transact (not payable)', { types: 'uint256 _po', values: '10' })
.testFunction('last',
@ -103,7 +103,7 @@ module.exports = {
},
'Run with live "mode" #group1': function (browser: NightwatchBrowser) {
'Run with live "mode" #group2': function (browser: NightwatchBrowser) {
let addressRef: string
browser.addFile('scenario_live_mode.json', { content: JSON.stringify(liveModeScenario, null, '\t') })
.addFile('scenario_live_mode_storage.sol', { content: testStorageForLiveMode })

@ -312,7 +312,7 @@ function testImportFromRemixd(browser: NightwatchBrowser, callback: VoidFunction
}
async function spawnRemixd(path: string): Promise<ChildProcess> {
const remixd = spawn('yarn run remixd', [`-s ${path}`], { cwd: process.cwd(), shell: true, detached: true })
const remixd = spawn('chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js --remix-ide http://127.0.0.1:8080', [`-s ${path}`], { cwd: process.cwd(), shell: true, detached: true })
return new Promise((resolve, reject) => {
remixd.stdout.on('data', function (data) {
if(

@ -224,7 +224,6 @@ module.exports = {
'Call web3.eth.getAccounts() using Injected Provider (Metamask)': !function (browser: NightwatchBrowser) {
browser
.executeScriptInTerminal('web3.eth.getAccounts()')
.pause(2000)
.journalLastChildIncludes('[ "0x76a3ABb5a12dcd603B52Ed22195dED17ee82708f" ]')
.end()
}

@ -29,7 +29,6 @@ module.exports = {
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '0', '0xaa')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(fallback)')
.journalLastChildIncludes('value: 0 wei')
.journalLastChildIncludes('data: 0xaa')
@ -67,7 +66,6 @@ module.exports = {
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(receive)')
.journalLastChildIncludes('value: 1 wei')
.journalLastChildIncludes('data: 0x')
@ -80,7 +78,6 @@ module.exports = {
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '10', '0xaa')
.pause(1000)
.journalLastChildIncludes('to CheckSpecials.(fallback) errored:')
.journalLastChildIncludes('The called function should be payable if you send value')
.perform(done())
@ -97,7 +94,6 @@ module.exports = {
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(receive)')
.journalLastChildIncludes('value: 1 wei')
.journalLastChildIncludes('data: 0x')
@ -110,7 +106,6 @@ module.exports = {
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '0', '0xaa')
.pause(1000)
.waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`)
.assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, '\'Fallback\' function is not defined')
.perform(done())
@ -127,7 +122,6 @@ module.exports = {
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '1', '')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(fallback)')
.journalLastChildIncludes('value: 1 wei')
.journalLastChildIncludes('data: 0x')
@ -140,7 +134,6 @@ module.exports = {
browser.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '1', '0xaa')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(fallback)')
.journalLastChildIncludes('value: 1 wei')
.journalLastChildIncludes('data: 0xaa')
@ -180,7 +173,6 @@ module.exports = {
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
browser.sendLowLevelTx(address, '999999998765257135', '0xaa')
.pause(1000)
.journalLastChildIncludes('to: CheckSpecials.(fallback)')
.journalLastChildIncludes('value: 999999998765257135 wei')
.journalLastChildIncludes('data: 0xaa')

@ -202,7 +202,6 @@ module.exports = {
.addFile('scripts/deploy_storage.js', { content: scriptAutoExec.script })
.openFile('contracts/storage.sol')
.sendKeys('body', [browser.Keys.CONTROL, browser.Keys.SHIFT, 's'])
.pause(15000)
.journalLastChildIncludes('147')
},

@ -141,7 +141,6 @@ module.exports = {
.click('.udapp_contractActionsContainerSingle > button')
.clickInstance(0)
.clickFunction('g - transact (not payable)')
.pause(5000)
.journalLastChildIncludes('Error provided by the contract:')
.journalLastChildIncludes('CustomError : error description')
.journalLastChildIncludes('Parameters:')
@ -182,7 +181,6 @@ module.exports = {
.click('.udapp_contractActionsContainerSingle > button')
.clickInstance(1)
.clickFunction('h - transact (not payable)')
.pause(5000)
.journalLastChildIncludes('Error provided by the contract:')
.journalLastChildIncludes('CustomError : error description from library')
.journalLastChildIncludes('Parameters:')

@ -9,7 +9,7 @@ declare global {
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, null, true, { name: 'vyper', url: 'http://127.0.0.1:5002'})
init(browser, done, null, true, { name: 'vyper', url: 'http://127.0.0.1:9999'})
},
'Should connect to vyper plugin #group1': function (browser: NightwatchBrowser) {

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
{
"presets": ["@babel/preset-env", ["@babel/preset-react",
"presets": ["@babel/preset-env", ["@nrwl/react/babel",
{"runtime": "automatic"}
]],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", "@babel/plugin-proposal-nullish-coalescing-operator"],

@ -10,11 +10,8 @@ TEST_EXITCODE=0
yarn run ganache-cli &
npx http-server -p 9090 --cors='*' ./node_modules &
yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
sleep 5
yarn run build:e2e
# grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | xargs -I {} basename {} .test.js | grep -E "\b[${2}]"
# TESTFILES=$(grep -IRiL "@disabled" "dist/apps/remix-ide-e2e/src/tests" | grep "\.spec\|\.test" | xargs -I {} basename {} .test.js | grep -E "\b[$2]" | circleci tests split --split-by=timings )
node apps/remix-ide/ci/splice_tests.js $2 $3

@ -6,16 +6,14 @@ BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npx http-server -p 9999 ./dist/apps/$1 &
yarn run ganache-cli &
npx http-server -p 9090 --cors='*' ./node_modules &
yarn run serve:production &
npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "plugin_api" | sort | circleci tests split )
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep $1 | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
yarn build etherscan
yarn run serve:production &
npx nx serve etherscan &
sleep 5
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "etherscan_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ]
then
exit 1
fi

@ -1,26 +0,0 @@
#!/usr/bin/env bash
set -e
BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
yarn build vyper
yarn run serve:production &
npx nx serve vyper &
sleep 5
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "vyper_api" | sort | circleci tests split )
for TESTFILE in $TESTFILES; do
npx nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js $TESTFILE --env=chrome || TEST_EXITCODE=1
done
echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ]
then
exit 1
fi

@ -2,7 +2,6 @@
set -e
yarn run build:e2e
TESTFILES=$(grep -IRiL "\'@disabled\': \?true" "dist/apps/remix-ide-e2e/src/tests" | grep "\.flaky" | sort )
# count test files
@ -19,10 +18,8 @@ echo "$BUILD_ID"
TEST_EXITCODE=0
yarn run ganache-cli &
npx http-server -p 9090 --cors='*' ./node_modules &
yarn run serve:production &
echo 'sharing folder: ' $PWD '/apps/remix-ide/contracts' &
npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5
for TESTFILE in $TESTFILES; do

@ -30,17 +30,15 @@
},
"configurations": {
"development": {
"extractLicenses": false,
"sourceMap": true,
"vendorChunk": true,
"optimization": false
"optimization": false,
"generateIndexHtml": true,
"extractCss": false
},
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": false,
"generateIndexHtml": true,
"extractCss": false,
"vendorChunk": false
}
}
@ -50,15 +48,18 @@
"defaultConfiguration": "development",
"options": {
"buildTarget": "remix-ide:build",
"watch": true,
"liveReload": true,
"hmr": false
},
"configurations": {
"development": {
"buildTarget": "remix-ide:build:development",
"port": 8080
},
"hot":{
"buildTarget": "remix-ide:build:development",
"port": 8080,
"hmr": true
},
"production": {
"buildTarget": "remix-ide:build:production",
"port": 8080

@ -119,8 +119,6 @@ class AppComponent {
this.engine = new RemixEngine()
this.engine.register(appManager);
const matomoDomains = {
'remix-alpha.ethereum.org': 27,
'remix-beta.ethereum.org': 25,
@ -450,7 +448,11 @@ class AppComponent {
if (
this.appManager.pluginLoader.current === 'queryParams' &&
this.workspace.length > 0
) { this.menuicons.select(this.workspace[this.workspace.length - 1]) }
) {
this.menuicons.select(this.workspace[this.workspace.length - 1])
} else {
this.appManager.call('tabs', 'focus', 'home')
}
}
if (params.call) {
@ -484,19 +486,16 @@ class AppComponent {
}
}
}
})
.catch(console.error)
}
const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'apploaded')
document.body.appendChild(loadedElement)
})
// activate solidity plugin
this.appManager.activatePlugin(['solidity', 'udapp', 'deploy-libraries', 'link-libraries', 'openzeppelin-proxy'])
// Load and start the service who manager layout and frame
}
}

@ -1,12 +1,7 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import prettier from 'prettier/standalone'
import { Options } from 'prettier';
import sol from './code-format/index'
import * as ts from 'prettier/parser-typescript'
import * as babel from 'prettier/parser-babel'
import * as espree from 'prettier/parser-espree'
import * as yml from 'prettier/parser-yaml'
import path from 'path'
import yaml from 'js-yaml'
import toml from 'toml'
@ -67,12 +62,28 @@ const defaultOptions = {
export class CodeFormat extends Plugin {
prettier: any
ts: any
babel: any
espree: any
yml: any
sol: any
constructor() {
super(profile)
}
async format(file: string) {
// lazy load
if (!this.prettier) {
this.prettier = await import('prettier/standalone')
this.ts = await import('prettier/parser-typescript')
this.babel = await import('prettier/parser-babel')
this.espree = await import('prettier/parser-espree')
this.yml = await import('prettier/parser-yaml')
}
try {
const content = await this.call('fileManager', 'readFile', file)
if (!content) return
@ -241,8 +252,8 @@ export class CodeFormat extends Plugin {
}
const result = prettier.format(content, {
plugins: [sol as any, ts, babel, espree, yml],
const result = this.prettier.format(content, {
plugins: [sol as any, this.ts, this.babel, this.espree, this.yml],
parser: parserName,
...options
})

@ -7,13 +7,20 @@ import { CodeParser } from "../code-parser";
import { fileDecoration, fileDecorationType } from '@remix-ui/file-decorators'
import { sourceMappingDecoder } from '@remix-project/remix-debug'
import { CompilerRetriggerMode, CompilationSourceCode } from '@remix-project/remix-solidity';
import { MarkerSeverity } from 'monaco-editor';
import { findLinesInStringWithMatch, SearchResultLine } from '@remix-ui/search'
import { lastCompilationResult } from '@remixproject/plugin-api';
import { monacoTypes } from '@remix-ui/editor';
enum MarkerSeverity {
Hint = 1,
Info = 2,
Warning = 4,
Error = 8
}
type errorMarker = {
message: string
severity: MarkerSeverity
severity: monacoTypes.MarkerSeverity
position: {
start: {
line: number

@ -13,7 +13,8 @@ export type JsonDataRequest = {
export type JsonDataResult = {
id: number,
jsonrpc: string // version
result: any
result?: any,
error?: any,
}
export type RejectRequest = (error: Error) => void

@ -57,14 +57,20 @@ export class InjectedProvider extends Plugin implements IProvider {
// This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!'
if (!this.provider) {
this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.')
return reject(new Error('no injected provider found.'))
return resolve({ jsonrpc: '2.0', error: 'no injected provider found', id: data.id })
}
try {
if ((window as any) && typeof (window as any).ethereum.request === "function") (window as any).ethereum.request({ method: "eth_requestAccounts" });
const resultData = await this.provider.currentProvider.send(data.method, data.params)
resolve({ jsonrpc: '2.0', result: resultData.result, id: data.id })
let resultData = await this.provider.currentProvider.send(data.method, data.params)
if (resultData) {
if (resultData.jsonrpc && resultData.jsonrpc === '2.0') {
resultData = resultData.result
}
resolve({ jsonrpc: '2.0', result: resultData, id: data.id })
} else {
resolve({ jsonrpc: '2.0', error: 'no return data provided', id: data.id })
}
} catch (error) {
reject(error)
resolve({ jsonrpc: '2.0', error: error.message, id: data.id })
}
}
}

@ -15,7 +15,7 @@ export class MainnetForkVMProvider extends BasicVMProvider {
}, blockchain)
this.blockchain = blockchain
this.fork = 'london'
this.nodeUrl = 'https://rpc.archivenode.io/e50zmkroshle2e2e50zm0044i7ao04ym'
this.nodeUrl = 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332'
this.blockNumber = 'latest'
}

@ -62,7 +62,7 @@ export class CompileAndRun extends Plugin {
if (clearAllInstances) {
await this.call('udapp', 'clearAllInstances')
}
await this.call('scriptRunner', 'execute', content)
await this.call('scriptRunner', 'execute', content, fileName)
} catch (e) {
this.call('notification', 'toast', e.message || e)
}

@ -2,7 +2,7 @@
import React from 'react' // eslint-disable-line
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompilerApiMixin } from '@remixproject/solidity-compiler-plugin' // eslint-disable-line
import { CompilerApiMixin } from '@remix-ui/solidity-compiler'
import { ViewPlugin } from '@remixproject/engine-web'
import { QueryParams } from '@remix-project/remix-lib'
// import { ICompilerApi } from '@remix-project/remix-lib'

@ -1,6 +1,6 @@
import Web3 from 'web3'
import { DebuggerUI } from '@remix-ui/debugger-ui' // eslint-disable-line
import { DebuggerApiMixin } from '@remixproject/debugger-plugin' // eslint-disable-line
import { DebuggerApiMixin } from '@remix-ui/debugger-ui'
import { ViewPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
import React from 'react' // eslint-disable-line

@ -3,7 +3,8 @@
"filePanel.workspace": "WORKSPACES",
"filePanel.create": "Create",
"filePanel.clone": "Clone",
"filePanel.download": "Backup",
"filePanel.download": "Download",
"filePanel.backup": "Backup",
"filePanel.restore": "Restore",
"filePanel.workspace.create": "Create Workspace",
"filePanel.workspace.rename": "Rename Workspace",
@ -14,7 +15,7 @@
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "Workspace name",
"filePanel.workspace.chooseTemplate": "Choose a template",
"filePanel.workspace.download": "Backup Workspaces",
"filePanel.workspace.backup": "Backup Workspaces",
"filePanel.workspace.restore": "Restore Workspaces from the Backup",
"filePanel.workspace.clone": "Clone Git Repository",
"filePanel.workspace.cloneMessage": "Please provide a valid git repository url.",
@ -39,10 +40,11 @@
"filePanel.paste": "Paste",
"filePanel.compile": "Compile",
"filePanel.compileForNahmii": "Compile for Nahmii",
"filePanel.createNewFile": "Create New File",
"filePanel.createNewFolder": "Create New Folder",
"filePanel.publishToGist": "Publish all the current workspace files to a github gist",
"filePanel.uploadFile": "Load a local file into current workspace",
"filePanel.createNewFile": "Create new file",
"filePanel.createNewFolder": "Create new folder",
"filePanel.publishToGist": "Publish all files to GitHub gist",
"filePanel.uploadFile": "Upload files",
"filePanel.uploadFolder": "Upload folder",
"filePanel.updateGist": "Update the current [gist] explorer",
"filePanel.viewAllBranches": "View all branches",
"filePanel.createBranch": "Create branch",

@ -4,6 +4,7 @@
"filePanel.create": "新建",
"filePanel.clone": "克隆",
"filePanel.download": "下载",
"filePanel.backup": "Backup",
"filePanel.restore": "恢复",
"filePanel.workspace.create": "新建工作空间",
"filePanel.workspace.rename": "重命名工作空间",

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -26,7 +26,7 @@
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Remix - Ethereum IDE</title>
<link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="icon" type="x-icon" href="assets/img/icon.png">
<link rel="icon" type="x-icon" href="assets/img/remix-logo-blue.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css">
<link rel="stylesheet" integrity="ha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
The MIT License (MIT)
Copyright (c) 2014, 2015, the individual contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>Remix - Ethereum IDE</title>
<link rel="stylesheet" href="assets/css/pygment_trac.css">
<link rel="icon" type="x-icon" href="assets/img/icon.png">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/4.1.0/introjs.min.css">
<link rel="stylesheet" integrity="ha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
<script src="assets/js/browserfs.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/2.7.0/introjs.min.css">
</head>
<body>
<div id="root"></div>
<script src="https://kit.fontawesome.com/41dd021e94.js" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/intro.min.js"></script>
</body>
</html>

@ -3,7 +3,6 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"],
"module": "es2020"
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx", "./src/assets/**/*"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]

@ -5,7 +5,7 @@
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"],
"types": ["node"],
"resolveJsonModule": true
},
"files": [

@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
"types": ["node"]
},
"include": [
"**/*.spec.ts",

@ -60,7 +60,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
config.plugins.push(
new CopyPlugin({
patterns: [
{ from: '../../node_modules/monaco-editor/dev/vs', to: 'assets/js/monaco-editor/dev/vs' }
{ from: '../../node_modules/monaco-editor/min/vs', to: 'assets/js/monaco-editor/min/vs' }
].filter(Boolean)
}),
new webpack.ProvidePlugin({
@ -79,7 +79,6 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
// set minimizer
config.optimization.minimizer = [
new TerserPlugin({

@ -1,4 +1,9 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
"presets": ["@babel/preset-env", ["@babel/preset-react",
{"runtime": "automatic"}
]],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime", "@babel/plugin-proposal-nullish-coalescing-operator"],
"ignore": [
"**/node_modules/**"
]
}

@ -2,7 +2,7 @@
/* eslint-disable no-unused-vars */
import { PluginClient } from '@remixproject/plugin'
import { createClient } from '@remixproject/plugin-webview'
import { CompilerApiMixin } from './compiler-api'
import { CompilerApiMixin } from '@remix-ui/solidity-compiler'
import { ICompilerApi } from '@remix-project/remix-lib'
import { CompileTabLogic } from '@remix-ui/solidity-compiler'

@ -1 +0,0 @@
export * from './app/compiler-api'

@ -9,7 +9,6 @@
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",

@ -1,44 +1,93 @@
const nxWebpack = require('@nrwl/react/plugins/webpack')
const { composePlugins, withNx } = require('@nrwl/webpack')
const { withReact } = require('@nrwl/react')
const webpack = require('webpack')
const version = require('../../package.json').version
const fs = require('fs')
const TerserPlugin = require("terser-webpack-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
module.exports = config => {
const nxWebpackConfig = nxWebpack(config)
const webpackConfig = {
...nxWebpackConfig,
resolve: {
...nxWebpackConfig.resolve,
fallback: {
...nxWebpackConfig.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"path": require.resolve("path-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"zlib": require.resolve("browserify-zlib"),
"fs": false,
"module": false,
"tls": false,
"net": false,
"readline": false,
"child_process": false,
"buffer": require.resolve("buffer/"),
},
},
plugins: [
...nxWebpackConfig.plugins,
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
const versionData = {
version: version,
timestamp: Date.now(),
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}
fs.writeFileSync('./apps/remix-ide/src/assets/version.json', JSON.stringify(versionData))
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), withReact(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
// add fallback for node modules
config.resolve.fallback = {
...config.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"path": require.resolve("path-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"constants": require.resolve("constants-browserify"),
"os": false, //require.resolve("os-browserify/browser"),
"timers": false, // require.resolve("timers-browserify"),
"zlib": require.resolve("browserify-zlib"),
"fs": false,
"module": false,
"tls": false,
"net": false,
"readline": false,
"child_process": false,
"buffer": require.resolve("buffer/"),
"vm": require.resolve('vm-browserify'),
}
if (process.env.NODE_ENV === 'production') {
return {
...webpackConfig,
mode: 'production',
devtool: 'source-map',
}
} else {
return webpackConfig
// add externals
config.externals = {
...config.externals,
solc: 'solc',
}
}
// add public path
config.output.publicPath = '/'
// add copy & provide plugin
config.plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
url: ['url', 'URL'],
process: 'process/browser',
})
)
// souce-map loader
config.module.rules.push({
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
// set minimizer
config.optimization.minimizer = [
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 2015,
compress: false,
mangle: false,
format: {
comments: false,
},
},
extractComments: false,
}),
new CssMinimizerPlugin(),
];
return config;
});

@ -3,9 +3,6 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/vyper/src",
"projectType": "application",
"implicitDependencies": [
"remix-debug"
],
"targets": {
"build": {
"executor": "@nrwl/webpack:webpack",

@ -1,31 +1,83 @@
const nxWebpack = require('@nrwl/react/plugins/webpack')
module.exports = config => {
const nxWebpackConfig = nxWebpack(config)
const webpackConfig = {
...nxWebpackConfig,
resolve : {
...nxWebpackConfig.resolve,
fallback: {
...nxWebpackConfig.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"http" : require.resolve("stream-http"),
"https" : require.resolve("https-browserify"),
"path" : require.resolve("path-browserify"),
"module": false,
"fs" : false
},
}
const { composePlugins, withNx } = require('@nrwl/webpack')
const webpack = require('webpack')
const TerserPlugin = require("terser-webpack-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
// add fallback for node modules
config.resolve.fallback = {
...config.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"path": require.resolve("path-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
"constants": require.resolve("constants-browserify"),
"os": false, //require.resolve("os-browserify/browser"),
"timers": false, // require.resolve("timers-browserify"),
"zlib": require.resolve("browserify-zlib"),
"fs": false,
"module": false,
"tls": false,
"net": false,
"readline": false,
"child_process": false,
"buffer": require.resolve("buffer/"),
"vm": require.resolve('vm-browserify'),
}
if (process.env.NODE_ENV === 'production') {
return {
...webpackConfig,
mode: 'production',
devtool: 'source-map',
}
} else {
return webpackConfig
// add externals
config.externals = {
...config.externals,
solc: 'solc',
}
}
// add public path
config.output.publicPath = '/'
// add copy & provide plugin
config.plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
url: ['url', 'URL'],
process: 'process/browser',
})
)
// souce-map loader
config.module.rules.push({
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
// set minimizer
config.optimization.minimizer = [
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 2015,
compress: false,
mangle: false,
format: {
comments: false,
},
},
extractComments: false,
}),
new CssMinimizerPlugin(),
];
return config;
});

@ -1,5 +1,5 @@
module.exports = {
"presets": ["@babel/preset-typescript", "@babel/preset-env", "@babel/preset-react"],
"presets": ["@babel/preset-typescript", "@babel/preset-env", "@nrwl/react/babel"],
"plugins": [
"babel-plugin-replace-ts-export-assignment",
"@babel/plugin-transform-modules-commonjs",

@ -1,4 +0,0 @@
const nxPreset = require('@nrwl/jest/preset');
module.exports = { ...nxPreset }

@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["jest", "node"]
"types": ["node"]
},
"include": ["**/*.ts"]
}

@ -3,7 +3,6 @@
"version": "0.0.1",
"description": "This library was generated with [Nx](https://nx.dev).",
"main": "src/index.js",
"type": "module",
"author": "Remix Team",
"license": "ISC"
}

@ -1,11 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"declaration": true,
"types": ["node"]
},
"exclude": [

@ -38,4 +38,4 @@ export {
SolidityDecoder,
storage,
CmdLine
}
}

@ -1,26 +0,0 @@
module.exports = {
name: 'remix-solidity',
preset: '../../jest.config.js',
verbose: true,
silent: false, // Silent console messages, specially the 'remix-simulator' ones
transform: {
'^.+\\.[tj]sx?$': ['ts-jest',
{
useESM: true,
}]
},
transformIgnorePatterns: ["/node_modules/", "/dist/", "\\.pnp\\.[^\\/]+$"],
rootDir: "./",
testTimeout: 40000,
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'],
// Coverage
collectCoverage: true,
coverageReporters: ['text', 'text-summary'],
collectCoverageFrom: [
"**/*.ts",
"!**/sol/**",
"!src/types.ts",
"!src/logger.ts"
],
coverageDirectory: '../../coverage/libs/remix-solidity'
};

@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["jest", "node"],
"types": ["node"],
},
"include": ["**/*.ts"]
}

@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
"types": ["node"]
},
"include": [
"**/*.spec.ts",

@ -1,2 +1,3 @@
export * from './lib/debugger-ui'
export * from './lib/idebugger-api'
export * from './lib/api/debugger-api'

@ -1 +1,2 @@
export * from './lib/remix-ui-editor'
export { default as monacoTypes } from './types/monaco'

@ -1,5 +1,5 @@
import { IRange } from "monaco-editor";
import { monacoTypes } from '@remix-ui/editor';
export interface Action {
type: string;
payload: Record<string, any>
@ -58,7 +58,7 @@ export const reducerActions = (models = initialState, action: Action) => {
}
case 'REVEAL_RANGE': {
if (!editor) return models
const range: IRange = {
const range: monacoTypes.IRange = {
startLineNumber: action.payload.startLineNumber + 1,
startColumn: action.payload.startColumn,
endLineNumber: action.payload.endLineNumber + 1,

@ -1,6 +1,5 @@
import { IRange } from "monaco-editor";
import monaco from "../../../types/monaco";
import path from "path";
import { monacoTypes } from '@remix-ui/editor';
type CodeParserImportsData = {
files?: string[],
@ -8,7 +7,7 @@ type CodeParserImportsData = {
packages?: string[],
}
export function getStringCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getStringCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: 'concatenate an arbitrary number of string values',
@ -21,7 +20,7 @@ export function getStringCompletionItems(range: IRange, monaco): monaco.language
]
}
export function getBytesCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getBytesCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: 'concatenate an arbitrary number of values',
@ -35,7 +34,7 @@ export function getBytesCompletionItems(range: IRange, monaco): monaco.languages
}
export function getBlockCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getBlockCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: '(address): Current block miner’s address',
@ -97,7 +96,7 @@ export function getBlockCompletionItems(range: IRange, monaco): monaco.languages
];
}
export function getCompletionSnippets(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getCompletionSnippets(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
label: 'contract',
@ -193,7 +192,7 @@ export function getCompletionSnippets(range: IRange, monaco): monaco.languages.C
]
}
export function getTxCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getTxCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: '(uint): gas price of the transaction',
@ -212,7 +211,7 @@ export function getTxCompletionItems(range: IRange, monaco): monaco.languages.Co
];
}
export function getMsgCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getMsgCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: '(bytes): complete calldata',
@ -252,7 +251,7 @@ export function getMsgCompletionItems(range: IRange, monaco): monaco.languages.C
];
}
export function getAbiCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getAbiCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: 'encode(..) returs (bytes): ABI-encodes the given arguments',
@ -298,7 +297,7 @@ export function getAbiCompletionItems(range: IRange, monaco): monaco.languages.C
}
export function GetCompletionTypes(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function GetCompletionTypes(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
const completionItems = [];
const types = ['address', 'string', 'bytes', 'byte', 'int', 'uint', 'bool', 'hash'];
for (let index = 8; index <= 256; index += 8) {
@ -314,8 +313,8 @@ export function GetCompletionTypes(range: IRange, monaco): monaco.languages.Comp
return completionItems;
}
function CreateCompletionItem(label: string, kind: monaco.languages.CompletionItemKind, detail: string, range: IRange) {
const completionItem: monaco.languages.CompletionItem = {
function CreateCompletionItem(label: string, kind: monacoTypes.languages.CompletionItemKind, detail: string, range: monacoTypes.IRange) {
const completionItem: monacoTypes.languages.CompletionItem = {
label,
kind,
detail,
@ -327,7 +326,7 @@ function CreateCompletionItem(label: string, kind: monaco.languages.CompletionIt
return completionItem;
}
export function GetCompletionKeywords(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function GetCompletionKeywords(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
const completionItems = [];
const keywords = ['modifier', 'mapping', 'break', 'continue', 'delete', 'else', 'for',
'after', 'promise', 'alias', 'apply', 'auto', 'copyof', 'default', 'define', 'final', 'implements',
@ -337,7 +336,7 @@ export function GetCompletionKeywords(range: IRange, monaco): monaco.languages.C
'private', 'public', 'external', 'internal', 'payable', 'nonpayable', 'view', 'pure', 'case', 'do', 'else', 'finally',
'in', 'instanceof', 'return', 'throw', 'try', 'catch', 'typeof', 'yield', 'void', 'virtual', 'override'];
keywords.forEach(unit => {
const completionItem: monaco.languages.CompletionItem = {
const completionItem: monacoTypes.languages.CompletionItem = {
label: unit,
kind: monaco.languages.CompletionItemKind.Keyword,
detail: unit + ' keyword',
@ -366,7 +365,7 @@ export function GetCompletionKeywords(range: IRange, monaco): monaco.languages.C
}
export function GeCompletionUnits(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function GeCompletionUnits(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
const completionItems = [];
const etherUnits = ['wei', 'gwei', 'finney', 'szabo', 'ether'];
etherUnits.forEach(unit => {
@ -390,10 +389,10 @@ export function GeCompletionUnits(range: IRange, monaco): monaco.languages.Compl
return completionItems;
}
export function GetImports(range: IRange
export function GetImports(range: monacoTypes.IRange
, monaco, data: CodeParserImportsData
, word: string
): monaco.languages.CompletionItem[] {
): monacoTypes.languages.CompletionItem[] {
let list = []
if (!word.startsWith('@')) {
word = word.replace('"', '');
@ -473,7 +472,7 @@ export function GetImports(range: IRange
return list;
};
export function GetGlobalVariable(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function GetGlobalVariable(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: 'Current block',
@ -520,7 +519,7 @@ export function GetGlobalVariable(range: IRange, monaco): monaco.languages.Compl
];
}
export function GetGlobalFunctions(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function GetGlobalFunctions(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: 'assert(bool condition): throws if the condition is not met - to be used for internal errors.',
@ -644,7 +643,7 @@ export function GetGlobalFunctions(range: IRange, monaco): monaco.languages.Comp
];
}
export function getContextualAutoCompleteByGlobalVariable(word: string, range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getContextualAutoCompleteByGlobalVariable(word: string, range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
if (word === 'block') {
return getBlockCompletionItems(range, monaco);
}
@ -669,7 +668,7 @@ export function getContextualAutoCompleteByGlobalVariable(word: string, range: I
return null;
}
export function getArrayCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getArrayCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: '',
@ -706,7 +705,7 @@ export function getArrayCompletionItems(range: IRange, monaco): monaco.languages
]
}
export function getAddressCompletionItems(range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getAddressCompletionItems(range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
return [
{
detail: '(uint256): balance of the Address in Wei',
@ -752,7 +751,7 @@ export function getAddressCompletionItems(range: IRange, monaco): monaco.languag
}
export function getContextualAutoCompleteBTypeName(word: string, range: IRange, monaco): monaco.languages.CompletionItem[] {
export function getContextualAutoCompleteBTypeName(word: string, range: monacoTypes.IRange, monaco): monacoTypes.languages.CompletionItem[] {
if (word === 'ArrayTypeName') {
return getArrayCompletionItems(range, monaco);
}

@ -1,11 +1,9 @@
import { AstNode } from "@remix-project/remix-solidity"
import { isArray } from "lodash"
import { editor, languages, Position } from "monaco-editor"
import monaco from "../../types/monaco"
import { EditorUIProps } from "../remix-ui-editor"
import { GeCompletionUnits, GetCompletionKeywords, getCompletionSnippets, GetCompletionTypes, getContextualAutoCompleteBTypeName, getContextualAutoCompleteByGlobalVariable, GetGlobalFunctions, GetGlobalVariable, GetImports } from "./completion/completionGlobals"
export class RemixCompletionProvider implements languages.CompletionItemProvider {
import { monacoTypes } from '@remix-ui/editor';
export class RemixCompletionProvider implements monacoTypes.languages.CompletionItemProvider {
props: EditorUIProps
monaco: any
@ -17,7 +15,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
}
triggerCharacters = ['.', '', '"', '@', '/']
async provideCompletionItems(model: editor.ITextModel, position: Position, context: monaco.languages.CompletionContext): Promise<monaco.languages.CompletionList | undefined> {
async provideCompletionItems(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.CompletionContext): Promise<monacoTypes.languages.CompletionList | undefined> {
const completionSettings = await this.props.plugin.call('config', 'getAppParameter', 'settings/auto-completion')
if (!completionSettings) return
@ -32,7 +30,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
const line = model.getLineContent(position.lineNumber)
let nodes: AstNode[] = []
let suggestions: monaco.languages.CompletionItem[] = []
let suggestions: monacoTypes.languages.CompletionItem[] = []
if (context.triggerCharacter === '"' || context.triggerCharacter === '@' || context.triggerCharacter === '/') {
const lastpart = line.substring(0, position.column - 1).split(';').pop()
@ -342,7 +340,7 @@ export class RemixCompletionProvider implements languages.CompletionItemProvider
private getDotCompletions = async (nameOfLastTypedExpression: string, range) => {
const contractCompletions = await this.getContractCompletions()
let nodes: any[] = []
let suggestions: monaco.languages.CompletionItem[] = []
let suggestions: monacoTypes.languages.CompletionItem[] = []
const filterNodes = (nodes: any[], parentNode: any, declarationOf: any = null) => {
return nodes && nodes.filter(node => {

@ -1,8 +1,8 @@
import { Monaco } from '@monaco-editor/react'
import { editor, languages, Position } from 'monaco-editor'
import { EditorUIProps } from '../remix-ui-editor'
export class RemixHoverProvider implements languages.HoverProvider {
import { monacoTypes } from '@remix-ui/editor';
export class RemixHoverProvider implements monacoTypes.languages.HoverProvider {
props: EditorUIProps
monaco: Monaco
@ -11,7 +11,7 @@ export class RemixHoverProvider implements languages.HoverProvider {
this.monaco = monaco
}
provideHover = async function (model: editor.ITextModel, position: Position): Promise<languages.Hover> {
provideHover = async function (model: monacoTypes.editor.ITextModel, position: monacoTypes.Position): Promise<monacoTypes.languages.Hover> {
const cursorPosition = this.props.editorAPI.getHoverPosition(position)
const nodeAtPosition = await this.props.plugin.call('codeParser', 'definitionAtPosition', cursorPosition)
const contents = []

@ -7,11 +7,12 @@ import { solidityTokensProvider, solidityLanguageConfig } from './syntaxes/solid
import { cairoTokensProvider, cairoLanguageConfig } from './syntaxes/cairo'
import { zokratesTokensProvider, zokratesLanguageConfig } from './syntaxes/zokrates'
import { moveTokenProvider, moveLanguageConfig } from './syntaxes/move'
import { monacoTypes } from '@remix-ui/editor';
import './remix-ui-editor.css'
import { loadTypes } from './web-types'
import monaco from '../types/monaco'
import { IMarkdownString, IPosition, MarkerSeverity } from 'monaco-editor'
import { RemixHoverProvider } from './providers/hoverProvider'
import { RemixReferenceProvider } from './providers/referenceProvider'
@ -19,6 +20,14 @@ import { RemixCompletionProvider } from './providers/completionProvider'
import { RemixHighLightProvider } from './providers/highlightProvider'
import { RemixDefinitionProvider } from './providers/definitionProvider'
enum MarkerSeverity {
Hint = 1,
Info = 2,
Warning = 4,
Error = 8
}
type sourceAnnotation = {
row: number,
column: number,
@ -59,12 +68,12 @@ export type lineText = {
className: string
afterContentClassName: string
hide: boolean,
hoverMessage: IMarkdownString | IMarkdownString[]
hoverMessage: monacoTypes.IMarkdownString | monacoTypes.IMarkdownString[]
}
type errorMarker = {
message: string
severity: MarkerSeverity | 'warning' | 'info' | 'error' | 'hint'
severity: monacoTypes.MarkerSeverity | 'warning' | 'info' | 'error' | 'hint'
position: {
start: {
line: number
@ -78,7 +87,8 @@ type errorMarker = {
file: string
}
loader.config({ paths: { vs: 'assets/js/monaco-editor/dev/vs' } })
loader.config({ paths: { vs: 'assets/js/monaco-editor/min/vs' } })
export type DecorationsReturn = {
currentDecorations: Array<string>
@ -105,8 +115,8 @@ export interface EditorUIProps {
findMatches: (uri: string, value: string) => any
getFontSize: () => number,
getValue: (uri: string) => string
getCursorPosition: (offset?: boolean) => number | IPosition
getHoverPosition: (position: IPosition) => number
getCursorPosition: (offset?: boolean) => number | monacoTypes.IPosition
getHoverPosition: (position: monacoTypes.IPosition) => number
addDecoration: (marker: sourceMarker, filePath: string, typeOfDecoration: string) => DecorationsReturn
clearDecorationsByPlugin: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn
keepDecorationsFor: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn
@ -425,7 +435,7 @@ export const EditorUI = (props: EditorUIProps) => {
props.editorAPI.addErrorMarker = async (errors: errorMarker[], from: string) => {
const allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {}
const allMarkersPerfile: Record<string, Array<monacoTypes.editor.IMarkerData>> = {}
for (const error of errors) {
let filePath = error.file
@ -440,7 +450,7 @@ export const EditorUI = (props: EditorUIProps) => {
'info': MarkerSeverity.Info
}
if (model) {
const markerData: monaco.editor.IMarkerData = {
const markerData: monacoTypes.editor.IMarkerData = {
severity: (typeof error.severity === 'string') ? errorServerityMap[error.severity] : error.severity,
startLineNumber: ((error.position.start && error.position.start.line) || 0),
startColumn: ((error.position.start && error.position.start.column) || 0),
@ -496,7 +506,7 @@ export const EditorUI = (props: EditorUIProps) => {
}
}
props.editorAPI.getHoverPosition = (position: monaco.Position) => {
props.editorAPI.getHoverPosition = (position: monacoTypes.Position) => {
if (!monacoRef.current) return
const model = editorModelsState[currentFileRef.current]?.model
if (model) {

@ -1,7 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import BasicLogo from 'libs/remix-ui/vertical-icons-panel/src/lib/components/BasicLogo'
import { ThemeContext } from '../themeContext'
import React, { useEffect, useState, useRef, useContext } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { CustomTooltip } from '@remix-ui/helper'
@ -21,7 +19,6 @@ function HomeTabTitle() {
searchDisable: true
})
const themeFilter = useContext(ThemeContext)
const searchInputRef = useRef(null)
const remiAudioEl = useRef(null)
const intl = useIntl()
@ -52,13 +49,12 @@ function HomeTabTitle() {
return (
<div className="px-2 pb-2 pt-2 d-flex flex-column border-bottom" id="hTTitleSection">
<div className="d-flex py-2 justify-content-between">
<div className='d-flex justify-content-start'>
<span className="h-80 text-uppercase" style={{ fontSize: 'xx-large', fontFamily: "Noah, sans-serif" }}>Remix</span>
<span className="h-80 text-uppercase" style={{ fontSize: 'xx-large', fontFamily: "Noah, sans-serif" }}>Remix</span>
<div className="ml-2 d-flex">
<div onClick={() => playRemi()} >
<img className="" src="assets/img/guitarRemiCroped.webp" style={{height: "3rem"}} alt=""></img>
<img className="" src="assets/img/guitarRemiCroped.webp" style={{ height: "3rem" }} alt=""></img>
</div>
<audio
id="remiAudio"
@ -68,7 +64,7 @@ function HomeTabTitle() {
></audio>
</div>
</div>
<span className="d-flex flex-nowrap">
<span className="d-flex flex-nowrap align-self-end">
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -81,10 +77,9 @@ function HomeTabTitle() {
openLink("https://www.youtube.com/channel/UCjTUPyFEr2xDGN6Cg8nKDaA")
_paq.push(['trackEvent', 'hometab', 'socialMedia', 'youtube'])
}}
className="border-0 h-100 btn fab fa-youtube p-1 pl-2">
className="border-0 px-1 h-100 btn fab fa-youtube">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -97,10 +92,9 @@ function HomeTabTitle() {
openLink("https://twitter.com/EthereumRemix")
_paq.push(['trackEvent', 'hometab', 'socialMedia', 'twitter'])
}}
className="border-0 p-1 h-100 pl-2 btn fab fa-twitter">
className="border-0 px-1 h-100 btn fab fa-twitter">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -113,10 +107,9 @@ function HomeTabTitle() {
openLink("https://www.linkedin.com/company/ethereum-remix/")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'linkedin'])
}}
className="border-0 p-1 h-100 pl-2 btn fa fa-linkedin">
className="border-0 px-1 h-100 btn fa fa-linkedin">
</button>
</CustomTooltip>
<CustomTooltip
placement={'top'}
tooltipId="overlay-tooltip"
@ -129,7 +122,7 @@ function HomeTabTitle() {
openLink("https://medium.com/remix-ide")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'medium'])
}}
className="border-0 p-1 h-100 pl-2 btn fab fa-medium">
className="border-0 h-100 px-1 btn fab fa-medium">
</button>
</CustomTooltip>
@ -145,7 +138,7 @@ function HomeTabTitle() {
openLink("https://discord.gg/mh9hFCKkEq")
_paq.push(['trackEvent', 'hometab', 'socialmedia', 'discord'])
}}
className="border-0 h-100 p-1 pr-2 btn fab fa-discord">
className="border-0 h-100 pl-1 pr-0 btn fab fa-discord">
</button>
</CustomTooltip>
</span>

@ -120,6 +120,7 @@ export function AccountUI (props: AccountProps) {
<div>
<textarea
id="prompt_text"
className='bg-light'
data-id="signMessageTextarea"
style={{ width: '100%' }}
rows={4}

@ -25,7 +25,8 @@ export function GithubSettings (props: GithubSettingsProps) {
}, [props.config])
const handleChangeTokenState = (event) => {
setGithubToken(event.target.value)
const token = event.target.value ? event.target.value.trim() : event.target.value
setGithubToken(token)
}
const handleChangeUserNameState = (event) => {

@ -1,3 +1,4 @@
export * from './lib/solidity-compiler'
export * from './lib/logic'
export * from './lib/logic/flattenerUtilities'
export * from './lib/api/compiler-api'

@ -137,7 +137,7 @@
.remixui_log {
display: flex;
flex-direction: column;
margin-bottom: 5%;
margin-bottom: 0.5rem;
overflow: visible;
}
.remixui_key {

@ -77,10 +77,16 @@ export function RemixUiSolidityUmlGen ({ updatedSvg, loading }: RemixUiSolidityU
}
const DefaultInfo = () => (
<div className="d-flex flex-column justify-content-center align-items-center mt-5">
<h2 className="h2 align-self-start"><p>To view your contract as a Uml Diragram</p></h2>
<h3 className="h4 align-self-start"><p>Right Click on your contract file (Usually ends with .sol)</p></h3>
<h3 className="h4 align-self-start"><p>Click on Generate UML</p></h3>
<div className="d-flex flex-column justify-content-center align-items-center mt-5 ml-5">
<h3 className="h3 align-self-start text-dark"><p>To view your contract as a UML Diagram</p></h3>
<ul className="ml-3 justify-content-start align-self-start">
<li>
<h5 className="h5 align-self-start text-dark"><p>Right click on your contract file</p></h5>
</li>
<li>
<h5 className="h5 align-self-start text-dark"><p>Click on <b>Generate UML</b></p></h5>
</li>
</ul>
</div>
)
const Display = () => {

@ -153,7 +153,7 @@ export const TabsUI = (props: TabsUIProps) => {
const path = active().substr(active().indexOf('/') + 1, active().length)
const content = await props.plugin.call('fileManager', "readFile", path)
if (tabsState.currentExt === 'js' || tabsState.currentExt === 'ts') {
await props.plugin.call('scriptRunner', 'execute', content)
await props.plugin.call('scriptRunner', 'execute', content, path)
_paq.push(['trackEvent', 'editor', 'clickRunFromEditor', tabsState.currentExt])
} else if (tabsState.currentExt === 'sol' || tabsState.currentExt === 'yul') {
await props.plugin.call('solidity', 'compile', path)

@ -12,6 +12,7 @@ import { ROOT_PATH, slitherYml, solTestYml, tsSolTestYml } from '../utils/consta
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB'
import { getUncommittedFiles } from '../utils/gitStatusFilter'
import { AppModal, ModalTypes } from '@remix-ui/app'
declare global {
interface Window { remixFileSystemCallback: IndexedDBStorage; }
@ -358,6 +359,30 @@ export const switchToWorkspace = async (name: string) => {
}
}
const loadFile = (name, file, provider, cb?): void => {
const fileReader = new FileReader()
fileReader.onload = async function (event) {
if (checkSpecialChars(file.name)) {
return dispatch(displayNotification('File Upload Failed', 'Special characters are not allowed', 'Close', null, async () => { }))
}
try {
await provider.set(name, event.target.result)
} catch (error) {
return dispatch(displayNotification('File Upload Failed', 'Failed to create file ' + name, 'Close', null, async () => { }))
}
const config = plugin.registry.get('config').api
const editor = plugin.registry.get('editor').api
if ((config.get('currentFile') === name) && (editor.currentContent() !== event.target.result)) {
editor.setText(name, event.target.result)
}
}
fileReader.readAsText(file)
cb && cb(null, true)
}
export const uploadFile = async (target, targetFolder: string, cb?: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {
// TODO The file explorer is merely a view on the current state of
// the files module. Please ask the user here if they want to overwrite
@ -365,39 +390,52 @@ export const uploadFile = async (target, targetFolder: string, cb?: (err: Error,
// pick that up via the 'fileAdded' event from the files module.
[...target.files].forEach(async (file) => {
const workspaceProvider = plugin.fileProviders.workspace
const loadFile = (name: string): void => {
const fileReader = new FileReader()
fileReader.onload = async function (event) {
if (checkSpecialChars(file.name)) {
return dispatch(displayNotification('File Upload Failed', 'Special characters are not allowed', 'Close', null, async () => { }))
}
try {
await workspaceProvider.set(name, event.target.result)
} catch (error) {
return dispatch(displayNotification('File Upload Failed', 'Failed to create file ' + name, 'Close', null, async () => { }))
}
const config = plugin.registry.get('config').api
const editor = plugin.registry.get('editor').api
const name = targetFolder === '/' ? file.name : `${targetFolder}/${file.name}`
if ((config.get('currentFile') === name) && (editor.currentContent() !== event.target.result)) {
editor.setText(name, event.target.result)
}
if (!await workspaceProvider.exists(name)) {
loadFile(name, file, workspaceProvider, cb)
} else {
const modalContent: AppModal = {
id: 'overwriteUploadFile',
title: 'Confirm overwrite',
message: `The file "${name}" already exists! Would you like to overwrite it?`,
modalType: ModalTypes.confirm,
okLabel: 'OK',
cancelLabel: 'Cancel',
okFn: () => {
loadFile(name, file, workspaceProvider, cb)
},
cancelFn: () => {},
hideFn: () => {}
}
fileReader.readAsText(file)
cb && cb(null, true)
plugin.call('notification', 'modal', modalContent)
}
const name = targetFolder === '/' ? file.name : `${targetFolder}/${file.name}`
})
}
export const uploadFolder = async (target, targetFolder: string, cb?: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {
for(const file of [...target.files]) {
const workspaceProvider = plugin.fileProviders.workspace
const name = targetFolder === '/' ? file.webkitRelativePath : `${targetFolder}/${file.webkitRelativePath}`
if (!await workspaceProvider.exists(name)) {
loadFile(name)
loadFile(name, file, workspaceProvider, cb)
} else {
dispatch(displayNotification('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, 'OK', null, () => {
loadFile(name)
}, () => { }))
const modalContent: AppModal = {
id: 'overwriteUploadFolderFile',
title: 'Confirm overwrite',
message: `The file "${name}" already exists! Would you like to overwrite it?`,
modalType: ModalTypes.confirm,
okLabel: 'OK',
cancelLabel: 'Cancel',
okFn: () => {
loadFile(name, file, workspaceProvider, cb)
},
cancelFn: () => {},
hideFn: () => {}
}
plugin.call('notification', 'modal', modalContent)
}
})
}
}
export const getWorkspaces = async (): Promise<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }[]> | undefined => {

@ -10,27 +10,33 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
menuItems: [
{
action: 'createNewFile',
title: 'Create New File',
title: 'Create new file',
icon: 'far fa-file',
placement: 'top-start'
placement: 'top'
},
{
action: 'createNewFolder',
title: 'Create New Folder',
title: 'Create new folder',
icon: 'far fa-folder',
placement: 'top-end'
placement: 'top'
},
{
action: 'publishToGist',
title: 'Publish all the current workspace files to a github gist',
title: 'Publish current workspace to GitHub gist',
icon: 'fab fa-github',
placement: 'bottom-start'
placement: 'top'
},
{
action: 'uploadFile',
title: 'Load a local file into current workspace',
title: 'Upload files into current workspace',
icon: 'fa fa-upload',
placement: 'right'
placement: 'top'
},
{
action: 'uploadFolder',
title: 'Upload folder into current workspace',
icon: 'fas fa-folder-upload',
placement: 'top'
},
{
action: 'updateGist',
@ -41,6 +47,7 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
].filter(item => props.menuItems && props.menuItems.find((name) => { return name === item.action })),
actions: {}
})
const enableDirUpload = { directory: "", webkitdirectory: "" }
useEffect(() => {
const actions = {
@ -67,7 +74,7 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
if (action === 'uploadFile') {
return (
<CustomTooltip
placement="right"
placement={placement as Placement}
tooltipId="uploadFileTooltip"
tooltipClasses="text-nowrap"
tooltipText={<FormattedMessage id={`filePanel.${action}`} defaultMessage={title} />}
@ -81,6 +88,7 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
>
<input id="fileUpload" data-id="fileExplorerFileUpload" type="file" onChange={(e) => {
e.stopPropagation()
_paq.push(['trackEvent', 'fileExplorer', 'fileAction', action])
props.uploadFile(e.target)
e.target.value = null
}}
@ -88,6 +96,31 @@ export const FileExplorerMenu = (props: FileExplorerMenuProps) => {
</label>
</CustomTooltip>
)
} else if (action === 'uploadFolder') {
return (
<CustomTooltip
placement={placement as Placement}
tooltipId="uploadFolderTooltip"
tooltipClasses="text-nowrap"
tooltipText={<FormattedMessage id={`filePanel.${action}`} defaultMessage={title} />}
key={`index-${action}-${placement}-${icon}`}
>
<label
id={action}
data-id={'fileExplorerUploadFolder' + action }
className={icon + ' mb-0 remixui_newFile'}
key={`index-${action}-${placement}-${icon}`}
>
<input id="folderUpload" data-id="fileExplorerFolderUpload" type="file" onChange={(e) => {
e.stopPropagation()
_paq.push(['trackEvent', 'fileExplorer', 'fileAction', action])
props.uploadFolder(e.target)
e.target.value = null
}}
{...enableDirUpload} multiple />
</label>
</CustomTooltip>
)
} else {
return (
<CustomTooltip

@ -190,6 +190,14 @@ export const FileExplorer = (props: FileExplorerProps) => {
props.dispatchUploadFile(target, parentFolder)
}
const uploadFolder = (target) => {
const parentFolder = getFocusedFolder()
const expandPath = [...new Set([...props.expandPath, parentFolder])]
props.dispatchHandleExpandPath(expandPath)
props.dispatchUploadFolder(target, parentFolder)
}
const copyFile = (src: string, dest: string) => {
try {
props.dispatchCopyFile(src, dest)
@ -459,6 +467,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
createNewFolder={handleNewFolderInput}
publishToGist={publishToGist}
uploadFile={uploadFile}
uploadFolder={uploadFolder}
/>
</div>
}

@ -45,7 +45,7 @@ export function HamburgerMenu (props: HamburgerMenuProps) {
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<Dropdown.Divider className="border mt-0 mb-0 remixui_menuhr" style={{ pointerEvents: 'none' }}/>
<HamburgerMenuItem kind='download' fa='far fa-download' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
<HamburgerMenuItem kind='backup' fa='far fa-download' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.downloadWorkspaces()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>

@ -18,6 +18,7 @@ export const FileSystemContext = createContext<{
dispatchDeleteAllWorkspaces: () => Promise<void>,
dispatchPublishToGist: (path?: string, type?: string) => Promise<void>,
dispatchUploadFile: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchUploadFolder: (target?: SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchCreateNewFile: (path: string, rootDir: string) => Promise<void>,
dispatchSetFocusElement: (elements: { key: string, type: 'file' | 'folder' | 'gist' }[]) => Promise<void>,
dispatchCreateNewFolder: (path: string, rootDir: string) => Promise<void>,

@ -7,7 +7,7 @@ import { FileSystemContext } from '../contexts'
import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder,
deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction
} from '../actions'
import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types'
@ -79,6 +79,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await uploadFile(target, targetFolder)
}
const dispatchUploadFolder = async (target?: SyntheticEvent, targetFolder?: string) => {
await uploadFolder(target, targetFolder)
}
const dispatchCreateNewFile = async (path: string, rootDir: string) => {
await createNewFile(path, rootDir)
}
@ -265,6 +269,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchDeleteAllWorkspaces,
dispatchPublishToGist,
dispatchUploadFile,
dispatchUploadFolder,
dispatchCreateNewFile,
dispatchSetFocusElement,
dispatchCreateNewFolder,

@ -528,7 +528,7 @@ export function Workspace () {
<div className='h-100 remixui_treeview' data-id='filePanelFileExplorerTree'>
<FileExplorer
name={currentWorkspace}
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '']}
menuItems={['createNewFile', 'createNewFolder', 'publishToGist', canUpload ? 'uploadFile' : '', canUpload ? 'uploadFolder' : '']}
contextMenuItems={global.fs.browser.contextMenu.registeredMenuItems}
removedContextMenuItems={global.fs.browser.contextMenu.removedMenuItems}
files={global.fs.browser.files}
@ -547,6 +547,7 @@ export function Workspace () {
dispatchRenamePath={global.dispatchRenamePath}
dispatchDownloadPath={global.dispatchDownloadPath}
dispatchUploadFile={global.dispatchUploadFile}
dispatchUploadFolder={global.dispatchUploadFolder}
dispatchCopyFile={global.dispatchCopyFile}
dispatchCopyFolder={global.dispatchCopyFolder}
dispatchPublishToGist={global.dispatchPublishToGist}
@ -587,6 +588,7 @@ export function Workspace () {
dispatchRenamePath={global.dispatchRenamePath}
dispatchDownloadPath={global.dispatchDownloadPath}
dispatchUploadFile={global.dispatchUploadFile}
dispatchUploadFolder={global.dispatchUploadFolder}
dispatchCopyFile={global.dispatchCopyFile}
dispatchCopyFolder={global.dispatchCopyFolder}
dispatchPublishToGist={global.dispatchPublishToGist}

@ -98,6 +98,7 @@ export interface FileExplorerProps {
dispatchRenamePath: (oldPath: string, newPath: string) => Promise<void>,
dispatchDownloadPath: (path: string) => Promise<void>,
dispatchUploadFile: (target?: React.SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchUploadFolder: (target?: React.SyntheticEvent, targetFolder?: string) => Promise<void>,
dispatchCopyFile: (src: string, dest: string) => Promise<void>,
dispatchCopyFolder: (src: string, dest: string) => Promise<void>,
dispatchRunScript: (path: string) => Promise<void>,
@ -120,6 +121,7 @@ export interface FileExplorerMenuProps {
createNewFolder: (parentFolder?: string) => void,
publishToGist: (path?: string) => void,
uploadFile: (target: EventTarget & HTMLInputElement) => void
uploadFolder: (target: EventTarget & HTMLInputElement) => void
tooltipPlacement?: Placement
}
export interface FileExplorerContextMenuProps {

@ -4,7 +4,6 @@
"description": "Create a Remix IDE workspace using different templates",
"main": "src/index.js",
"types": "src/index.d.ts",
"type": "module",
"publishConfig": {
"access": "public"
},

@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
"types": ["node"]
},
"include": [
"**/*.spec.ts",

@ -28,6 +28,7 @@
"nx": "nx",
"start": "nx start",
"serve": "nx serve remix-ide --configuration=development",
"serve:hot": "nx serve remix-ide --configuration=hot",
"build": "nx build",
"test": "nx test",
"lint": "nx lint",
@ -57,8 +58,8 @@
"browsertest": "sleep 5 && yarn run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/",
"downloadsolc_assets_e2e": "node ./apps/remix-ide/ci/download_e2e_assets.js",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"downloadsolc_assets_dist": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./dist/apps/remix-ide/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./dist/apps/solidity-compiler/assets/js/soljson.js",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./apps/remix-ide/src/assets/js/soljson.js",
"downloadsolc_assets_dist": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.18+commit.87f61d96.js -O ./dist/apps/remix-ide/assets/js/soljson.js",
"make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",
"build:production": "NODE_ENV=production nx build remix-ide --configuration=production --skip-nx-cache",
@ -128,7 +129,6 @@
"@ethereumjs/vm": "^6.3.0",
"@ethersphere/bee-js": "^3.2.0",
"@isomorphic-git/lightning-fs": "^4.4.1",
"@monaco-editor/react": "4.4.5",
"@openzeppelin/contracts": "^4.7.3",
"@openzeppelin/upgrades-core": "^1.22.0",
"@openzeppelin/wizard": "^0.1.1",
@ -174,10 +174,9 @@
"jszip": "^3.6.0",
"latest-version": "^5.1.0",
"merge": "^2.1.1",
"monaco-editor": "^0.30.1",
"npm-install-version": "^6.0.2",
"path-browserify": "^1.0.1",
"prettier": "^2.7.1",
"prettier": "^2.8.4",
"prettier-plugin-solidity": "^1.0.0-beta.24",
"raw-loader": "^4.0.2",
"react": "^17.0.2",
@ -223,18 +222,19 @@
"@babel/preset-typescript": "^7.18.6",
"@babel/register": "^7.4.4",
"@fortawesome/fontawesome-free": "^5.8.1",
"@nrwl/cli": "^15.6.3",
"@nrwl/eslint-plugin-nx": "^15.6.3",
"@nrwl/jest": "15.6.3",
"@nrwl/js": "15.6.3",
"@nrwl/linter": "15.6.3",
"@nrwl/node": "15.6.3",
"@nrwl/react": "15.6.3",
"@nrwl/tao": "^15.6.3",
"@nrwl/web": "15.6.3",
"@nrwl/webpack": "15.6.3",
"@nrwl/workspace": "^15.6.3",
"@monaco-editor/react": "4.4.5",
"@nrwl/cli": "^15.7.1",
"@nrwl/eslint-plugin-nx": "^15.7.1",
"@nrwl/js": "15.7.1",
"@nrwl/linter": "15.7.1",
"@nrwl/node": "15.7.1",
"@nrwl/react": "15.7.1",
"@nrwl/tao": "^15.7.1",
"@nrwl/web": "15.7.1",
"@nrwl/webpack": "15.7.1",
"@nrwl/workspace": "^15.7.1",
"@openzeppelin/contracts-upgradeable": "^4.8.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@svgr/webpack": "^6.5.1",
"@testing-library/react": "13.4.0",
"@types/axios": "^0.14.0",
@ -242,7 +242,6 @@
"@types/express-ws": "^3.0.1",
"@types/fs-extra": "^9.0.1",
"@types/isomorphic-git__lightning-fs": "^4.4.2",
"@types/jest": "28.1.1",
"@types/lodash": "^4.14.172",
"@types/mocha": "^9.1.1",
"@types/node": "18.7.18",
@ -263,7 +262,6 @@
"ace-mode-solidity": "^0.1.0",
"ace-mode-zokrates": "^1.0.4",
"babel-eslint": "^10.0.0",
"babel-jest": "25.1.0",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-plugin-fast-async": "^6.1.2",
"babel-plugin-module-resolver": "^4.0.0",
@ -314,14 +312,13 @@
"ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1",
"jest": "^29.3.1",
"jest-environment-jsdom": "28.1.1",
"js-base64": "^2.1.9",
"js-beautify": "1.6.14",
"lerna": "^3.22.1",
"minixhr": "^4.0.0",
"mkdirp": "^0.5.1",
"mocha": "^8.0.1",
"monaco-editor": "^0.30.1",
"nanohtml": "^1.6.3",
"nightwatch": "^2.3",
"nodemon": "^2.0.4",
@ -329,11 +326,12 @@
"npm-link-local": "^1.1.0",
"npm-merge-driver": "^2.3.5",
"npm-run-all": "^4.0.2",
"nx": "15.6.3",
"nx": "15.7.1",
"nyc": "^13.3.0",
"onchange": "^3.2.1",
"os-browserify": "^0.3.0",
"process": "^0.11.10",
"react-refresh": "^0.14.0",
"react-test-renderer": "^17.0.2",
"request": "^2.83.0",
"rimraf": "^2.6.1",
@ -347,7 +345,6 @@
"tape": "^4.13.3",
"terser-webpack-plugin": "^5.3.6",
"timers-browserify": "^2.0.12",
"ts-jest": "^29.0.3",
"ts-node": "10.9.1",
"tslint": "~6.0.0",
"typescript": "^4.8.4",

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save