From 6e3d62442400ac5032ff49dd643d6bbfab3bf8c2 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 10 Apr 2021 02:06:33 +0100 Subject: [PATCH 001/199] refactor: added custom checkbox for static analyser plugin --- apps/remix-ide/src/app/tabs/analysis-tab.js | 49 ++- libs/remix-ui/static-analyser/.babelrc | 4 + libs/remix-ui/static-analyser/.eslintrc | 19 + libs/remix-ui/static-analyser/README.md | 7 + libs/remix-ui/static-analyser/src/index.ts | 1 + .../src/lib/Button/StaticAnalyserButton.tsx | 23 ++ .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 +++ .../static-analyser/src/lib/ErrorRenderer.tsx | 76 ++++ .../src/lib/remix-ui-static-analyser.tsx | 381 ++++++++++++++++++ libs/remix-ui/static-analyser/tsconfig.json | 16 + .../static-analyser/tsconfig.lib.json | 13 + nx.json | 3 + package-lock.json | 6 +- package.json | 1 + tsconfig.json | 5 +- workspace.json | 19 + 16 files changed, 647 insertions(+), 21 deletions(-) create mode 100644 libs/remix-ui/static-analyser/.babelrc create mode 100644 libs/remix-ui/static-analyser/.eslintrc create mode 100644 libs/remix-ui/static-analyser/README.md create mode 100644 libs/remix-ui/static-analyser/src/index.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx create mode 100644 libs/remix-ui/static-analyser/tsconfig.json create mode 100644 libs/remix-ui/static-analyser/tsconfig.lib.json diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index 4406ba875e..ad3c2fce54 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -1,9 +1,11 @@ +import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' +import ReactDOM from 'react-dom' import { EventEmitter } from 'events' +import {RemixUiStaticAnalyser} from '@remix-ui/static-analyser' // eslint-disable-line import * as packageJson from '../../../../../package.json' +var Renderer = require('../ui/renderer') -var yo = require('yo-yo') -var StaticAnalysis = require('./staticanalysis/staticAnalysisView') var EventManager = require('../../lib/events') const profile = { @@ -25,24 +27,39 @@ class AnalysisTab extends ViewPlugin { this.event = new EventManager() this.events = new EventEmitter() this.registry = registry + this.element = document.createElement('div') + this.element.setAttribute('id', 'staticAnalyserView') + this._components = { + renderer: new Renderer(this) + } + this._components.registry = this.registry + this._deps = { + offsetToLineColumnConverter: this.registry.get( + 'offsettolinecolumnconverter').api + } + } + + onActivation () { + this.renderComponent() } render () { - this.staticanalysis = new StaticAnalysis(this.registry, this) - this.staticanalysis.event.register('staticAnaysisWarning', (count) => { - if (count > 0) { - this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) - } else if (count === 0) { - this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) - } else { - // count ==-1 no compilation result - this.emit('statusChanged', { key: 'none' }) - } - }) - this.registry.put({ api: this.staticanalysis, name: 'staticanalysis' }) - - return yo`
${this.staticanalysis.render()}
` + return this.element } + + renderComponent () { + ReactDOM.render( + , + this.element + ) + } + } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/.babelrc b/libs/remix-ui/static-analyser/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/static-analyser/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/static-analyser/.eslintrc b/libs/remix-ui/static-analyser/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/static-analyser/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/static-analyser/README.md b/libs/remix-ui/static-analyser/README.md new file mode 100644 index 0000000000..7e4b95c0e5 --- /dev/null +++ b/libs/remix-ui/static-analyser/README.md @@ -0,0 +1,7 @@ +# remix-ui-static-analyser + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-static-analyser` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/static-analyser/src/index.ts b/libs/remix-ui/static-analyser/src/index.ts new file mode 100644 index 0000000000..86a00ccd14 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-static-analyser' diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx new file mode 100644 index 0000000000..5cd7e9392b --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -0,0 +1,23 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserButtonProps { + onClick: (event) => void + buttonText: string, + disabled?: boolean +} + +const StaticAnalyserButton = ({ + onClick, + buttonText, + disabled +}: StaticAnalyserButtonProps) => { + return ( +
+ +
+ ) +} + +export default StaticAnalyserButton diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx new file mode 100644 index 0000000000..2326a39122 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -0,0 +1,45 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserCheckBoxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +const StaticAnalyserCheckedBox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: StaticAnalyserCheckBoxProps) => { + return ( +
+ + +
+ ) +} + +export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx new file mode 100644 index 0000000000..7b7a01f37d --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -0,0 +1,76 @@ +import React, { useState } from 'react' //eslint-disable-line + +interface ErrorRendererProps { + message: any; + opt: any, + warningErrors: any +} + +const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { + const [, setError] = useState( + { + row: null, + column: null, + text: null, + type: null, + errFile: null + } + ) + const getPositionDetails = (msg: any) => { + const result = { } as any + + // To handle some compiler warning without location like SPDX license warning etc + if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } + + // extract line / column + let position = msg.match(/^(.*?):([0-9]*?):([0-9]*?)?/) + result.errLine = position ? parseInt(position[2]) - 1 : -1 + result.errCol = position ? parseInt(position[3]) : -1 + + // extract file + position = msg.match(/^(https:.*?|http:.*?|.*?):/) + result.errFile = position ? position[1] : '' + return result + } + if (!message) return + let position = getPositionDetails(message) + if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { + // Updated error reported includes '-->' before file details + const errorDetails = message.split('-->') + // errorDetails[1] will have file details + if (errorDetails.length > 1) position = getPositionDetails(errorDetails[1]) + } + opt.errLine = position.errLine + opt.errCol = position.errCol + opt.errFile = position.errFile.trim() + if (!opt.noAnnotations && opt.errFile) { + setError({ + errFile: opt.errFile, + row: opt.errLine, + column: opt.errCol, + text: message, + type: opt.type + }) + } + const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' + return ( +
+
+
+ +
+ + {opt.item.name} + { opt.item.warning } + {opt.item.more + ? more + : + } + Pos: {opt.locationString} + +
+
+ ) +} + +export default ErrorRenderer diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx new file mode 100644 index 0000000000..1674d66d84 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -0,0 +1,381 @@ +import React, { useEffect, useState } from 'react' +import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line +import Button from './Button/StaticAnalyserButton' // eslint-disable-line +import remixLib from '@remix-project/remix-lib' +import _ from 'lodash' +import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis +const utils = remixLib.util + +/* eslint-disable-next-line */ +export interface RemixUiStaticAnalyserProps { + renderStaticAnalysis: any + staticanalysis: any + analysisRunner: any, + lastCompilationResult: any, + lastCompilationSource: any, + registry: any, + event: any, + analysisModule: any + _deps: any +} + +export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { + const [runner] = useState(new StaticAnalysisRunner()) + + const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) + } + + const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' + ) + + const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) + } + + const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory + } + + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + const warningContainer = React.useRef(null) + const [runButtonState, setRunButtonState] = useState(true) + const [autoRun, setAutoRun] = useState(true) + const [result, setResult] = useState({ + lastCompilationResult: null, + lastCompilationSource: null, + currentFile: 'No file compiled' + }) + const [, setModuleNameResult] = useState(null) + const [, setWarning] = useState({ + msg: '', + options: {}, + hasWarning: false, + warningErrors: [] + }) + const [warningState, setWarningState] = useState([]) + + useEffect(() => { + if (autoRun) { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } + + if (props.analysisModule) { + console.log({ autoRun }) + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + run(data, source, file) + } + ) + } + } + return () => { } + }, [autoRun]) + + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { + // const highlightLocation = async (location, fileName) => { + // await props.analysisModule.call('editor', 'discardHighlight') + // await props.analysisModule.call('editor', 'highlight', location, fileName) + // } + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] + + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) + }) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + var split = item.location.split(':') + var file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] + } + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more + } + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) + }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) + }) + props.event.trigger('staticAnaysisWarning', [warningCount]) + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) + } + } + + // const correctRunBtnDisabled = () => { + // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { + // setRunButtonState(false) + // } else { + // setRunButtonState(true) + // } + // } + + const handleCheckAllModules = (groupedModules) => { + const index = groupedModuleIndex(groupedModules) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleCheckOrUncheckCategory = (category) => { + const index = groupedModuleIndex(category) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleAutoRun = () => { + if (autoRun) { + setAutoRun(false) + } else { + setAutoRun(true) + } + console.log(' auton run function') + } + + const handleCheckSingle = (event, _index) => { + _index = _index.toString() + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) + } else { + setCategoryIndex(_.uniq([...categoryIndex, _index])) + } + } + + const categoryItem = (categoryId, item, i) => { + return ( +
+ handleCheckSingle(event, item._index)} + checked={categoryIndex.includes(item._index.toString())} + /> +
+ ) + } + + const categorySection = (category, categoryId, i) => { + return ( +
+
+ + + {category[0].categoryDisplayName} +
+ +
+ + } + expand={true} + > +
+ handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> +
+
+ {category.map((item, i) => { + return ( + categoryItem(categoryId, item, i) + ) + })} +
+
+
+
+
+ ) + } + + return ( +
+
+
+
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
+
+ +
+
+
+
+ {Object.keys(groupedModules).map((categoryId, i) => { + const category = groupedModules[categoryId] + return ( + categorySection(category, categoryId, i) + ) + }) + } +
+
+ last results for: + + {result.currentFile && result.currentFile} + +
+
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
+
+
+ ) +} + +export default RemixUiStaticAnalyser diff --git a/libs/remix-ui/static-analyser/tsconfig.json b/libs/remix-ui/static-analyser/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/static-analyser/tsconfig.lib.json b/libs/remix-ui/static-analyser/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index 5cf047d9cc..802b6fe374 100644 --- a/nx.json +++ b/nx.json @@ -95,6 +95,9 @@ }, "remix-ui-workspace": { "tags": [] + }, + "remix-ui-static-analyser": { + "tags": [] } } } diff --git a/package-lock.json b/package-lock.json index 75be37b1d3..881c8c7858 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24982,9 +24982,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { "version": "4.17.15", diff --git a/package.json b/package.json index 5180840e01..46e75e0542 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ "http-server": "^0.11.1", "isbinaryfile": "^3.0.2", "jszip": "^3.6.0", + "lodash": "^4.17.21", "merge": "^1.2.0", "npm-install-version": "^6.0.2", "react": "16.13.1", diff --git a/tsconfig.json b/tsconfig.json index c2a383e9de..c90ed09031 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "target": "es2015", "module": "commonjs", "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "dom"], + "lib": ["es2017", "es2019", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", @@ -38,7 +38,8 @@ "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], - "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"] + "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 10793e13b3..9c734f96a7 100644 --- a/workspace.json +++ b/workspace.json @@ -725,6 +725,25 @@ } } } + }, + "remix-ui-static-analyser": { + "root": "libs/remix-ui/static-analyser", + "sourceRoot": "libs/remix-ui/static-analyser/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/static-analyser/tsconfig.lib.json"], + "exclude": [ + "**/node_modules/**", + "!libs/remix-ui/static-analyser/**/*" + ] + } + } + } } }, "cli": { From b829de8c35615b66c999cb1bd8a0d23b68eab601 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 12:51:49 +0100 Subject: [PATCH 002/199] added warning sign when analysis has runned --- apps/remix-ide/src/app/tabs/analysis-tab.js | 15 +++++++++++++-- .../src/lib/remix-ui-static-analyser.tsx | 19 +++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index ad3c2fce54..b3bba2705c 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -56,10 +56,21 @@ class AnalysisTab extends ViewPlugin { analysisModule={this} event={this.event} />, - this.element + this.element, + () => { + this.event.register('staticAnaysisWarning', (count) => { + if (count > 0) { + this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) + } else if (count === 0) { + this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) + } else { + // count ==-1 no compilation result + this.emit('statusChanged', { key: 'none' }) + } + }) + } ) } - } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 1674d66d84..81d4e29e15 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' +import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' @@ -18,7 +19,8 @@ export interface RemixUiStaticAnalyserProps { registry: any, event: any, analysisModule: any - _deps: any + _deps: any, + emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -63,7 +65,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(true) + const [autoRun, setAutoRun] = useState(false) const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -96,7 +98,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } ) } + } else { + setAutoRun(true) } + return () => { } }, [autoRun]) @@ -105,6 +110,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } + console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -193,6 +199,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) + props.event.trigger('staticAnaysisWarning', [warningCount]) } else { setRunButtonState(true) @@ -203,14 +210,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } } - // const correctRunBtnDisabled = () => { - // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { - // setRunButtonState(false) - // } else { - // setRunButtonState(true) - // } - // } - const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) if (index.every(el => categoryIndex.includes(el))) { From e765dd6fabeeaaf653b0666356b001f087327abe Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 13:05:48 +0100 Subject: [PATCH 003/199] removed icon: fas fa-angle-double-right from each category display name --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 81d4e29e15..b1810c3143 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -288,9 +288,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { data-bs-target={`#heading${categoryId}`} > {category[0].categoryDisplayName} -
- -
} expand={true} From 84bcd82caa8653b86b3422485894413ded7bd3e7 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 13 Apr 2021 18:37:37 +0100 Subject: [PATCH 004/199] adding a condition to fix ci build --- .../src/lib/remix-ui-static-analyser.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index b1810c3143..5000a94c01 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -356,20 +356,22 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile} -
-
- { - (Object.entries(warningState).map((element) => ( - <> - {element[0]} - {element[1].map(x => ( - x.hasWarning ? () : null - ))} - - ))) - } + { Object.entries(warningState).length > 0 && +
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
-
+ }
) } From edf19b46772daf99913592c8c4cba63a138d2b87 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 06:49:06 +0100 Subject: [PATCH 005/199] fix: testing to see if test passes --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..b2c3f41cb6 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 7b7a01f37d..878cccb7da 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -60,7 +60,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { - {opt.item.name} + {opt.name} { opt.item.warning } {opt.item.more ? more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5000a94c01..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -164,6 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` + console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, From 3d8d939281b405cd192965555ae1e23a1e4d7c8d Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 09:19:39 +0100 Subject: [PATCH 006/199] added className staticAnalysisView to staticAnalyser component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index b2c3f41cb6..a68a4a24ce 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..93b1b6b3a4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Fri, 16 Apr 2021 09:54:37 +0100 Subject: [PATCH 007/199] remove className staticAnalysisView and added id = staticanalysisView --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 93b1b6b3a4..8e42d97ce4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:07:13 +0100 Subject: [PATCH 008/199] fix: moved staticanalysisButton id to the Button component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/Button/StaticAnalyserButton.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,7 +40,7 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisView button') + .click('#staticanalysisButton button') .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 5cd7e9392b..336a0fe56a 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,7 +12,7 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
+
diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8e42d97ce4..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:27:48 +0100 Subject: [PATCH 009/199] fix: removed disabled props on button --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..38e4988a0f 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From 1a595bfc3b9d0af1ccad6fc74bd18d8484edf7b0 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 06:52:33 +0100 Subject: [PATCH 010/199] reversed changes --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 38e4988a0f..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From 81b7e38110fc296b831a1c5db81c64087b1ff110 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 17:49:24 +0100 Subject: [PATCH 011/199] commiting code to detect failing test --- .../src/tests/staticAnalysis.spec.ts | 24 +++++++++---------- .../src/lib/remix-ui-static-analyser.tsx | 4 ---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..480fab63fb 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,18 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) + //.click('#staticanalysisButton button') + // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + // listSelectorContains(['Use of tx.origin', + // 'Fallback function of contract TooMuchGas requires too much gas', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + // '#staticanalysisresult .warning', + // browser, function () { + // browser.end() + // } + // ) + // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..5a24785838 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -87,7 +87,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } if (props.analysisModule) { - console.log({ autoRun }) props.analysisModule.on( 'solidity', 'compilationFinished', @@ -110,7 +109,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } - console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -164,7 +162,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` - console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, @@ -243,7 +240,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } else { setAutoRun(true) } - console.log(' auton run function') } const handleCheckSingle = (event, _index) => { From ba090e2aff6984c9a4e709d05d8c585b7f7bf15c Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:00:14 +0100 Subject: [PATCH 012/199] removed comments --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 480fab63fb..e9777e2970 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,6 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - //.click('#staticanalysisButton button') - // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - // listSelectorContains(['Use of tx.origin', - // 'Fallback function of contract TooMuchGas requires too much gas', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - // '#staticanalysisresult .warning', - // browser, function () { - // browser.end() - // } - // ) - // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { From d351f4c70a3cea81fd8b1e77b27d289073761260 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:09:41 +0100 Subject: [PATCH 013/199] removing comments and unused functions --- .../src/tests/staticAnalysis.spec.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index e9777e2970..a10a2a8348 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -42,20 +42,4 @@ function runTests (browser: NightwatchBrowser) { .clickLaunchIcon('solidityStaticAnalysis') } -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) -} + From 973de43305d2c6f5b5f78910d676923206fe9b85 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:20:19 +0100 Subject: [PATCH 014/199] removed extra space at end of file --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a10a2a8348..8fa094273e 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,6 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} - - +} \ No newline at end of file From a34e01c0d099abfad7d419b8420771b4e404a7ee Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:27:17 +0100 Subject: [PATCH 015/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 8fa094273e..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} \ No newline at end of file + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) +} From cacfc5c3a596f092b893a0c91c6f3cd2ed23f3bc Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:35:52 +0100 Subject: [PATCH 016/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..55f7329f65 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,34 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) -} - -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) } From 845cb3bc3c10464f70099525c6641a54afeab038 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:37:33 +0100 Subject: [PATCH 017/199] restored staticAnalysis.spec.ts to it previous code structure --- .../src/tests/staticAnalysis.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 55f7329f65..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) } From 18cb9d4742e0db9681fba3a23906487ea8a81ae7 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 19 Apr 2021 14:25:28 +0100 Subject: [PATCH 018/199] fix failing test --- .../src/lib/remix-ui-static-analyser.tsx | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5a24785838..2fb460eec9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -81,19 +81,24 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { + if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { + props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - run(data, source, file) + if(categoryIndex.length > 0){ + run(data, source, file) + } + } ) } @@ -102,7 +107,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return () => { } - }, [autoRun]) + }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { // const highlightLocation = async (location, fileName) => { @@ -197,8 +202,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) - - props.event.trigger('staticAnaysisWarning', [warningCount]) + if(categoryIndex.length > 0){ + props.event.trigger('staticAnaysisWarning', [warningCount]) + } } else { setRunButtonState(true) if (categoryIndex.length) { @@ -217,8 +223,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + setCategoryIndex(_.uniq([...categoryIndex])) } + } const handleCheckOrUncheckCategory = (category) => { @@ -353,9 +360,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
-
+
{ (Object.entries(warningState).map((element) => ( <> From 40cb362c64782485b91fd04357ae48dcf5bfcb14 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 11:23:00 +0100 Subject: [PATCH 019/199] feat_fix_n_refactor: exptracted checkbox as a reusable component and fix selec all and auto run, --- libs/remix-ui/checkbox/.babelrc | 4 + libs/remix-ui/checkbox/.eslintrc | 19 ++ libs/remix-ui/checkbox/README.md | 7 + libs/remix-ui/checkbox/src/index.ts | 1 + .../checkbox/src/lib/remix-ui-checkbox.css | 0 .../checkbox/src/lib/remix-ui-checkbox.tsx | 47 ++++ libs/remix-ui/checkbox/tsconfig.json | 16 ++ libs/remix-ui/checkbox/tsconfig.lib.json | 13 + .../src/lib/Button/StaticAnalyserButton.tsx | 8 +- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 8 +- .../static-analyser/src/lib/ErrorRenderer.tsx | 31 +-- .../src/lib/remix-ui-static-analyser.tsx | 260 +++++++++--------- nx.json | 3 + package.json | 2 +- tsconfig.json | 3 +- workspace.json | 16 ++ 16 files changed, 273 insertions(+), 165 deletions(-) create mode 100644 libs/remix-ui/checkbox/.babelrc create mode 100644 libs/remix-ui/checkbox/.eslintrc create mode 100644 libs/remix-ui/checkbox/README.md create mode 100644 libs/remix-ui/checkbox/src/index.ts create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx create mode 100644 libs/remix-ui/checkbox/tsconfig.json create mode 100644 libs/remix-ui/checkbox/tsconfig.lib.json diff --git a/libs/remix-ui/checkbox/.babelrc b/libs/remix-ui/checkbox/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/checkbox/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/checkbox/.eslintrc b/libs/remix-ui/checkbox/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/checkbox/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/checkbox/README.md b/libs/remix-ui/checkbox/README.md new file mode 100644 index 0000000000..56f9b617b0 --- /dev/null +++ b/libs/remix-ui/checkbox/README.md @@ -0,0 +1,7 @@ +# remix-ui-checkbox + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-checkbox` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/checkbox/src/index.ts b/libs/remix-ui/checkbox/src/index.ts new file mode 100644 index 0000000000..27b694c6bd --- /dev/null +++ b/libs/remix-ui/checkbox/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-checkbox' diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx new file mode 100644 index 0000000000..5535a05971 --- /dev/null +++ b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx @@ -0,0 +1,47 @@ +import React from 'react' //eslint-disable-line +import './remix-ui-checkbox.css' + +/* eslint-disable-next-line */ +export interface RemixUiCheckboxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +export const RemixUiCheckbox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: RemixUiCheckboxProps) => { + return ( +
+ + +
+ ) +} + +export default RemixUiCheckbox diff --git a/libs/remix-ui/checkbox/tsconfig.json b/libs/remix-ui/checkbox/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/checkbox/tsconfig.lib.json b/libs/remix-ui/checkbox/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 336a0fe56a..2a67c82cf8 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,11 +12,9 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
- -
+ ) } diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx index 2326a39122..e42caa4851 100644 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -24,7 +24,7 @@ const StaticAnalyserCheckedBox = ({ categoryId }: StaticAnalyserCheckBoxProps) => { return ( -
+
-
) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 878cccb7da..b31a62b9de 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -4,20 +4,12 @@ interface ErrorRendererProps { message: any; opt: any, warningErrors: any + editor: any } -const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { - const [, setError] = useState( - { - row: null, - column: null, - text: null, - type: null, - errFile: null - } - ) +const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { const getPositionDetails = (msg: any) => { - const result = { } as any + const result = { } as Record // To handle some compiler warning without location like SPDX license warning etc if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } @@ -32,6 +24,12 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { result.errFile = position ? position[1] : '' return result } + + const handlePointToErrorOnClick = () => { + const result = opt.locationString.split(':') + editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + } + if (!message) return let position = getPositionDetails(message) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { @@ -43,15 +41,6 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { opt.errLine = position.errLine opt.errCol = position.errCol opt.errFile = position.errFile.trim() - if (!opt.noAnnotations && opt.errFile) { - setError({ - errFile: opt.errFile, - row: opt.errLine, - column: opt.errCol, - text: message, - type: opt.type - }) - } const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' return (
@@ -59,7 +48,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
- + {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 2fb460eec9..21acfe376a 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,10 +1,11 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -60,12 +61,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return indexOfCategory } - + const [autoRun, setAutoRun] = useState(true) const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(false) + const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -81,136 +82,129 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { - if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { - props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - if(categoryIndex.length > 0){ + if (categoryIndex.length > 0) { run(data, source, file) } - } ) } - } else { - setAutoRun(true) } return () => { } }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { - // const highlightLocation = async (location, fileName) => { - // await props.analysisModule.call('editor', 'discardHighlight') - // await props.analysisModule.call('editor', 'highlight', location, fileName) - // } - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length) { - setRunButtonState(false) - let warningCount = 0 - const warningMessage = [] + if (autoRun) { + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length > 0) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { - results.map((result) => { - let moduleName - Object.keys(groupedModules).map(key => { - groupedModules[key].forEach(el => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) }) - }) - setModuleNameResult(moduleName) - const warningErrors = [] - result.report.map((item) => { - let location: any = {} - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + const split = item.location.split(':') + const file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] } - location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - lastCompilationSource.sources, - lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = row + 1 + ':' + column + ':' - fileName = Object.keys(lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more } - Pos: ${locationString} - ` - const options = { - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column, - item: item, - name: result.name, - locationString, - more: item.more - } - warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) }) - const resultArray = [] - warningMessage.map(x => { - resultArray.push(x) - }) - function groupBy (objectArray, property) { - return objectArray.reduce((acc, obj) => { - const key = obj[property] - if (!acc[key]) { - acc[key] = [] - } - // Add object to list for given key's value - acc[key].push(obj) - return acc - }, {}) + if (categoryIndex.length > 0) { + props.event.trigger('staticAnaysisWarning', [warningCount]) } - - const groupedCategory = groupBy(resultArray, 'warningModuleName') - setWarningState(groupedCategory) - }) - if(categoryIndex.length > 0){ - props.event.trigger('staticAnaysisWarning', [warningCount]) - } - } else { - setRunButtonState(true) - if (categoryIndex.length) { - warningContainer.current.innerText = 'No compiled AST available' + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) } - props.event.trigger('staticAnaysisWarning', [-1]) } } @@ -223,9 +217,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex])) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } - } const handleCheckOrUncheckCategory = (category) => { @@ -261,7 +254,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const categoryItem = (categoryId, item, i) => { return (
- { } - expand={true} + expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} />
{category.map((item, i) => { @@ -314,31 +307,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return ( -
+
-
- { - return (value.map(x => { - return x._index.toString() - })) - }).flat().every(el => categoryIndex.includes(el))} - label="Select all" - onClick={() => handleCheckAllModules(groupedModules)} - /> -
-
- -
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
@@ -368,7 +357,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { <> {element[0]} {element[1].map(x => ( - x.hasWarning ? () : null + x.hasWarning ? ( +
+ +
+ + ) : null ))} ))) diff --git a/nx.json b/nx.json index 802b6fe374..a63c015d64 100644 --- a/nx.json +++ b/nx.json @@ -98,6 +98,9 @@ }, "remix-ui-static-analyser": { "tags": [] + }, + "remix-ui-checkbox": { + "tags": [] } } } diff --git a/package.json b/package.json index 4981321f93..8048576b7c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs", diff --git a/tsconfig.json b/tsconfig.json index c90ed09031..75db5bc6ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,7 +39,8 @@ "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], - "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 9c734f96a7..5d2bf912c0 100644 --- a/workspace.json +++ b/workspace.json @@ -744,6 +744,22 @@ } } } + }, + "remix-ui-checkbox": { + "root": "libs/remix-ui/checkbox", + "sourceRoot": "libs/remix-ui/checkbox/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/checkbox/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/checkbox/**/*"] + } + } + } } }, "cli": { From af075393f3b2c74a91c2646871f237f795765dac Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 16:57:24 +0100 Subject: [PATCH 020/199] refactored warning message --- .../src/lib/remix-ui-static-analyser.tsx | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 21acfe376a..383bfa7643 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -105,6 +105,20 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return () => { } }, [autoRun, categoryIndex]) + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) + } + Pos: ${locationString} + ` + ) + } + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) @@ -150,16 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' - } - Pos: ${locationString} - ` + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, From cbd56b3a11bf14fed3d2bdd5c090f50072b14907 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 24 Apr 2021 06:10:21 +0100 Subject: [PATCH 021/199] fix editor highlighter --- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 8 ++++---- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index b31a62b9de..46dfd16a15 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -25,9 +25,9 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { return result } - const handlePointToErrorOnClick = () => { - const result = opt.locationString.split(':') - editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + const handlePointToErrorOnClick = (location, fileName) => { + editor.call('editor', 'discardHighlight') + editor.call('editor', 'highlight', location, fileName) } if (!message) return @@ -48,7 +48,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => {
- + handlePointToErrorOnClick(opt.location, opt.fileName)}> {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 383bfa7643..7bcdd9d0a3 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -169,12 +169,14 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { type: 'warning', useSpan: true, errFile: fileName, + fileName, errLine: row, errCol: column, item: item, name: result.name, locationString, - more: item.more + more: item.more, + location: location } warningErrors.push(options) setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) @@ -314,7 +316,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sun, 25 Apr 2021 13:41:17 +0100 Subject: [PATCH 022/199] removed old staticAnalysis from remix-project --- .../tabs/staticanalysis/staticAnalysisView.js | 302 ------------------ .../styles/staticAnalysisView-styles.js | 36 --- .../src/lib/remix-ui-static-analyser.tsx | 42 +-- 3 files changed, 24 insertions(+), 356 deletions(-) delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js b/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js deleted file mode 100644 index 668adab89e..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js +++ /dev/null @@ -1,302 +0,0 @@ -'use strict' -var StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -var yo = require('yo-yo') -var $ = require('jquery') -var remixLib = require('@remix-project/remix-lib') -var utils = remixLib.util -var css = require('./styles/staticAnalysisView-styles') -var Renderer = require('../../ui/renderer') -const SourceHighlighter = require('../../editor/sourceHighlighter') - -var EventManager = require('../../../lib/events') - -function staticAnalysisView (localRegistry, analysisModule) { - var self = this - this.event = new EventManager() - this.view = null - this.runner = new StaticAnalysisRunner() - this.modulesView = this.renderModules() - this.lastCompilationResult = null - this.lastCompilationSource = null - this.currentFile = 'No file compiled' - this.sourceHighlighter = new SourceHighlighter() - this.analysisModule = analysisModule - self._components = { - renderer: new Renderer(analysisModule) - } - self._components.registry = localRegistry - // dependencies - self._deps = { - offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api - } - - analysisModule.on('solidity', 'compilationFinished', (file, source, languageVersion, data) => { - self.lastCompilationResult = null - self.lastCompilationSource = null - if (languageVersion.indexOf('soljson') !== 0) return - self.lastCompilationResult = data - self.lastCompilationSource = source - self.currentFile = file - self.correctRunBtnDisabled() - if (self.view && self.view.querySelector('#autorunstaticanalysis').checked) { - self.run() - } - }) -} - -staticAnalysisView.prototype.render = function () { - this.runBtn = yo`` - const view = yo` -
-
-
-
- - -
-
- - -
- ${this.runBtn} -
-
-
- ${this.modulesView} -
-
- last results for: - ${this.currentFile} -
-
-
- ` - - if (!this.view) { - this.view = view - } - this.correctRunBtnDisabled() - return view -} - -staticAnalysisView.prototype.selectedModules = function () { - if (!this.view) { - return [] - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - var toRun = [] - for (var i = 0; i < selected.length; i++) { - toRun.push(selected[i].attributes.index.value) - } - return toRun -} - -staticAnalysisView.prototype.run = function () { - if (!this.view) { - return - } - const highlightLocation = async (location, fileName) => { - await this.analysisModule.call('editor', 'discardHighlight') - await this.analysisModule.call('editor', 'highlight', location, fileName) - } - const selected = this.selectedModules() - const warningContainer = $('#staticanalysisresult') - warningContainer.empty() - this.view.querySelector('#staticAnalysisCurrentFile').innerText = this.currentFile - var self = this - if (this.lastCompilationResult && selected.length) { - this.runBtn.removeAttribute('disabled') - let warningCount = 0 - this.runner.run(this.lastCompilationResult, selected, (results) => { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - results.map((result, j) => { - let moduleName - Object.keys(groupedModules).map((key) => { - groupedModules[key].forEach((el) => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } - }) - }) - const alreadyExistedEl = this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`) - if (!alreadyExistedEl) { - warningContainer.append(` -
- ${moduleName} -
- `) - } - - result.report.map((item, i) => { - let location = '' - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = this.currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) - } - location = self._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - self.lastCompilationSource.sources, - self.lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = (row + 1) + ':' + column + ':' - fileName = Object.keys(self.lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = yo` - - ${result.name} - ${item.warning} - ${item.more ? yo`more` : yo``} - Pos: ${locationString} - ` - self._components.renderer.error( - msg, - this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`), - { - click: () => highlightLocation(location, fileName), - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column - } - ) - }) - }) - // hide empty staticAnalysisModules sections - this.view.querySelectorAll('[name="staticAnalysisModules"]').forEach((section) => { - if (!section.getElementsByClassName('alert-warning').length) section.hidden = true - }) - self.event.trigger('staticAnaysisWarning', [warningCount]) - }) - } else { - this.runBtn.setAttribute('disabled', 'disabled') - if (selected.length) { - warningContainer.html('No compiled AST available') - } - self.event.trigger('staticAnaysisWarning', [-1]) - } -} -staticAnalysisView.prototype.checkModule = function (event) { - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - const checkAll = this.view.querySelector('[id="checkAllEntries"]') - this.correctRunBtnDisabled() - if (event.target.checked) { - checkAll.checked = true - } else if (!selected.length) { - checkAll.checked = false - } -} -staticAnalysisView.prototype.correctRunBtnDisabled = function () { - if (!this.view) { - return - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - if (this.lastCompilationResult && selected.length !== 0) { - this.runBtn.removeAttribute('disabled') - } else { - this.runBtn.setAttribute('disabled', 'disabled') - } -} -staticAnalysisView.prototype.checkAll = function (event) { - if (!this.view) { - return - } - // checks/unchecks all - const checkBoxes = this.view.querySelectorAll('[name="staticanalysismodule"]') - checkBoxes.forEach((checkbox) => { checkbox.checked = event.target.checked }) - this.correctRunBtnDisabled() -} - -staticAnalysisView.prototype.handleCollapse = function (e) { - const downs = e.toElement.parentElement.getElementsByClassName('fas fa-angle-double-right') - const iEls = document.getElementsByTagName('i') - for (var i = 0; i < iEls.length; i++) { iEls[i].hidden = false } - downs[0].hidden = true -} - -staticAnalysisView.prototype.renderModules = function () { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - const moduleEntries = Object.keys(groupedModules).map((categoryId, i) => { - const category = groupedModules[categoryId] - const entriesDom = category.map((item, i) => { - return yo` -
- - -
- ` - }) - return yo` -
- this.handleCollapse(e)}"/> - -
- ${entriesDom} -
-
- ` - }) - // collaps first module - moduleEntries[0].getElementsByTagName('input')[0].checked = true - moduleEntries[0].getElementsByTagName('i')[0].hidden = true - return yo` -
- ${moduleEntries} -
` -} - -module.exports = staticAnalysisView - -/** - * @dev Process & categorize static analysis modules to show them on UI - * @param arr list of static analysis modules received from remix-analyzer module - */ -function preProcessModules (arr) { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js b/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js deleted file mode 100644 index bd277a03aa..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js +++ /dev/null @@ -1,36 +0,0 @@ -var csjs = require('csjs-inject') - -var css = csjs` - .analysis { - display: flex; - flex-direction: column; - } - .result { - margin-top: 1%; - max-height: 300px; - word-break: break-word; - } - .buttons { - margin: 1rem 0; - } - .label { - display: flex; - align-items: center; - } - .label { - display: flex; - align-items: center; - user-select: none; - } - .block input[type='radio']:checked ~ .entries{ - height: auto; - transition: .5s ease-in; - } - .entries{ - height: 0; - overflow: hidden; - transition: .5s ease-out; - } -` - -module.exports = css diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7bcdd9d0a3..8cae6c9e60 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -81,27 +81,30 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [warningState, setWarningState] = useState([]) - useEffect(() => { - if (autoRun) { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } + const executeCompilation = () => { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } + if (props.analysisModule) { + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (categoryIndex.length > 0) { + run(data, source, file) } - ) - } + } + ) } + } + useEffect(() => { + if (autoRun) { + executeCompilation() + } return () => { } }, [autoRun, categoryIndex]) @@ -270,6 +273,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label={item.description} onClick={event => handleCheckSingle(event, item._index)} checked={categoryIndex.includes(item._index.toString())} + onChange={() => {}} />
) @@ -297,7 +301,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -327,6 +331,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} + onChange={() => {}} /> { onClick={handleAutoRun} checked={autoRun} label="Autorun" + onChange={() => {}} />
From b851b9695406c3ebf89798c267f10f0040a4e670 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 03:25:23 +0100 Subject: [PATCH 023/199] created actions and reducer to optimise code --- .../src/lib/actions/staticAnalysisActions.ts | 24 +++ .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++++++++ .../src/lib/remix-ui-static-analyser.tsx | 153 ++++++++++-------- 3 files changed, 172 insertions(+), 70 deletions(-) create mode 100644 libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts new file mode 100644 index 0000000000..ab9b8d3fc9 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -0,0 +1,24 @@ +import React, { useState } from 'react' //eslint-disable-line + +export const compilation = (analysisModule, state, run) => { +// const setCompilationResult = async (data, source, file) => { +// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) +// } + if (analysisModule) { + analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (state.categoryIndex.length > 0) { + run(data, source, file) + } + } + ) + } +} + +export const setCompilationResult = async (data, source, file) => { + return await { data, source, file } +} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts new file mode 100644 index 0000000000..f2f1a8c9d0 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -0,0 +1,65 @@ +import remixLib from '@remix-project/remix-lib' +import * as _ from 'lodash' +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis + +const utils = remixLib.util + +const runner = new StaticAnalysisRunner() + +const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) +} + +const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' +) + +const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) +} +const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory +} + +export const initialState = { categoryIndex: [] } + +export const analysisReducer = (state, action) => { + switch (action.type) { + case 'initialize': + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + case 'uncheck': + return { + ...state, + categoryIndex: state.categoryIndex.filter((el) => { + return !action.payload.includes(el) + }) + } + case 'check': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + case 'uncheckSingle': + return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + case 'checkSingle': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + default: + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + } +} diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8cae6c9e60..c0c89415c9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState, useReducer } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -7,6 +7,9 @@ import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +import { compilation, setCompilationResult } from './actions/staticAnalysisActions' +import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' + const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -62,7 +65,32 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + // const initialState = { categoryIndex: [] } + + // const reducer = (state, action) => { + // console.log({ action }) + // switch (action.type) { + // case 'initialize': + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // case 'uncheck': + // return { + // categoryIndex: state.categoryIndex.filter((el) => { + // return !action.payload.includes(el) + // }) + // } + // case 'check': + // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + // case 'uncheckSingle': + // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + // case 'checkSingle': + // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + // default: + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // } + // } + + const [state, dispatch] = useReducer(analysisReducer, initialState) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) @@ -74,63 +102,51 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [, setModuleNameResult] = useState(null) const [, setWarning] = useState({ - msg: '', options: {}, hasWarning: false, warningErrors: [] }) const [warningState, setWarningState] = useState([]) - const executeCompilation = () => { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } - - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } - } - ) - } - } + // const executeCompilation = (categoryIndex) => { + // const setCompilationResult = async (data, source, file) => { + // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + // } + // if (props.analysisModule) { + // props.analysisModule.on( + // 'solidity', + // 'compilationFinished', + // (file, source, languageVersion, data) => { + // if (languageVersion.indexOf('soljson') !== 0) return + // setCompilationResult(data, source, file) + // console.log(categoryIndex, ' inside execute funtions') + // if (state.categoryIndex.length > 0) { + // run(data, source, file) + // } + // } + // ) + // } + // } useEffect(() => { if (autoRun) { - executeCompilation() + if (props.analysisModule && state.categoryIndex.length > 0) { + compilation(props.analysisModule, state, run) + } } - return () => { } - }, [autoRun, categoryIndex]) - - const message = (name, warning, more, fileName, locationString) : string => { - return (` - - ${name} - ${warning} - ${more - ? (more) - : ( ) + return () => { } - Pos: ${locationString} - ` - ) - } + }, [autoRun, state, props.analysisModule, setWarning]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length > 0) { + if (lastCompilationResult && state.categoryIndex.length > 0) { setRunButtonState(false) let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { + runner.run(lastCompilationResult, state.categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -167,7 +183,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -182,8 +197,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + setWarning({ hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -201,16 +216,21 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } - const groupedCategory = groupBy(resultArray, 'warningModuleName') + console.log({ warningCount }, ' 221') + console.log({ groupedCategory }) setWarningState(groupedCategory) + console.log({ warningState }) + console.log({ warningCount }, ' 223') }) - if (categoryIndex.length > 0) { + console.log({ warningCount }, ' CategoryIndex outside function') + if (state.categoryIndex.length > 0) { + console.log(state.categoryIndex, ' CategoryIndex in execute funtions') props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { setRunButtonState(true) - if (categoryIndex.length) { + if (state.categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -220,27 +240,19 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } @@ -254,10 +266,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (categoryIndex.includes(_index)) { - setCategoryIndex(categoryIndex.filter(val => val !== _index)) + if (state.categoryIndex.includes(_index)) { + dispatch({ type: 'uncheckSingle', payload: _index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, _index])) + dispatch({ type: 'checkSingle', payload: _index }) } } @@ -272,7 +284,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={categoryIndex.includes(item._index.toString())} + checked={state.categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -301,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -328,7 +340,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => categoryIndex.includes(el))} + }).flat().every(el => state.categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -341,7 +353,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -362,10 +374,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { console.log({ warningState }) } + { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- { + {/* { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -379,7 +392,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } + } */}
} From 36a37ef7bb5625bac320c310ba9f7bf0dfdcbc91 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 17:30:40 +0100 Subject: [PATCH 024/199] refactored static analysis to improve performance --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 ----- .../static-analyser/src/lib/ErrorRenderer.tsx | 3 +- .../src/lib/actions/staticAnalysisActions.ts | 16 +- .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++----- .../src/lib/remix-ui-static-analyser.tsx | 163 ++++++------------ 5 files changed, 71 insertions(+), 221 deletions(-) delete mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx deleted file mode 100644 index e42caa4851..0000000000 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' //eslint-disable-line - -interface StaticAnalyserCheckBoxProps { - onClick?: (event) => void - onChange?: (event) => void - label?: string - inputType?: string - name?: string - checked?: boolean - id?: string - itemName?: string - categoryId?: string -} - -const StaticAnalyserCheckedBox = ({ - id, - label, - onClick, - inputType, - name, - checked, - onChange, - itemName, - categoryId -}: StaticAnalyserCheckBoxProps) => { - return ( -
- - -
- ) -} - -export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 46dfd16a15..6f1989e3ac 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line interface ErrorRendererProps { message: any; @@ -32,6 +32,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { if (!message) return let position = getPositionDetails(message) + console.log({ position }) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { // Updated error reported includes '-->' before file details const errorDetails = message.split('-->') diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts index ab9b8d3fc9..4f55437cb6 100644 --- a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -1,24 +1,14 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line -export const compilation = (analysisModule, state, run) => { -// const setCompilationResult = async (data, source, file) => { -// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) -// } +export const compilation = (analysisModule, dispatch) => { if (analysisModule) { analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (state.categoryIndex.length > 0) { - run(data, source, file) - } + dispatch({ type: 'compilationFinished', payload: { file, source, languageVersion, data } }) } ) } } - -export const setCompilationResult = async (data, source, file) => { - return await { data, source, file } -} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts index f2f1a8c9d0..833ef55b39 100644 --- a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -1,65 +1,22 @@ -import remixLib from '@remix-project/remix-lib' -import * as _ from 'lodash' -const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -const utils = remixLib.util - -const runner = new StaticAnalysisRunner() - -const preProcessModules = (arr: any) => { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} - -const groupedModules = utils.groupBy( - preProcessModules(runner.modules()), - 'categoryId' -) - -const getIndex = (modules, array) => { - Object.values(modules).map((value: {_index}) => { - if (Array.isArray(value)) { - value.forEach((x) => { - array.push(x._index.toString()) - }) - } else { - array.push(value._index.toString()) - } - }) -} -const groupedModuleIndex = (modules) => { - const indexOfCategory = [] - if (!_.isEmpty(modules)) { - getIndex(modules, indexOfCategory) - } - return indexOfCategory +export const initialState = { + file: null, + source: null, + languageVersion: null, + data: null } -export const initialState = { categoryIndex: [] } - export const analysisReducer = (state, action) => { switch (action.type) { - case 'initialize': - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } - case 'uncheck': + case 'compilationFinished': return { ...state, - categoryIndex: state.categoryIndex.filter((el) => { - return !action.payload.includes(el) - }) + file: action.payload.file, + source: action.payload.source, + languageVersion: action.payload.languageVersion, + data: action.payload.data } - case 'check': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - case 'uncheckSingle': - return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - case 'checkSingle': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } default: - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + return initialState } } diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index c0c89415c9..7725321271 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,30 +1,20 @@ import React, { useEffect, useState, useReducer } from 'react' -import ReactDOM from 'react-dom' //eslint-disable-line -import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line -import { compilation, setCompilationResult } from './actions/staticAnalysisActions' -import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' - +import { compilation } from './actions/staticAnalysisActions' +import { initialState, analysisReducer } from './reducers/staticAnalysisReducer' const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util /* eslint-disable-next-line */ export interface RemixUiStaticAnalyserProps { - renderStaticAnalysis: any - staticanalysis: any - analysisRunner: any, - lastCompilationResult: any, - lastCompilationSource: any, registry: any, event: any, analysisModule: any - _deps: any, - emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -65,88 +55,46 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - - // const initialState = { categoryIndex: [] } - - // const reducer = (state, action) => { - // console.log({ action }) - // switch (action.type) { - // case 'initialize': - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // case 'uncheck': - // return { - // categoryIndex: state.categoryIndex.filter((el) => { - // return !action.payload.includes(el) - // }) - // } - // case 'check': - // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - // case 'uncheckSingle': - // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - // case 'checkSingle': - // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } - // default: - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // } - // } - - const [state, dispatch] = useReducer(analysisReducer, initialState) + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) - const [runButtonState, setRunButtonState] = useState(true) - - const [result, setResult] = useState({ - lastCompilationResult: null, - lastCompilationSource: null, - currentFile: 'No file compiled' - }) - const [, setModuleNameResult] = useState(null) - const [, setWarning] = useState({ - options: {}, - hasWarning: false, - warningErrors: [] - }) const [warningState, setWarningState] = useState([]) + const [state, dispatch] = useReducer(analysisReducer, initialState) - // const executeCompilation = (categoryIndex) => { - // const setCompilationResult = async (data, source, file) => { - // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - // } - // if (props.analysisModule) { - // props.analysisModule.on( - // 'solidity', - // 'compilationFinished', - // (file, source, languageVersion, data) => { - // if (languageVersion.indexOf('soljson') !== 0) return - // setCompilationResult(data, source, file) - // console.log(categoryIndex, ' inside execute funtions') - // if (state.categoryIndex.length > 0) { - // run(data, source, file) - // } - // } - // ) - // } - // } + useEffect(() => { + compilation(props.analysisModule, dispatch) + }, []) useEffect(() => { if (autoRun) { - if (props.analysisModule && state.categoryIndex.length > 0) { - compilation(props.analysisModule, state, run) + if (state.data !== null) { + run(state.data, state.source, state.file) } } - return () => { + return () => { } + }, [autoRun, categoryIndex, state]) + + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) } - }, [autoRun, state, props.analysisModule, setWarning]) + Pos: ${locationString} + ` + ) + } const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && state.categoryIndex.length > 0) { - setRunButtonState(false) + if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, state.categoryIndex, results => { + runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -156,7 +104,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } }) }) - setModuleNameResult(moduleName) const warningErrors = [] result.report.map((item) => { let location: any = {} @@ -183,6 +130,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -197,8 +145,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -216,21 +163,15 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } + const groupedCategory = groupBy(resultArray, 'warningModuleName') - console.log({ warningCount }, ' 221') - console.log({ groupedCategory }) setWarningState(groupedCategory) - console.log({ warningState }) - console.log({ warningCount }, ' 223') }) - console.log({ warningCount }, ' CategoryIndex outside function') - if (state.categoryIndex.length > 0) { - console.log(state.categoryIndex, ' CategoryIndex in execute funtions') + if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { - setRunButtonState(true) - if (state.categoryIndex.length) { + if (categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -240,19 +181,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } @@ -266,10 +215,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (state.categoryIndex.includes(_index)) { - dispatch({ type: 'uncheckSingle', payload: _index }) + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) } else { - dispatch({ type: 'checkSingle', payload: _index }) + setCategoryIndex(_.uniq([...categoryIndex, _index])) } } @@ -284,7 +233,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={state.categoryIndex.includes(item._index.toString())} + checked={categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -313,7 +262,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -340,7 +289,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => state.categoryIndex.includes(el))} + }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -353,7 +302,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -371,14 +320,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { className="text-break break-word word-break font-weight-bold" id="staticAnalysisCurrentFile" > - {result.currentFile && result.currentFile}
- { console.log({ warningState }) } - { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- {/* { + { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -392,7 +339,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } */} + }
} From 93b0e5f0451dab95b262b3fa048e961a99f06e96 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 10 Apr 2021 02:06:33 +0100 Subject: [PATCH 025/199] refactor: added custom checkbox for static analyser plugin --- apps/remix-ide/src/app/tabs/analysis-tab.js | 49 ++- libs/remix-ui/static-analyser/.babelrc | 4 + libs/remix-ui/static-analyser/.eslintrc | 19 + libs/remix-ui/static-analyser/README.md | 7 + libs/remix-ui/static-analyser/src/index.ts | 1 + .../src/lib/Button/StaticAnalyserButton.tsx | 23 ++ .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 +++ .../static-analyser/src/lib/ErrorRenderer.tsx | 76 ++++ .../src/lib/remix-ui-static-analyser.tsx | 381 ++++++++++++++++++ libs/remix-ui/static-analyser/tsconfig.json | 16 + .../static-analyser/tsconfig.lib.json | 13 + nx.json | 3 + package-lock.json | 6 +- package.json | 1 + tsconfig.json | 5 +- workspace.json | 19 + 16 files changed, 647 insertions(+), 21 deletions(-) create mode 100644 libs/remix-ui/static-analyser/.babelrc create mode 100644 libs/remix-ui/static-analyser/.eslintrc create mode 100644 libs/remix-ui/static-analyser/README.md create mode 100644 libs/remix-ui/static-analyser/src/index.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx create mode 100644 libs/remix-ui/static-analyser/tsconfig.json create mode 100644 libs/remix-ui/static-analyser/tsconfig.lib.json diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index 4406ba875e..ad3c2fce54 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -1,9 +1,11 @@ +import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' +import ReactDOM from 'react-dom' import { EventEmitter } from 'events' +import {RemixUiStaticAnalyser} from '@remix-ui/static-analyser' // eslint-disable-line import * as packageJson from '../../../../../package.json' +var Renderer = require('../ui/renderer') -var yo = require('yo-yo') -var StaticAnalysis = require('./staticanalysis/staticAnalysisView') var EventManager = require('../../lib/events') const profile = { @@ -25,24 +27,39 @@ class AnalysisTab extends ViewPlugin { this.event = new EventManager() this.events = new EventEmitter() this.registry = registry + this.element = document.createElement('div') + this.element.setAttribute('id', 'staticAnalyserView') + this._components = { + renderer: new Renderer(this) + } + this._components.registry = this.registry + this._deps = { + offsetToLineColumnConverter: this.registry.get( + 'offsettolinecolumnconverter').api + } + } + + onActivation () { + this.renderComponent() } render () { - this.staticanalysis = new StaticAnalysis(this.registry, this) - this.staticanalysis.event.register('staticAnaysisWarning', (count) => { - if (count > 0) { - this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) - } else if (count === 0) { - this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) - } else { - // count ==-1 no compilation result - this.emit('statusChanged', { key: 'none' }) - } - }) - this.registry.put({ api: this.staticanalysis, name: 'staticanalysis' }) - - return yo`
${this.staticanalysis.render()}
` + return this.element } + + renderComponent () { + ReactDOM.render( + , + this.element + ) + } + } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/.babelrc b/libs/remix-ui/static-analyser/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/static-analyser/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/static-analyser/.eslintrc b/libs/remix-ui/static-analyser/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/static-analyser/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/static-analyser/README.md b/libs/remix-ui/static-analyser/README.md new file mode 100644 index 0000000000..7e4b95c0e5 --- /dev/null +++ b/libs/remix-ui/static-analyser/README.md @@ -0,0 +1,7 @@ +# remix-ui-static-analyser + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-static-analyser` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/static-analyser/src/index.ts b/libs/remix-ui/static-analyser/src/index.ts new file mode 100644 index 0000000000..86a00ccd14 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-static-analyser' diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx new file mode 100644 index 0000000000..5cd7e9392b --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -0,0 +1,23 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserButtonProps { + onClick: (event) => void + buttonText: string, + disabled?: boolean +} + +const StaticAnalyserButton = ({ + onClick, + buttonText, + disabled +}: StaticAnalyserButtonProps) => { + return ( +
+ +
+ ) +} + +export default StaticAnalyserButton diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx new file mode 100644 index 0000000000..2326a39122 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -0,0 +1,45 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserCheckBoxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +const StaticAnalyserCheckedBox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: StaticAnalyserCheckBoxProps) => { + return ( +
+ + +
+ ) +} + +export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx new file mode 100644 index 0000000000..7b7a01f37d --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -0,0 +1,76 @@ +import React, { useState } from 'react' //eslint-disable-line + +interface ErrorRendererProps { + message: any; + opt: any, + warningErrors: any +} + +const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { + const [, setError] = useState( + { + row: null, + column: null, + text: null, + type: null, + errFile: null + } + ) + const getPositionDetails = (msg: any) => { + const result = { } as any + + // To handle some compiler warning without location like SPDX license warning etc + if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } + + // extract line / column + let position = msg.match(/^(.*?):([0-9]*?):([0-9]*?)?/) + result.errLine = position ? parseInt(position[2]) - 1 : -1 + result.errCol = position ? parseInt(position[3]) : -1 + + // extract file + position = msg.match(/^(https:.*?|http:.*?|.*?):/) + result.errFile = position ? position[1] : '' + return result + } + if (!message) return + let position = getPositionDetails(message) + if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { + // Updated error reported includes '-->' before file details + const errorDetails = message.split('-->') + // errorDetails[1] will have file details + if (errorDetails.length > 1) position = getPositionDetails(errorDetails[1]) + } + opt.errLine = position.errLine + opt.errCol = position.errCol + opt.errFile = position.errFile.trim() + if (!opt.noAnnotations && opt.errFile) { + setError({ + errFile: opt.errFile, + row: opt.errLine, + column: opt.errCol, + text: message, + type: opt.type + }) + } + const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' + return ( +
+
+
+ +
+ + {opt.item.name} + { opt.item.warning } + {opt.item.more + ? more + : + } + Pos: {opt.locationString} + +
+
+ ) +} + +export default ErrorRenderer diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx new file mode 100644 index 0000000000..1674d66d84 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -0,0 +1,381 @@ +import React, { useEffect, useState } from 'react' +import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line +import Button from './Button/StaticAnalyserButton' // eslint-disable-line +import remixLib from '@remix-project/remix-lib' +import _ from 'lodash' +import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis +const utils = remixLib.util + +/* eslint-disable-next-line */ +export interface RemixUiStaticAnalyserProps { + renderStaticAnalysis: any + staticanalysis: any + analysisRunner: any, + lastCompilationResult: any, + lastCompilationSource: any, + registry: any, + event: any, + analysisModule: any + _deps: any +} + +export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { + const [runner] = useState(new StaticAnalysisRunner()) + + const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) + } + + const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' + ) + + const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) + } + + const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory + } + + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + const warningContainer = React.useRef(null) + const [runButtonState, setRunButtonState] = useState(true) + const [autoRun, setAutoRun] = useState(true) + const [result, setResult] = useState({ + lastCompilationResult: null, + lastCompilationSource: null, + currentFile: 'No file compiled' + }) + const [, setModuleNameResult] = useState(null) + const [, setWarning] = useState({ + msg: '', + options: {}, + hasWarning: false, + warningErrors: [] + }) + const [warningState, setWarningState] = useState([]) + + useEffect(() => { + if (autoRun) { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } + + if (props.analysisModule) { + console.log({ autoRun }) + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + run(data, source, file) + } + ) + } + } + return () => { } + }, [autoRun]) + + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { + // const highlightLocation = async (location, fileName) => { + // await props.analysisModule.call('editor', 'discardHighlight') + // await props.analysisModule.call('editor', 'highlight', location, fileName) + // } + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] + + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) + }) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + var split = item.location.split(':') + var file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] + } + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more + } + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) + }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) + }) + props.event.trigger('staticAnaysisWarning', [warningCount]) + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) + } + } + + // const correctRunBtnDisabled = () => { + // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { + // setRunButtonState(false) + // } else { + // setRunButtonState(true) + // } + // } + + const handleCheckAllModules = (groupedModules) => { + const index = groupedModuleIndex(groupedModules) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleCheckOrUncheckCategory = (category) => { + const index = groupedModuleIndex(category) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleAutoRun = () => { + if (autoRun) { + setAutoRun(false) + } else { + setAutoRun(true) + } + console.log(' auton run function') + } + + const handleCheckSingle = (event, _index) => { + _index = _index.toString() + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) + } else { + setCategoryIndex(_.uniq([...categoryIndex, _index])) + } + } + + const categoryItem = (categoryId, item, i) => { + return ( +
+ handleCheckSingle(event, item._index)} + checked={categoryIndex.includes(item._index.toString())} + /> +
+ ) + } + + const categorySection = (category, categoryId, i) => { + return ( +
+
+ + + {category[0].categoryDisplayName} +
+ +
+ + } + expand={true} + > +
+ handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> +
+
+ {category.map((item, i) => { + return ( + categoryItem(categoryId, item, i) + ) + })} +
+
+
+
+
+ ) + } + + return ( +
+
+
+
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
+
+ +
+
+
+
+ {Object.keys(groupedModules).map((categoryId, i) => { + const category = groupedModules[categoryId] + return ( + categorySection(category, categoryId, i) + ) + }) + } +
+
+ last results for: + + {result.currentFile && result.currentFile} + +
+
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
+
+
+ ) +} + +export default RemixUiStaticAnalyser diff --git a/libs/remix-ui/static-analyser/tsconfig.json b/libs/remix-ui/static-analyser/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/static-analyser/tsconfig.lib.json b/libs/remix-ui/static-analyser/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index 5cf047d9cc..802b6fe374 100644 --- a/nx.json +++ b/nx.json @@ -95,6 +95,9 @@ }, "remix-ui-workspace": { "tags": [] + }, + "remix-ui-static-analyser": { + "tags": [] } } } diff --git a/package-lock.json b/package-lock.json index ca2eb9f4a5..d0c0ce7b6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25004,9 +25004,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { "version": "4.17.15", diff --git a/package.json b/package.json index d67f99f74f..0b7fcd4372 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ "http-server": "^0.11.1", "isbinaryfile": "^3.0.2", "jszip": "^3.6.0", + "lodash": "^4.17.21", "merge": "^1.2.0", "npm-install-version": "^6.0.2", "react": "16.13.1", diff --git a/tsconfig.json b/tsconfig.json index c2a383e9de..c90ed09031 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "target": "es2015", "module": "commonjs", "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "dom"], + "lib": ["es2017", "es2019", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", @@ -38,7 +38,8 @@ "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], - "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"] + "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 10793e13b3..9c734f96a7 100644 --- a/workspace.json +++ b/workspace.json @@ -725,6 +725,25 @@ } } } + }, + "remix-ui-static-analyser": { + "root": "libs/remix-ui/static-analyser", + "sourceRoot": "libs/remix-ui/static-analyser/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/static-analyser/tsconfig.lib.json"], + "exclude": [ + "**/node_modules/**", + "!libs/remix-ui/static-analyser/**/*" + ] + } + } + } } }, "cli": { From 9b3eda8e7fbbd321b52106b86652fbc8e5d50be1 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 12:51:49 +0100 Subject: [PATCH 026/199] added warning sign when analysis has runned --- apps/remix-ide/src/app/tabs/analysis-tab.js | 15 +++++++++++++-- .../src/lib/remix-ui-static-analyser.tsx | 19 +++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index ad3c2fce54..b3bba2705c 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -56,10 +56,21 @@ class AnalysisTab extends ViewPlugin { analysisModule={this} event={this.event} />, - this.element + this.element, + () => { + this.event.register('staticAnaysisWarning', (count) => { + if (count > 0) { + this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) + } else if (count === 0) { + this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) + } else { + // count ==-1 no compilation result + this.emit('statusChanged', { key: 'none' }) + } + }) + } ) } - } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 1674d66d84..81d4e29e15 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' +import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' @@ -18,7 +19,8 @@ export interface RemixUiStaticAnalyserProps { registry: any, event: any, analysisModule: any - _deps: any + _deps: any, + emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -63,7 +65,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(true) + const [autoRun, setAutoRun] = useState(false) const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -96,7 +98,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } ) } + } else { + setAutoRun(true) } + return () => { } }, [autoRun]) @@ -105,6 +110,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } + console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -193,6 +199,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) + props.event.trigger('staticAnaysisWarning', [warningCount]) } else { setRunButtonState(true) @@ -203,14 +210,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } } - // const correctRunBtnDisabled = () => { - // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { - // setRunButtonState(false) - // } else { - // setRunButtonState(true) - // } - // } - const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) if (index.every(el => categoryIndex.includes(el))) { From 5a6953c9ac3e64a2623023d9b88d687ebb6cb3c8 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 13:05:48 +0100 Subject: [PATCH 027/199] removed icon: fas fa-angle-double-right from each category display name --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 81d4e29e15..b1810c3143 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -288,9 +288,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { data-bs-target={`#heading${categoryId}`} > {category[0].categoryDisplayName} -
- -
} expand={true} From 6f1d745f49d56125afae41197eeca50eb091eb88 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 13 Apr 2021 18:37:37 +0100 Subject: [PATCH 028/199] adding a condition to fix ci build --- .../src/lib/remix-ui-static-analyser.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index b1810c3143..5000a94c01 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -356,20 +356,22 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
-
-
- { - (Object.entries(warningState).map((element) => ( - <> - {element[0]} - {element[1].map(x => ( - x.hasWarning ? () : null - ))} - - ))) - } + { Object.entries(warningState).length > 0 && +
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
-
+ }
) } From 5666d303c46df4b94700d3ca43e5c914da0377ae Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 06:49:06 +0100 Subject: [PATCH 029/199] fix: testing to see if test passes --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..b2c3f41cb6 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 7b7a01f37d..878cccb7da 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -60,7 +60,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
- {opt.item.name} + {opt.name} { opt.item.warning } {opt.item.more ? more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5000a94c01..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -164,6 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` + console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, From 219ff3af27daf5f31fb8e6e1a02bee1649688428 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 09:19:39 +0100 Subject: [PATCH 030/199] added className staticAnalysisView to staticAnalyser component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index b2c3f41cb6..a68a4a24ce 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..93b1b6b3a4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Fri, 16 Apr 2021 09:54:37 +0100 Subject: [PATCH 031/199] remove className staticAnalysisView and added id = staticanalysisView --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 93b1b6b3a4..8e42d97ce4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:07:13 +0100 Subject: [PATCH 032/199] fix: moved staticanalysisButton id to the Button component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/Button/StaticAnalyserButton.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,7 +40,7 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisView button') + .click('#staticanalysisButton button') .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 5cd7e9392b..336a0fe56a 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,7 +12,7 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
+
diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8e42d97ce4..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:27:48 +0100 Subject: [PATCH 033/199] fix: removed disabled props on button --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..38e4988a0f 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From e50b0e5de85d9acdde0ddb1d64b3f31009972bcc Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 06:52:33 +0100 Subject: [PATCH 034/199] reversed changes --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 38e4988a0f..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From 19de4ba6b05011a820cca67e0eee7d46a3d83bb3 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 17:49:24 +0100 Subject: [PATCH 035/199] commiting code to detect failing test --- .../src/tests/staticAnalysis.spec.ts | 24 +++++++++---------- .../src/lib/remix-ui-static-analyser.tsx | 4 ---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..480fab63fb 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,18 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) + //.click('#staticanalysisButton button') + // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + // listSelectorContains(['Use of tx.origin', + // 'Fallback function of contract TooMuchGas requires too much gas', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + // '#staticanalysisresult .warning', + // browser, function () { + // browser.end() + // } + // ) + // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..5a24785838 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -87,7 +87,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } if (props.analysisModule) { - console.log({ autoRun }) props.analysisModule.on( 'solidity', 'compilationFinished', @@ -110,7 +109,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } - console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -164,7 +162,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` - console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, @@ -243,7 +240,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } else { setAutoRun(true) } - console.log(' auton run function') } const handleCheckSingle = (event, _index) => { From d1d9122c192267925a728ec71ba081f54f8d1850 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:00:14 +0100 Subject: [PATCH 036/199] removed comments --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 480fab63fb..e9777e2970 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,6 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - //.click('#staticanalysisButton button') - // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - // listSelectorContains(['Use of tx.origin', - // 'Fallback function of contract TooMuchGas requires too much gas', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - // '#staticanalysisresult .warning', - // browser, function () { - // browser.end() - // } - // ) - // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { From b88913ff516c61528d8d66843ad0b8b8321095b3 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:09:41 +0100 Subject: [PATCH 037/199] removing comments and unused functions --- .../src/tests/staticAnalysis.spec.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index e9777e2970..a10a2a8348 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -42,20 +42,4 @@ function runTests (browser: NightwatchBrowser) { .clickLaunchIcon('solidityStaticAnalysis') } -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) -} + From 288754383d67c9f12833a42d95e997a039d8a442 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:20:19 +0100 Subject: [PATCH 038/199] removed extra space at end of file --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a10a2a8348..8fa094273e 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,6 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} - - +} \ No newline at end of file From f42daa20f580ad15df5f9b8570a9a61e236e1251 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:27:17 +0100 Subject: [PATCH 039/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 8fa094273e..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} \ No newline at end of file + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) +} From 8cf8b84d1c1642e3e0481ab1f9e4a9c249dd3e8b Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:35:52 +0100 Subject: [PATCH 040/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..55f7329f65 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,34 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) -} - -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) } From cb4c85c0d35960ac90bf663b276bc23aa2a5c5d2 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:37:33 +0100 Subject: [PATCH 041/199] restored staticAnalysis.spec.ts to it previous code structure --- .../src/tests/staticAnalysis.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 55f7329f65..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) } From 8a85ae84edce826bc1f8ad6ea35dc1237885b04f Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 19 Apr 2021 14:25:28 +0100 Subject: [PATCH 042/199] fix failing test --- .../src/lib/remix-ui-static-analyser.tsx | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5a24785838..2fb460eec9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -81,19 +81,24 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { + if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { + props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - run(data, source, file) + if(categoryIndex.length > 0){ + run(data, source, file) + } + } ) } @@ -102,7 +107,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return () => { } - }, [autoRun]) + }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { // const highlightLocation = async (location, fileName) => { @@ -197,8 +202,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) - - props.event.trigger('staticAnaysisWarning', [warningCount]) + if(categoryIndex.length > 0){ + props.event.trigger('staticAnaysisWarning', [warningCount]) + } } else { setRunButtonState(true) if (categoryIndex.length) { @@ -217,8 +223,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + setCategoryIndex(_.uniq([...categoryIndex])) } + } const handleCheckOrUncheckCategory = (category) => { @@ -353,9 +360,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
-
+
{ (Object.entries(warningState).map((element) => ( <> From 1b39eb1577830a65f0bae601adfa9444ff58d21c Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 11:23:00 +0100 Subject: [PATCH 043/199] feat_fix_n_refactor: exptracted checkbox as a reusable component and fix selec all and auto run, --- libs/remix-ui/checkbox/.babelrc | 4 + libs/remix-ui/checkbox/.eslintrc | 19 ++ libs/remix-ui/checkbox/README.md | 7 + libs/remix-ui/checkbox/src/index.ts | 1 + .../checkbox/src/lib/remix-ui-checkbox.css | 0 .../checkbox/src/lib/remix-ui-checkbox.tsx | 47 ++++ libs/remix-ui/checkbox/tsconfig.json | 16 ++ libs/remix-ui/checkbox/tsconfig.lib.json | 13 + .../src/lib/Button/StaticAnalyserButton.tsx | 8 +- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 8 +- .../static-analyser/src/lib/ErrorRenderer.tsx | 31 +-- .../src/lib/remix-ui-static-analyser.tsx | 260 +++++++++--------- nx.json | 3 + package.json | 2 +- tsconfig.json | 3 +- workspace.json | 16 ++ 16 files changed, 273 insertions(+), 165 deletions(-) create mode 100644 libs/remix-ui/checkbox/.babelrc create mode 100644 libs/remix-ui/checkbox/.eslintrc create mode 100644 libs/remix-ui/checkbox/README.md create mode 100644 libs/remix-ui/checkbox/src/index.ts create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx create mode 100644 libs/remix-ui/checkbox/tsconfig.json create mode 100644 libs/remix-ui/checkbox/tsconfig.lib.json diff --git a/libs/remix-ui/checkbox/.babelrc b/libs/remix-ui/checkbox/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/checkbox/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/checkbox/.eslintrc b/libs/remix-ui/checkbox/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/checkbox/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/checkbox/README.md b/libs/remix-ui/checkbox/README.md new file mode 100644 index 0000000000..56f9b617b0 --- /dev/null +++ b/libs/remix-ui/checkbox/README.md @@ -0,0 +1,7 @@ +# remix-ui-checkbox + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-checkbox` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/checkbox/src/index.ts b/libs/remix-ui/checkbox/src/index.ts new file mode 100644 index 0000000000..27b694c6bd --- /dev/null +++ b/libs/remix-ui/checkbox/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-checkbox' diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx new file mode 100644 index 0000000000..5535a05971 --- /dev/null +++ b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx @@ -0,0 +1,47 @@ +import React from 'react' //eslint-disable-line +import './remix-ui-checkbox.css' + +/* eslint-disable-next-line */ +export interface RemixUiCheckboxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +export const RemixUiCheckbox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: RemixUiCheckboxProps) => { + return ( +
+ + +
+ ) +} + +export default RemixUiCheckbox diff --git a/libs/remix-ui/checkbox/tsconfig.json b/libs/remix-ui/checkbox/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/checkbox/tsconfig.lib.json b/libs/remix-ui/checkbox/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 336a0fe56a..2a67c82cf8 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,11 +12,9 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
- -
+ ) } diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx index 2326a39122..e42caa4851 100644 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -24,7 +24,7 @@ const StaticAnalyserCheckedBox = ({ categoryId }: StaticAnalyserCheckBoxProps) => { return ( -
+
-
) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 878cccb7da..b31a62b9de 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -4,20 +4,12 @@ interface ErrorRendererProps { message: any; opt: any, warningErrors: any + editor: any } -const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { - const [, setError] = useState( - { - row: null, - column: null, - text: null, - type: null, - errFile: null - } - ) +const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { const getPositionDetails = (msg: any) => { - const result = { } as any + const result = { } as Record // To handle some compiler warning without location like SPDX license warning etc if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } @@ -32,6 +24,12 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { result.errFile = position ? position[1] : '' return result } + + const handlePointToErrorOnClick = () => { + const result = opt.locationString.split(':') + editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + } + if (!message) return let position = getPositionDetails(message) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { @@ -43,15 +41,6 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { opt.errLine = position.errLine opt.errCol = position.errCol opt.errFile = position.errFile.trim() - if (!opt.noAnnotations && opt.errFile) { - setError({ - errFile: opt.errFile, - row: opt.errLine, - column: opt.errCol, - text: message, - type: opt.type - }) - } const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' return (
@@ -59,7 +48,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
- + {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 2fb460eec9..21acfe376a 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,10 +1,11 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -60,12 +61,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return indexOfCategory } - + const [autoRun, setAutoRun] = useState(true) const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(false) + const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -81,136 +82,129 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { - if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { - props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - if(categoryIndex.length > 0){ + if (categoryIndex.length > 0) { run(data, source, file) } - } ) } - } else { - setAutoRun(true) } return () => { } }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { - // const highlightLocation = async (location, fileName) => { - // await props.analysisModule.call('editor', 'discardHighlight') - // await props.analysisModule.call('editor', 'highlight', location, fileName) - // } - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length) { - setRunButtonState(false) - let warningCount = 0 - const warningMessage = [] + if (autoRun) { + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length > 0) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { - results.map((result) => { - let moduleName - Object.keys(groupedModules).map(key => { - groupedModules[key].forEach(el => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) }) - }) - setModuleNameResult(moduleName) - const warningErrors = [] - result.report.map((item) => { - let location: any = {} - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + const split = item.location.split(':') + const file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] } - location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - lastCompilationSource.sources, - lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = row + 1 + ':' + column + ':' - fileName = Object.keys(lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more } - Pos: ${locationString} - ` - const options = { - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column, - item: item, - name: result.name, - locationString, - more: item.more - } - warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) }) - const resultArray = [] - warningMessage.map(x => { - resultArray.push(x) - }) - function groupBy (objectArray, property) { - return objectArray.reduce((acc, obj) => { - const key = obj[property] - if (!acc[key]) { - acc[key] = [] - } - // Add object to list for given key's value - acc[key].push(obj) - return acc - }, {}) + if (categoryIndex.length > 0) { + props.event.trigger('staticAnaysisWarning', [warningCount]) } - - const groupedCategory = groupBy(resultArray, 'warningModuleName') - setWarningState(groupedCategory) - }) - if(categoryIndex.length > 0){ - props.event.trigger('staticAnaysisWarning', [warningCount]) - } - } else { - setRunButtonState(true) - if (categoryIndex.length) { - warningContainer.current.innerText = 'No compiled AST available' + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) } - props.event.trigger('staticAnaysisWarning', [-1]) } } @@ -223,9 +217,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex])) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } - } const handleCheckOrUncheckCategory = (category) => { @@ -261,7 +254,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const categoryItem = (categoryId, item, i) => { return (
- { } - expand={true} + expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} />
{category.map((item, i) => { @@ -314,31 +307,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return ( -
+
-
- { - return (value.map(x => { - return x._index.toString() - })) - }).flat().every(el => categoryIndex.includes(el))} - label="Select all" - onClick={() => handleCheckAllModules(groupedModules)} - /> -
-
- -
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
@@ -368,7 +357,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { <> {element[0]} {element[1].map(x => ( - x.hasWarning ? () : null + x.hasWarning ? ( +
+ +
+ + ) : null ))} ))) diff --git a/nx.json b/nx.json index 802b6fe374..a63c015d64 100644 --- a/nx.json +++ b/nx.json @@ -98,6 +98,9 @@ }, "remix-ui-static-analyser": { "tags": [] + }, + "remix-ui-checkbox": { + "tags": [] } } } diff --git a/package.json b/package.json index 0b7fcd4372..15e2a95e3e 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs", diff --git a/tsconfig.json b/tsconfig.json index c90ed09031..75db5bc6ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,7 +39,8 @@ "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], - "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 9c734f96a7..5d2bf912c0 100644 --- a/workspace.json +++ b/workspace.json @@ -744,6 +744,22 @@ } } } + }, + "remix-ui-checkbox": { + "root": "libs/remix-ui/checkbox", + "sourceRoot": "libs/remix-ui/checkbox/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/checkbox/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/checkbox/**/*"] + } + } + } } }, "cli": { From 8479ad2ab100107504b5a7fdb6b9552d3f79820e Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 16:57:24 +0100 Subject: [PATCH 044/199] refactored warning message --- .../src/lib/remix-ui-static-analyser.tsx | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 21acfe376a..383bfa7643 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -105,6 +105,20 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return () => { } }, [autoRun, categoryIndex]) + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) + } + Pos: ${locationString} + ` + ) + } + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) @@ -150,16 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' - } - Pos: ${locationString} - ` + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, From 691f449c6b2205116af0abebbe1d00c8cabda602 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 24 Apr 2021 06:10:21 +0100 Subject: [PATCH 045/199] fix editor highlighter --- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 8 ++++---- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index b31a62b9de..46dfd16a15 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -25,9 +25,9 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { return result } - const handlePointToErrorOnClick = () => { - const result = opt.locationString.split(':') - editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + const handlePointToErrorOnClick = (location, fileName) => { + editor.call('editor', 'discardHighlight') + editor.call('editor', 'highlight', location, fileName) } if (!message) return @@ -48,7 +48,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => {
- + handlePointToErrorOnClick(opt.location, opt.fileName)}> {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 383bfa7643..7bcdd9d0a3 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -169,12 +169,14 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { type: 'warning', useSpan: true, errFile: fileName, + fileName, errLine: row, errCol: column, item: item, name: result.name, locationString, - more: item.more + more: item.more, + location: location } warningErrors.push(options) setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) @@ -314,7 +316,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sun, 25 Apr 2021 13:41:17 +0100 Subject: [PATCH 046/199] removed old staticAnalysis from remix-project --- .../tabs/staticanalysis/staticAnalysisView.js | 302 ------------------ .../styles/staticAnalysisView-styles.js | 36 --- .../src/lib/remix-ui-static-analyser.tsx | 42 +-- 3 files changed, 24 insertions(+), 356 deletions(-) delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js b/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js deleted file mode 100644 index 668adab89e..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js +++ /dev/null @@ -1,302 +0,0 @@ -'use strict' -var StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -var yo = require('yo-yo') -var $ = require('jquery') -var remixLib = require('@remix-project/remix-lib') -var utils = remixLib.util -var css = require('./styles/staticAnalysisView-styles') -var Renderer = require('../../ui/renderer') -const SourceHighlighter = require('../../editor/sourceHighlighter') - -var EventManager = require('../../../lib/events') - -function staticAnalysisView (localRegistry, analysisModule) { - var self = this - this.event = new EventManager() - this.view = null - this.runner = new StaticAnalysisRunner() - this.modulesView = this.renderModules() - this.lastCompilationResult = null - this.lastCompilationSource = null - this.currentFile = 'No file compiled' - this.sourceHighlighter = new SourceHighlighter() - this.analysisModule = analysisModule - self._components = { - renderer: new Renderer(analysisModule) - } - self._components.registry = localRegistry - // dependencies - self._deps = { - offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api - } - - analysisModule.on('solidity', 'compilationFinished', (file, source, languageVersion, data) => { - self.lastCompilationResult = null - self.lastCompilationSource = null - if (languageVersion.indexOf('soljson') !== 0) return - self.lastCompilationResult = data - self.lastCompilationSource = source - self.currentFile = file - self.correctRunBtnDisabled() - if (self.view && self.view.querySelector('#autorunstaticanalysis').checked) { - self.run() - } - }) -} - -staticAnalysisView.prototype.render = function () { - this.runBtn = yo`` - const view = yo` -
-
-
-
- - -
-
- - -
- ${this.runBtn} -
-
-
- ${this.modulesView} -
-
- last results for: - ${this.currentFile} -
-
-
- ` - - if (!this.view) { - this.view = view - } - this.correctRunBtnDisabled() - return view -} - -staticAnalysisView.prototype.selectedModules = function () { - if (!this.view) { - return [] - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - var toRun = [] - for (var i = 0; i < selected.length; i++) { - toRun.push(selected[i].attributes.index.value) - } - return toRun -} - -staticAnalysisView.prototype.run = function () { - if (!this.view) { - return - } - const highlightLocation = async (location, fileName) => { - await this.analysisModule.call('editor', 'discardHighlight') - await this.analysisModule.call('editor', 'highlight', location, fileName) - } - const selected = this.selectedModules() - const warningContainer = $('#staticanalysisresult') - warningContainer.empty() - this.view.querySelector('#staticAnalysisCurrentFile').innerText = this.currentFile - var self = this - if (this.lastCompilationResult && selected.length) { - this.runBtn.removeAttribute('disabled') - let warningCount = 0 - this.runner.run(this.lastCompilationResult, selected, (results) => { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - results.map((result, j) => { - let moduleName - Object.keys(groupedModules).map((key) => { - groupedModules[key].forEach((el) => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } - }) - }) - const alreadyExistedEl = this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`) - if (!alreadyExistedEl) { - warningContainer.append(` -
- ${moduleName} -
- `) - } - - result.report.map((item, i) => { - let location = '' - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = this.currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) - } - location = self._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - self.lastCompilationSource.sources, - self.lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = (row + 1) + ':' + column + ':' - fileName = Object.keys(self.lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = yo` - - ${result.name} - ${item.warning} - ${item.more ? yo`more` : yo``} - Pos: ${locationString} - ` - self._components.renderer.error( - msg, - this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`), - { - click: () => highlightLocation(location, fileName), - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column - } - ) - }) - }) - // hide empty staticAnalysisModules sections - this.view.querySelectorAll('[name="staticAnalysisModules"]').forEach((section) => { - if (!section.getElementsByClassName('alert-warning').length) section.hidden = true - }) - self.event.trigger('staticAnaysisWarning', [warningCount]) - }) - } else { - this.runBtn.setAttribute('disabled', 'disabled') - if (selected.length) { - warningContainer.html('No compiled AST available') - } - self.event.trigger('staticAnaysisWarning', [-1]) - } -} -staticAnalysisView.prototype.checkModule = function (event) { - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - const checkAll = this.view.querySelector('[id="checkAllEntries"]') - this.correctRunBtnDisabled() - if (event.target.checked) { - checkAll.checked = true - } else if (!selected.length) { - checkAll.checked = false - } -} -staticAnalysisView.prototype.correctRunBtnDisabled = function () { - if (!this.view) { - return - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - if (this.lastCompilationResult && selected.length !== 0) { - this.runBtn.removeAttribute('disabled') - } else { - this.runBtn.setAttribute('disabled', 'disabled') - } -} -staticAnalysisView.prototype.checkAll = function (event) { - if (!this.view) { - return - } - // checks/unchecks all - const checkBoxes = this.view.querySelectorAll('[name="staticanalysismodule"]') - checkBoxes.forEach((checkbox) => { checkbox.checked = event.target.checked }) - this.correctRunBtnDisabled() -} - -staticAnalysisView.prototype.handleCollapse = function (e) { - const downs = e.toElement.parentElement.getElementsByClassName('fas fa-angle-double-right') - const iEls = document.getElementsByTagName('i') - for (var i = 0; i < iEls.length; i++) { iEls[i].hidden = false } - downs[0].hidden = true -} - -staticAnalysisView.prototype.renderModules = function () { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - const moduleEntries = Object.keys(groupedModules).map((categoryId, i) => { - const category = groupedModules[categoryId] - const entriesDom = category.map((item, i) => { - return yo` -
- - -
- ` - }) - return yo` -
- this.handleCollapse(e)}"/> - -
- ${entriesDom} -
-
- ` - }) - // collaps first module - moduleEntries[0].getElementsByTagName('input')[0].checked = true - moduleEntries[0].getElementsByTagName('i')[0].hidden = true - return yo` -
- ${moduleEntries} -
` -} - -module.exports = staticAnalysisView - -/** - * @dev Process & categorize static analysis modules to show them on UI - * @param arr list of static analysis modules received from remix-analyzer module - */ -function preProcessModules (arr) { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js b/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js deleted file mode 100644 index bd277a03aa..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js +++ /dev/null @@ -1,36 +0,0 @@ -var csjs = require('csjs-inject') - -var css = csjs` - .analysis { - display: flex; - flex-direction: column; - } - .result { - margin-top: 1%; - max-height: 300px; - word-break: break-word; - } - .buttons { - margin: 1rem 0; - } - .label { - display: flex; - align-items: center; - } - .label { - display: flex; - align-items: center; - user-select: none; - } - .block input[type='radio']:checked ~ .entries{ - height: auto; - transition: .5s ease-in; - } - .entries{ - height: 0; - overflow: hidden; - transition: .5s ease-out; - } -` - -module.exports = css diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7bcdd9d0a3..8cae6c9e60 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -81,27 +81,30 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [warningState, setWarningState] = useState([]) - useEffect(() => { - if (autoRun) { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } + const executeCompilation = () => { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } + if (props.analysisModule) { + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (categoryIndex.length > 0) { + run(data, source, file) } - ) - } + } + ) } + } + useEffect(() => { + if (autoRun) { + executeCompilation() + } return () => { } }, [autoRun, categoryIndex]) @@ -270,6 +273,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label={item.description} onClick={event => handleCheckSingle(event, item._index)} checked={categoryIndex.includes(item._index.toString())} + onChange={() => {}} />
) @@ -297,7 +301,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -327,6 +331,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} + onChange={() => {}} /> { onClick={handleAutoRun} checked={autoRun} label="Autorun" + onChange={() => {}} />
From 40973df6ca56cf21e9f54f5ad8bfaed217171161 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 03:25:23 +0100 Subject: [PATCH 047/199] created actions and reducer to optimise code --- .../src/lib/actions/staticAnalysisActions.ts | 24 +++ .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++++++++ .../src/lib/remix-ui-static-analyser.tsx | 153 ++++++++++-------- 3 files changed, 172 insertions(+), 70 deletions(-) create mode 100644 libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts new file mode 100644 index 0000000000..ab9b8d3fc9 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -0,0 +1,24 @@ +import React, { useState } from 'react' //eslint-disable-line + +export const compilation = (analysisModule, state, run) => { +// const setCompilationResult = async (data, source, file) => { +// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) +// } + if (analysisModule) { + analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (state.categoryIndex.length > 0) { + run(data, source, file) + } + } + ) + } +} + +export const setCompilationResult = async (data, source, file) => { + return await { data, source, file } +} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts new file mode 100644 index 0000000000..f2f1a8c9d0 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -0,0 +1,65 @@ +import remixLib from '@remix-project/remix-lib' +import * as _ from 'lodash' +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis + +const utils = remixLib.util + +const runner = new StaticAnalysisRunner() + +const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) +} + +const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' +) + +const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) +} +const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory +} + +export const initialState = { categoryIndex: [] } + +export const analysisReducer = (state, action) => { + switch (action.type) { + case 'initialize': + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + case 'uncheck': + return { + ...state, + categoryIndex: state.categoryIndex.filter((el) => { + return !action.payload.includes(el) + }) + } + case 'check': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + case 'uncheckSingle': + return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + case 'checkSingle': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + default: + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + } +} diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8cae6c9e60..c0c89415c9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState, useReducer } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -7,6 +7,9 @@ import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +import { compilation, setCompilationResult } from './actions/staticAnalysisActions' +import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' + const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -62,7 +65,32 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + // const initialState = { categoryIndex: [] } + + // const reducer = (state, action) => { + // console.log({ action }) + // switch (action.type) { + // case 'initialize': + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // case 'uncheck': + // return { + // categoryIndex: state.categoryIndex.filter((el) => { + // return !action.payload.includes(el) + // }) + // } + // case 'check': + // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + // case 'uncheckSingle': + // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + // case 'checkSingle': + // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + // default: + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // } + // } + + const [state, dispatch] = useReducer(analysisReducer, initialState) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) @@ -74,63 +102,51 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [, setModuleNameResult] = useState(null) const [, setWarning] = useState({ - msg: '', options: {}, hasWarning: false, warningErrors: [] }) const [warningState, setWarningState] = useState([]) - const executeCompilation = () => { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } - - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } - } - ) - } - } + // const executeCompilation = (categoryIndex) => { + // const setCompilationResult = async (data, source, file) => { + // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + // } + // if (props.analysisModule) { + // props.analysisModule.on( + // 'solidity', + // 'compilationFinished', + // (file, source, languageVersion, data) => { + // if (languageVersion.indexOf('soljson') !== 0) return + // setCompilationResult(data, source, file) + // console.log(categoryIndex, ' inside execute funtions') + // if (state.categoryIndex.length > 0) { + // run(data, source, file) + // } + // } + // ) + // } + // } useEffect(() => { if (autoRun) { - executeCompilation() + if (props.analysisModule && state.categoryIndex.length > 0) { + compilation(props.analysisModule, state, run) + } } - return () => { } - }, [autoRun, categoryIndex]) - - const message = (name, warning, more, fileName, locationString) : string => { - return (` - - ${name} - ${warning} - ${more - ? (more) - : ( ) + return () => { } - Pos: ${locationString} - ` - ) - } + }, [autoRun, state, props.analysisModule, setWarning]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length > 0) { + if (lastCompilationResult && state.categoryIndex.length > 0) { setRunButtonState(false) let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { + runner.run(lastCompilationResult, state.categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -167,7 +183,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -182,8 +197,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + setWarning({ hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -201,16 +216,21 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } - const groupedCategory = groupBy(resultArray, 'warningModuleName') + console.log({ warningCount }, ' 221') + console.log({ groupedCategory }) setWarningState(groupedCategory) + console.log({ warningState }) + console.log({ warningCount }, ' 223') }) - if (categoryIndex.length > 0) { + console.log({ warningCount }, ' CategoryIndex outside function') + if (state.categoryIndex.length > 0) { + console.log(state.categoryIndex, ' CategoryIndex in execute funtions') props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { setRunButtonState(true) - if (categoryIndex.length) { + if (state.categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -220,27 +240,19 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } @@ -254,10 +266,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (categoryIndex.includes(_index)) { - setCategoryIndex(categoryIndex.filter(val => val !== _index)) + if (state.categoryIndex.includes(_index)) { + dispatch({ type: 'uncheckSingle', payload: _index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, _index])) + dispatch({ type: 'checkSingle', payload: _index }) } } @@ -272,7 +284,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={categoryIndex.includes(item._index.toString())} + checked={state.categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -301,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -328,7 +340,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => categoryIndex.includes(el))} + }).flat().every(el => state.categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -341,7 +353,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -362,10 +374,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { console.log({ warningState }) } + { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- { + {/* { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -379,7 +392,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } + } */}
} From f48693991116ea5ada1f0566531e620a37915299 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 17:30:40 +0100 Subject: [PATCH 048/199] refactored static analysis to improve performance --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 ----- .../static-analyser/src/lib/ErrorRenderer.tsx | 3 +- .../src/lib/actions/staticAnalysisActions.ts | 16 +- .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++----- .../src/lib/remix-ui-static-analyser.tsx | 163 ++++++------------ 5 files changed, 71 insertions(+), 221 deletions(-) delete mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx deleted file mode 100644 index e42caa4851..0000000000 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' //eslint-disable-line - -interface StaticAnalyserCheckBoxProps { - onClick?: (event) => void - onChange?: (event) => void - label?: string - inputType?: string - name?: string - checked?: boolean - id?: string - itemName?: string - categoryId?: string -} - -const StaticAnalyserCheckedBox = ({ - id, - label, - onClick, - inputType, - name, - checked, - onChange, - itemName, - categoryId -}: StaticAnalyserCheckBoxProps) => { - return ( -
- - -
- ) -} - -export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 46dfd16a15..6f1989e3ac 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line interface ErrorRendererProps { message: any; @@ -32,6 +32,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { if (!message) return let position = getPositionDetails(message) + console.log({ position }) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { // Updated error reported includes '-->' before file details const errorDetails = message.split('-->') diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts index ab9b8d3fc9..4f55437cb6 100644 --- a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -1,24 +1,14 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line -export const compilation = (analysisModule, state, run) => { -// const setCompilationResult = async (data, source, file) => { -// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) -// } +export const compilation = (analysisModule, dispatch) => { if (analysisModule) { analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (state.categoryIndex.length > 0) { - run(data, source, file) - } + dispatch({ type: 'compilationFinished', payload: { file, source, languageVersion, data } }) } ) } } - -export const setCompilationResult = async (data, source, file) => { - return await { data, source, file } -} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts index f2f1a8c9d0..833ef55b39 100644 --- a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -1,65 +1,22 @@ -import remixLib from '@remix-project/remix-lib' -import * as _ from 'lodash' -const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -const utils = remixLib.util - -const runner = new StaticAnalysisRunner() - -const preProcessModules = (arr: any) => { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} - -const groupedModules = utils.groupBy( - preProcessModules(runner.modules()), - 'categoryId' -) - -const getIndex = (modules, array) => { - Object.values(modules).map((value: {_index}) => { - if (Array.isArray(value)) { - value.forEach((x) => { - array.push(x._index.toString()) - }) - } else { - array.push(value._index.toString()) - } - }) -} -const groupedModuleIndex = (modules) => { - const indexOfCategory = [] - if (!_.isEmpty(modules)) { - getIndex(modules, indexOfCategory) - } - return indexOfCategory +export const initialState = { + file: null, + source: null, + languageVersion: null, + data: null } -export const initialState = { categoryIndex: [] } - export const analysisReducer = (state, action) => { switch (action.type) { - case 'initialize': - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } - case 'uncheck': + case 'compilationFinished': return { ...state, - categoryIndex: state.categoryIndex.filter((el) => { - return !action.payload.includes(el) - }) + file: action.payload.file, + source: action.payload.source, + languageVersion: action.payload.languageVersion, + data: action.payload.data } - case 'check': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - case 'uncheckSingle': - return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - case 'checkSingle': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } default: - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + return initialState } } diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index c0c89415c9..7725321271 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,30 +1,20 @@ import React, { useEffect, useState, useReducer } from 'react' -import ReactDOM from 'react-dom' //eslint-disable-line -import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line -import { compilation, setCompilationResult } from './actions/staticAnalysisActions' -import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' - +import { compilation } from './actions/staticAnalysisActions' +import { initialState, analysisReducer } from './reducers/staticAnalysisReducer' const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util /* eslint-disable-next-line */ export interface RemixUiStaticAnalyserProps { - renderStaticAnalysis: any - staticanalysis: any - analysisRunner: any, - lastCompilationResult: any, - lastCompilationSource: any, registry: any, event: any, analysisModule: any - _deps: any, - emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -65,88 +55,46 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - - // const initialState = { categoryIndex: [] } - - // const reducer = (state, action) => { - // console.log({ action }) - // switch (action.type) { - // case 'initialize': - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // case 'uncheck': - // return { - // categoryIndex: state.categoryIndex.filter((el) => { - // return !action.payload.includes(el) - // }) - // } - // case 'check': - // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - // case 'uncheckSingle': - // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - // case 'checkSingle': - // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } - // default: - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // } - // } - - const [state, dispatch] = useReducer(analysisReducer, initialState) + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) - const [runButtonState, setRunButtonState] = useState(true) - - const [result, setResult] = useState({ - lastCompilationResult: null, - lastCompilationSource: null, - currentFile: 'No file compiled' - }) - const [, setModuleNameResult] = useState(null) - const [, setWarning] = useState({ - options: {}, - hasWarning: false, - warningErrors: [] - }) const [warningState, setWarningState] = useState([]) + const [state, dispatch] = useReducer(analysisReducer, initialState) - // const executeCompilation = (categoryIndex) => { - // const setCompilationResult = async (data, source, file) => { - // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - // } - // if (props.analysisModule) { - // props.analysisModule.on( - // 'solidity', - // 'compilationFinished', - // (file, source, languageVersion, data) => { - // if (languageVersion.indexOf('soljson') !== 0) return - // setCompilationResult(data, source, file) - // console.log(categoryIndex, ' inside execute funtions') - // if (state.categoryIndex.length > 0) { - // run(data, source, file) - // } - // } - // ) - // } - // } + useEffect(() => { + compilation(props.analysisModule, dispatch) + }, []) useEffect(() => { if (autoRun) { - if (props.analysisModule && state.categoryIndex.length > 0) { - compilation(props.analysisModule, state, run) + if (state.data !== null) { + run(state.data, state.source, state.file) } } - return () => { + return () => { } + }, [autoRun, categoryIndex, state]) + + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) } - }, [autoRun, state, props.analysisModule, setWarning]) + Pos: ${locationString} + ` + ) + } const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && state.categoryIndex.length > 0) { - setRunButtonState(false) + if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, state.categoryIndex, results => { + runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -156,7 +104,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } }) }) - setModuleNameResult(moduleName) const warningErrors = [] result.report.map((item) => { let location: any = {} @@ -183,6 +130,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -197,8 +145,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -216,21 +163,15 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } + const groupedCategory = groupBy(resultArray, 'warningModuleName') - console.log({ warningCount }, ' 221') - console.log({ groupedCategory }) setWarningState(groupedCategory) - console.log({ warningState }) - console.log({ warningCount }, ' 223') }) - console.log({ warningCount }, ' CategoryIndex outside function') - if (state.categoryIndex.length > 0) { - console.log(state.categoryIndex, ' CategoryIndex in execute funtions') + if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { - setRunButtonState(true) - if (state.categoryIndex.length) { + if (categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -240,19 +181,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } @@ -266,10 +215,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (state.categoryIndex.includes(_index)) { - dispatch({ type: 'uncheckSingle', payload: _index }) + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) } else { - dispatch({ type: 'checkSingle', payload: _index }) + setCategoryIndex(_.uniq([...categoryIndex, _index])) } } @@ -284,7 +233,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={state.categoryIndex.includes(item._index.toString())} + checked={categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -313,7 +262,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -340,7 +289,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => state.categoryIndex.includes(el))} + }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -353,7 +302,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -371,14 +320,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { className="text-break break-word word-break font-weight-bold" id="staticAnalysisCurrentFile" > - {result.currentFile && result.currentFile}
- { console.log({ warningState }) } - { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- {/* { + { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -392,7 +339,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } */} + }
} From 6046453fd4cb4d5aa76035cf5ed0d125d90f06ba Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 30 Apr 2021 09:33:50 +0100 Subject: [PATCH 049/199] fix: filename not showing in the result `last result for:` section --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7725321271..a4fc998fad 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -320,6 +320,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { className="text-break break-word word-break font-weight-bold" id="staticAnalysisCurrentFile" > + {state.file}
{ categoryIndex.length > 0 && Object.entries(warningState).length > 0 && From 15a549f9786325cd6c4ab3a129e853994a4042c2 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 10 Apr 2021 02:06:33 +0100 Subject: [PATCH 050/199] refactor: added custom checkbox for static analyser plugin --- apps/remix-ide/src/app/tabs/analysis-tab.js | 49 ++- libs/remix-ui/static-analyser/.babelrc | 4 + libs/remix-ui/static-analyser/.eslintrc | 19 + libs/remix-ui/static-analyser/README.md | 7 + libs/remix-ui/static-analyser/src/index.ts | 1 + .../src/lib/Button/StaticAnalyserButton.tsx | 23 ++ .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 +++ .../static-analyser/src/lib/ErrorRenderer.tsx | 76 ++++ .../src/lib/remix-ui-static-analyser.tsx | 381 ++++++++++++++++++ libs/remix-ui/static-analyser/tsconfig.json | 16 + .../static-analyser/tsconfig.lib.json | 13 + nx.json | 3 + package-lock.json | 6 +- package.json | 1 + tsconfig.json | 5 +- workspace.json | 19 + 16 files changed, 647 insertions(+), 21 deletions(-) create mode 100644 libs/remix-ui/static-analyser/.babelrc create mode 100644 libs/remix-ui/static-analyser/.eslintrc create mode 100644 libs/remix-ui/static-analyser/README.md create mode 100644 libs/remix-ui/static-analyser/src/index.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx create mode 100644 libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx create mode 100644 libs/remix-ui/static-analyser/tsconfig.json create mode 100644 libs/remix-ui/static-analyser/tsconfig.lib.json diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index 4406ba875e..ad3c2fce54 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -1,9 +1,11 @@ +import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' +import ReactDOM from 'react-dom' import { EventEmitter } from 'events' +import {RemixUiStaticAnalyser} from '@remix-ui/static-analyser' // eslint-disable-line import * as packageJson from '../../../../../package.json' +var Renderer = require('../ui/renderer') -var yo = require('yo-yo') -var StaticAnalysis = require('./staticanalysis/staticAnalysisView') var EventManager = require('../../lib/events') const profile = { @@ -25,24 +27,39 @@ class AnalysisTab extends ViewPlugin { this.event = new EventManager() this.events = new EventEmitter() this.registry = registry + this.element = document.createElement('div') + this.element.setAttribute('id', 'staticAnalyserView') + this._components = { + renderer: new Renderer(this) + } + this._components.registry = this.registry + this._deps = { + offsetToLineColumnConverter: this.registry.get( + 'offsettolinecolumnconverter').api + } + } + + onActivation () { + this.renderComponent() } render () { - this.staticanalysis = new StaticAnalysis(this.registry, this) - this.staticanalysis.event.register('staticAnaysisWarning', (count) => { - if (count > 0) { - this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) - } else if (count === 0) { - this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) - } else { - // count ==-1 no compilation result - this.emit('statusChanged', { key: 'none' }) - } - }) - this.registry.put({ api: this.staticanalysis, name: 'staticanalysis' }) - - return yo`
${this.staticanalysis.render()}
` + return this.element } + + renderComponent () { + ReactDOM.render( + , + this.element + ) + } + } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/.babelrc b/libs/remix-ui/static-analyser/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/static-analyser/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/static-analyser/.eslintrc b/libs/remix-ui/static-analyser/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/static-analyser/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/static-analyser/README.md b/libs/remix-ui/static-analyser/README.md new file mode 100644 index 0000000000..7e4b95c0e5 --- /dev/null +++ b/libs/remix-ui/static-analyser/README.md @@ -0,0 +1,7 @@ +# remix-ui-static-analyser + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-static-analyser` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/static-analyser/src/index.ts b/libs/remix-ui/static-analyser/src/index.ts new file mode 100644 index 0000000000..86a00ccd14 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-static-analyser' diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx new file mode 100644 index 0000000000..5cd7e9392b --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -0,0 +1,23 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserButtonProps { + onClick: (event) => void + buttonText: string, + disabled?: boolean +} + +const StaticAnalyserButton = ({ + onClick, + buttonText, + disabled +}: StaticAnalyserButtonProps) => { + return ( +
+ +
+ ) +} + +export default StaticAnalyserButton diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx new file mode 100644 index 0000000000..2326a39122 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -0,0 +1,45 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserCheckBoxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +const StaticAnalyserCheckedBox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: StaticAnalyserCheckBoxProps) => { + return ( +
+ + +
+ ) +} + +export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx new file mode 100644 index 0000000000..7b7a01f37d --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -0,0 +1,76 @@ +import React, { useState } from 'react' //eslint-disable-line + +interface ErrorRendererProps { + message: any; + opt: any, + warningErrors: any +} + +const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { + const [, setError] = useState( + { + row: null, + column: null, + text: null, + type: null, + errFile: null + } + ) + const getPositionDetails = (msg: any) => { + const result = { } as any + + // To handle some compiler warning without location like SPDX license warning etc + if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } + + // extract line / column + let position = msg.match(/^(.*?):([0-9]*?):([0-9]*?)?/) + result.errLine = position ? parseInt(position[2]) - 1 : -1 + result.errCol = position ? parseInt(position[3]) : -1 + + // extract file + position = msg.match(/^(https:.*?|http:.*?|.*?):/) + result.errFile = position ? position[1] : '' + return result + } + if (!message) return + let position = getPositionDetails(message) + if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { + // Updated error reported includes '-->' before file details + const errorDetails = message.split('-->') + // errorDetails[1] will have file details + if (errorDetails.length > 1) position = getPositionDetails(errorDetails[1]) + } + opt.errLine = position.errLine + opt.errCol = position.errCol + opt.errFile = position.errFile.trim() + if (!opt.noAnnotations && opt.errFile) { + setError({ + errFile: opt.errFile, + row: opt.errLine, + column: opt.errCol, + text: message, + type: opt.type + }) + } + const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' + return ( +
+
+
+ +
+ + {opt.item.name} + { opt.item.warning } + {opt.item.more + ? more + : + } + Pos: {opt.locationString} + +
+
+ ) +} + +export default ErrorRenderer diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx new file mode 100644 index 0000000000..1674d66d84 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -0,0 +1,381 @@ +import React, { useEffect, useState } from 'react' +import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line +import Button from './Button/StaticAnalyserButton' // eslint-disable-line +import remixLib from '@remix-project/remix-lib' +import _ from 'lodash' +import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis +const utils = remixLib.util + +/* eslint-disable-next-line */ +export interface RemixUiStaticAnalyserProps { + renderStaticAnalysis: any + staticanalysis: any + analysisRunner: any, + lastCompilationResult: any, + lastCompilationSource: any, + registry: any, + event: any, + analysisModule: any + _deps: any +} + +export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { + const [runner] = useState(new StaticAnalysisRunner()) + + const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) + } + + const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' + ) + + const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) + } + + const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory + } + + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + const warningContainer = React.useRef(null) + const [runButtonState, setRunButtonState] = useState(true) + const [autoRun, setAutoRun] = useState(true) + const [result, setResult] = useState({ + lastCompilationResult: null, + lastCompilationSource: null, + currentFile: 'No file compiled' + }) + const [, setModuleNameResult] = useState(null) + const [, setWarning] = useState({ + msg: '', + options: {}, + hasWarning: false, + warningErrors: [] + }) + const [warningState, setWarningState] = useState([]) + + useEffect(() => { + if (autoRun) { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } + + if (props.analysisModule) { + console.log({ autoRun }) + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + run(data, source, file) + } + ) + } + } + return () => { } + }, [autoRun]) + + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { + // const highlightLocation = async (location, fileName) => { + // await props.analysisModule.call('editor', 'discardHighlight') + // await props.analysisModule.call('editor', 'highlight', location, fileName) + // } + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] + + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) + }) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + var split = item.location.split(':') + var file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] + } + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more + } + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) + }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) + }) + props.event.trigger('staticAnaysisWarning', [warningCount]) + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) + } + } + + // const correctRunBtnDisabled = () => { + // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { + // setRunButtonState(false) + // } else { + // setRunButtonState(true) + // } + // } + + const handleCheckAllModules = (groupedModules) => { + const index = groupedModuleIndex(groupedModules) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleCheckOrUncheckCategory = (category) => { + const index = groupedModuleIndex(category) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) + } else { + setCategoryIndex(_.uniq([...categoryIndex, ...index])) + } + } + + const handleAutoRun = () => { + if (autoRun) { + setAutoRun(false) + } else { + setAutoRun(true) + } + console.log(' auton run function') + } + + const handleCheckSingle = (event, _index) => { + _index = _index.toString() + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) + } else { + setCategoryIndex(_.uniq([...categoryIndex, _index])) + } + } + + const categoryItem = (categoryId, item, i) => { + return ( +
+ handleCheckSingle(event, item._index)} + checked={categoryIndex.includes(item._index.toString())} + /> +
+ ) + } + + const categorySection = (category, categoryId, i) => { + return ( +
+
+ + + {category[0].categoryDisplayName} +
+ +
+ + } + expand={true} + > +
+ handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> +
+
+ {category.map((item, i) => { + return ( + categoryItem(categoryId, item, i) + ) + })} +
+
+
+
+
+ ) + } + + return ( +
+
+
+
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
+
+ +
+
+
+
+ {Object.keys(groupedModules).map((categoryId, i) => { + const category = groupedModules[categoryId] + return ( + categorySection(category, categoryId, i) + ) + }) + } +
+
+ last results for: + + {result.currentFile && result.currentFile} + +
+
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
+
+
+ ) +} + +export default RemixUiStaticAnalyser diff --git a/libs/remix-ui/static-analyser/tsconfig.json b/libs/remix-ui/static-analyser/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/static-analyser/tsconfig.lib.json b/libs/remix-ui/static-analyser/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/static-analyser/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/nx.json b/nx.json index 5cf047d9cc..802b6fe374 100644 --- a/nx.json +++ b/nx.json @@ -95,6 +95,9 @@ }, "remix-ui-workspace": { "tags": [] + }, + "remix-ui-static-analyser": { + "tags": [] } } } diff --git a/package-lock.json b/package-lock.json index b2c38f3b0f..b5ab19b3ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25142,9 +25142,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { "version": "4.17.15", diff --git a/package.json b/package.json index bd2a0e8aa6..03cd967635 100644 --- a/package.json +++ b/package.json @@ -159,6 +159,7 @@ "isbinaryfile": "^3.0.2", "jquery": "^3.3.1", "jszip": "^3.6.0", + "lodash": "^4.17.21", "merge": "^1.2.0", "npm-install-version": "^6.0.2", "react": "16.13.1", diff --git a/tsconfig.json b/tsconfig.json index c2a383e9de..c90ed09031 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "target": "es2015", "module": "commonjs", "typeRoots": ["node_modules/@types"], - "lib": ["es2017", "dom"], + "lib": ["es2017", "es2019", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", @@ -38,7 +38,8 @@ "@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"], "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], - "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"] + "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 10793e13b3..9c734f96a7 100644 --- a/workspace.json +++ b/workspace.json @@ -725,6 +725,25 @@ } } } + }, + "remix-ui-static-analyser": { + "root": "libs/remix-ui/static-analyser", + "sourceRoot": "libs/remix-ui/static-analyser/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/static-analyser/tsconfig.lib.json"], + "exclude": [ + "**/node_modules/**", + "!libs/remix-ui/static-analyser/**/*" + ] + } + } + } } }, "cli": { From 4c0312144875a674ae8539010a484ebe31d7f8ee Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 12:51:49 +0100 Subject: [PATCH 051/199] added warning sign when analysis has runned --- apps/remix-ide/src/app/tabs/analysis-tab.js | 15 +++++++++++++-- .../src/lib/remix-ui-static-analyser.tsx | 19 +++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/analysis-tab.js b/apps/remix-ide/src/app/tabs/analysis-tab.js index ad3c2fce54..b3bba2705c 100644 --- a/apps/remix-ide/src/app/tabs/analysis-tab.js +++ b/apps/remix-ide/src/app/tabs/analysis-tab.js @@ -56,10 +56,21 @@ class AnalysisTab extends ViewPlugin { analysisModule={this} event={this.event} />, - this.element + this.element, + () => { + this.event.register('staticAnaysisWarning', (count) => { + if (count > 0) { + this.emit('statusChanged', { key: count, title: `${count} warning${count === 1 ? '' : 's'}`, type: 'warning' }) + } else if (count === 0) { + this.emit('statusChanged', { key: 'succeed', title: 'no warning', type: 'success' }) + } else { + // count ==-1 no compilation result + this.emit('statusChanged', { key: 'none' }) + } + }) + } ) } - } module.exports = AnalysisTab diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 1674d66d84..81d4e29e15 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' +import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' @@ -18,7 +19,8 @@ export interface RemixUiStaticAnalyserProps { registry: any, event: any, analysisModule: any - _deps: any + _deps: any, + emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -63,7 +65,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(true) + const [autoRun, setAutoRun] = useState(false) const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -96,7 +98,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } ) } + } else { + setAutoRun(true) } + return () => { } }, [autoRun]) @@ -105,6 +110,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } + console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -193,6 +199,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) + props.event.trigger('staticAnaysisWarning', [warningCount]) } else { setRunButtonState(true) @@ -203,14 +210,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } } - // const correctRunBtnDisabled = () => { - // if (props.lastCompilationResult && selectedCategoryIndex.length !== 0) { - // setRunButtonState(false) - // } else { - // setRunButtonState(true) - // } - // } - const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) if (index.every(el => categoryIndex.includes(el))) { From fcbf5412899bd7108bc16e6a332ccfb457d9c90a Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 13:05:48 +0100 Subject: [PATCH 052/199] removed icon: fas fa-angle-double-right from each category display name --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 81d4e29e15..b1810c3143 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -288,9 +288,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { data-bs-target={`#heading${categoryId}`} > {category[0].categoryDisplayName} -
- -
} expand={true} From 59714716791021ea154a49b9c624793fa91d34cc Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 13 Apr 2021 18:37:37 +0100 Subject: [PATCH 053/199] adding a condition to fix ci build --- .../src/lib/remix-ui-static-analyser.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index b1810c3143..5000a94c01 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -356,20 +356,22 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
-
-
- { - (Object.entries(warningState).map((element) => ( - <> - {element[0]} - {element[1].map(x => ( - x.hasWarning ? () : null - ))} - - ))) - } + { Object.entries(warningState).length > 0 && +
+
+ { + (Object.entries(warningState).map((element) => ( + <> + {element[0]} + {element[1].map(x => ( + x.hasWarning ? () : null + ))} + + ))) + } +
-
+ }
) } From dcf510f2c47c1eb07532a4cb0d8ba73a21618588 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 06:49:06 +0100 Subject: [PATCH 054/199] fix: testing to see if test passes --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..b2c3f41cb6 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 7b7a01f37d..878cccb7da 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -60,7 +60,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
- {opt.item.name} + {opt.name} { opt.item.warning } {opt.item.more ? more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5000a94c01..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -164,6 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` + console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, From 8d2c9124fa4dcd30d19a0a1c3005f1547486b64a Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 16 Apr 2021 09:19:39 +0100 Subject: [PATCH 055/199] added className staticAnalysisView to staticAnalyser component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index b2c3f41cb6..a68a4a24ce 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -41,7 +41,7 @@ function runTests (browser: NightwatchBrowser) { .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') .click('#staticanalysisView button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, false, function () { + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', 'TooMuchGas.() : Variables have very similar names "test" and "test1".', diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..93b1b6b3a4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Fri, 16 Apr 2021 09:54:37 +0100 Subject: [PATCH 056/199] remove className staticAnalysisView and added id = staticanalysisView --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 93b1b6b3a4..8e42d97ce4 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:07:13 +0100 Subject: [PATCH 057/199] fix: moved staticanalysisButton id to the Button component --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 2 +- .../static-analyser/src/lib/Button/StaticAnalyserButton.tsx | 2 +- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a68a4a24ce..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,7 +40,7 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisView button') + .click('#staticanalysisButton button') .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { listSelectorContains(['Use of tx.origin', 'Fallback function of contract TooMuchGas requires too much gas', diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 5cd7e9392b..336a0fe56a 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,7 +12,7 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
+
diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8e42d97ce4..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -313,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sat, 17 Apr 2021 06:27:48 +0100 Subject: [PATCH 058/199] fix: removed disabled props on button --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..38e4988a0f 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From 74817561ca442ccef23977cb1841daa6ff7d78b1 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 06:52:33 +0100 Subject: [PATCH 059/199] reversed changes --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 38e4988a0f..6a6edde1a7 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -336,7 +336,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" />
-
From 5fb870d49db9428683c07e866472e82204328c6f Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 17:49:24 +0100 Subject: [PATCH 060/199] commiting code to detect failing test --- .../src/tests/staticAnalysis.spec.ts | 24 +++++++++---------- .../src/lib/remix-ui-static-analyser.tsx | 4 ---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..480fab63fb 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,18 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) + //.click('#staticanalysisButton button') + // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + // listSelectorContains(['Use of tx.origin', + // 'Fallback function of contract TooMuchGas requires too much gas', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + // '#staticanalysisresult .warning', + // browser, function () { + // browser.end() + // } + // ) + // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 6a6edde1a7..5a24785838 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -87,7 +87,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } if (props.analysisModule) { - console.log({ autoRun }) props.analysisModule.on( 'solidity', 'compilationFinished', @@ -110,7 +109,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { // await props.analysisModule.call('editor', 'discardHighlight') // await props.analysisModule.call('editor', 'highlight', location, fileName) // } - console.log({ autoRun }, ' auto run in run function') setResult({ lastCompilationResult, lastCompilationSource, currentFile }) if (lastCompilationResult && categoryIndex.length) { setRunButtonState(false) @@ -164,7 +162,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } Pos: ${locationString} ` - console.log(result.name, ' result name now') const options = { type: 'warning', useSpan: true, @@ -243,7 +240,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } else { setAutoRun(true) } - console.log(' auton run function') } const handleCheckSingle = (event, _index) => { From 17c1257d35dcd6f212e542fdbf6f815c69bfcb95 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:00:14 +0100 Subject: [PATCH 061/199] removed comments --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 480fab63fb..e9777e2970 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,6 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - //.click('#staticanalysisButton button') - // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - // listSelectorContains(['Use of tx.origin', - // 'Fallback function of contract TooMuchGas requires too much gas', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - // '#staticanalysisresult .warning', - // browser, function () { - // browser.end() - // } - // ) - // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { From cbb2c03246a9f5d0bac58b1ec0f39523dad88569 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:09:41 +0100 Subject: [PATCH 062/199] removing comments and unused functions --- .../src/tests/staticAnalysis.spec.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index e9777e2970..a10a2a8348 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -42,20 +42,4 @@ function runTests (browser: NightwatchBrowser) { .clickLaunchIcon('solidityStaticAnalysis') } -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) -} + From 9ab0288b2d80b657d565aa40c177c5b20820eb5e Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:20:19 +0100 Subject: [PATCH 063/199] removed extra space at end of file --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a10a2a8348..8fa094273e 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,6 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} - - +} \ No newline at end of file From ef34146c1cd08c9225f9c3d27c81bfee157971b3 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:27:17 +0100 Subject: [PATCH 064/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 8fa094273e..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} \ No newline at end of file + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) +} From 197eda914fe4f3905bfc370ba88df2a5170f69eb Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:35:52 +0100 Subject: [PATCH 065/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..55f7329f65 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,34 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) -} - -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) } From e6ae1d35a904690fe93a4df7d6aec3039e442e51 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:37:33 +0100 Subject: [PATCH 066/199] restored staticAnalysis.spec.ts to it previous code structure --- .../src/tests/staticAnalysis.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 55f7329f65..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) } From 493511fe4038bbdc678997d60e92b17dfb8f647b Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 19 Apr 2021 14:25:28 +0100 Subject: [PATCH 067/199] fix failing test --- .../src/lib/remix-ui-static-analyser.tsx | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5a24785838..2fb460eec9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -81,19 +81,24 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { + if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { + props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - run(data, source, file) + if(categoryIndex.length > 0){ + run(data, source, file) + } + } ) } @@ -102,7 +107,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return () => { } - }, [autoRun]) + }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { // const highlightLocation = async (location, fileName) => { @@ -197,8 +202,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const groupedCategory = groupBy(resultArray, 'warningModuleName') setWarningState(groupedCategory) }) - - props.event.trigger('staticAnaysisWarning', [warningCount]) + if(categoryIndex.length > 0){ + props.event.trigger('staticAnaysisWarning', [warningCount]) + } } else { setRunButtonState(true) if (categoryIndex.length) { @@ -217,8 +223,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + setCategoryIndex(_.uniq([...categoryIndex])) } + } const handleCheckOrUncheckCategory = (category) => { @@ -353,9 +360,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
-
+
{ (Object.entries(warningState).map((element) => ( <> From 6dfe730e0b91952c9baece597394faa4889b2ae2 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 11:23:00 +0100 Subject: [PATCH 068/199] feat_fix_n_refactor: exptracted checkbox as a reusable component and fix selec all and auto run, --- libs/remix-ui/checkbox/.babelrc | 4 + libs/remix-ui/checkbox/.eslintrc | 19 ++ libs/remix-ui/checkbox/README.md | 7 + libs/remix-ui/checkbox/src/index.ts | 1 + .../checkbox/src/lib/remix-ui-checkbox.css | 0 .../checkbox/src/lib/remix-ui-checkbox.tsx | 47 ++++ libs/remix-ui/checkbox/tsconfig.json | 16 ++ libs/remix-ui/checkbox/tsconfig.lib.json | 13 + .../src/lib/Button/StaticAnalyserButton.tsx | 8 +- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 8 +- .../static-analyser/src/lib/ErrorRenderer.tsx | 31 +-- .../src/lib/remix-ui-static-analyser.tsx | 260 +++++++++--------- nx.json | 3 + package.json | 2 +- tsconfig.json | 3 +- workspace.json | 16 ++ 16 files changed, 273 insertions(+), 165 deletions(-) create mode 100644 libs/remix-ui/checkbox/.babelrc create mode 100644 libs/remix-ui/checkbox/.eslintrc create mode 100644 libs/remix-ui/checkbox/README.md create mode 100644 libs/remix-ui/checkbox/src/index.ts create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css create mode 100644 libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx create mode 100644 libs/remix-ui/checkbox/tsconfig.json create mode 100644 libs/remix-ui/checkbox/tsconfig.lib.json diff --git a/libs/remix-ui/checkbox/.babelrc b/libs/remix-ui/checkbox/.babelrc new file mode 100644 index 0000000000..09d67939cc --- /dev/null +++ b/libs/remix-ui/checkbox/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["@nrwl/react/babel"], + "plugins": [] +} diff --git a/libs/remix-ui/checkbox/.eslintrc b/libs/remix-ui/checkbox/.eslintrc new file mode 100644 index 0000000000..dae5c6feeb --- /dev/null +++ b/libs/remix-ui/checkbox/.eslintrc @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": "../../../.eslintrc", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 11, + "sourceType": "module" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error" + } +} diff --git a/libs/remix-ui/checkbox/README.md b/libs/remix-ui/checkbox/README.md new file mode 100644 index 0000000000..56f9b617b0 --- /dev/null +++ b/libs/remix-ui/checkbox/README.md @@ -0,0 +1,7 @@ +# remix-ui-checkbox + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test remix-ui-checkbox` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/remix-ui/checkbox/src/index.ts b/libs/remix-ui/checkbox/src/index.ts new file mode 100644 index 0000000000..27b694c6bd --- /dev/null +++ b/libs/remix-ui/checkbox/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-ui-checkbox' diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx new file mode 100644 index 0000000000..5535a05971 --- /dev/null +++ b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx @@ -0,0 +1,47 @@ +import React from 'react' //eslint-disable-line +import './remix-ui-checkbox.css' + +/* eslint-disable-next-line */ +export interface RemixUiCheckboxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +export const RemixUiCheckbox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: RemixUiCheckboxProps) => { + return ( +
+ + +
+ ) +} + +export default RemixUiCheckbox diff --git a/libs/remix-ui/checkbox/tsconfig.json b/libs/remix-ui/checkbox/tsconfig.json new file mode 100644 index 0000000000..6b65264565 --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "jsx": "react", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/libs/remix-ui/checkbox/tsconfig.lib.json b/libs/remix-ui/checkbox/tsconfig.lib.json new file mode 100644 index 0000000000..b560bc4dec --- /dev/null +++ b/libs/remix-ui/checkbox/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx index 336a0fe56a..2a67c82cf8 100644 --- a/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Button/StaticAnalyserButton.tsx @@ -12,11 +12,9 @@ const StaticAnalyserButton = ({ disabled }: StaticAnalyserButtonProps) => { return ( -
- -
+ ) } diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx index 2326a39122..e42caa4851 100644 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -24,7 +24,7 @@ const StaticAnalyserCheckedBox = ({ categoryId }: StaticAnalyserCheckBoxProps) => { return ( -
+
-
) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 878cccb7da..b31a62b9de 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -4,20 +4,12 @@ interface ErrorRendererProps { message: any; opt: any, warningErrors: any + editor: any } -const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { - const [, setError] = useState( - { - row: null, - column: null, - text: null, - type: null, - errFile: null - } - ) +const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { const getPositionDetails = (msg: any) => { - const result = { } as any + const result = { } as Record // To handle some compiler warning without location like SPDX license warning etc if (!msg.includes(':')) return { errLine: -1, errCol: -1, errFile: msg } @@ -32,6 +24,12 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { result.errFile = position ? position[1] : '' return result } + + const handlePointToErrorOnClick = () => { + const result = opt.locationString.split(':') + editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + } + if (!message) return let position = getPositionDetails(message) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { @@ -43,15 +41,6 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => { opt.errLine = position.errLine opt.errCol = position.errCol opt.errFile = position.errFile.trim() - if (!opt.noAnnotations && opt.errFile) { - setError({ - errFile: opt.errFile, - row: opt.errLine, - column: opt.errCol, - text: message, - type: opt.type - }) - } const classList = opt.type === 'error' ? 'alert alert-danger' : 'alert alert-warning' return (
@@ -59,7 +48,7 @@ const ErrorRenderer = ({ message, opt }: ErrorRendererProps) => {
- + {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 2fb460eec9..21acfe376a 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,10 +1,11 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line +import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -60,12 +61,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return indexOfCategory } - + const [autoRun, setAutoRun] = useState(true) const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) - const [autoRun, setAutoRun] = useState(false) + const [result, setResult] = useState({ lastCompilationResult: null, lastCompilationSource: null, @@ -81,136 +82,129 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [warningState, setWarningState] = useState([]) useEffect(() => { - if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - + if (props.analysisModule) { - props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - if(categoryIndex.length > 0){ + if (categoryIndex.length > 0) { run(data, source, file) } - } ) } - } else { - setAutoRun(true) } return () => { } }, [autoRun, categoryIndex]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { - // const highlightLocation = async (location, fileName) => { - // await props.analysisModule.call('editor', 'discardHighlight') - // await props.analysisModule.call('editor', 'highlight', location, fileName) - // } - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length) { - setRunButtonState(false) - let warningCount = 0 - const warningMessage = [] + if (autoRun) { + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length > 0) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { - results.map((result) => { - let moduleName - Object.keys(groupedModules).map(key => { - groupedModules[key].forEach(el => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } + runner.run(lastCompilationResult, categoryIndex, results => { + results.map((result) => { + let moduleName + Object.keys(groupedModules).map(key => { + groupedModules[key].forEach(el => { + if (el.name === result.name) { + moduleName = groupedModules[key][0].categoryDisplayName + } + }) }) - }) - setModuleNameResult(moduleName) - const warningErrors = [] - result.report.map((item) => { - let location: any = {} - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) + setModuleNameResult(moduleName) + const warningErrors = [] + result.report.map((item) => { + let location: any = {} + let locationString = 'not available' + let column = 0 + let row = 0 + let fileName = currentFile + if (item.location) { + const split = item.location.split(':') + const file = split[2] + location = { + start: parseInt(split[0]), + length: parseInt(split[1]) + } + location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( + location, + parseInt(file), + lastCompilationSource.sources, + lastCompilationResult.sources + ) + row = location.start.line + column = location.start.column + locationString = row + 1 + ':' + column + ':' + fileName = Object.keys(lastCompilationResult.contracts)[file] } - location = props.analysisModule._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - lastCompilationSource.sources, - lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = row + 1 + ':' + column + ':' - fileName = Object.keys(lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' + warningCount++ + const msg = ` + + ${result.name} + ${item.warning} + ${item.more + ? `more` + : ' ' + } + Pos: ${locationString} + ` + const options = { + type: 'warning', + useSpan: true, + errFile: fileName, + errLine: row, + errCol: column, + item: item, + name: result.name, + locationString, + more: item.more } - Pos: ${locationString} - ` - const options = { - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column, - item: item, - name: result.name, - locationString, - more: item.more - } - warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + warningErrors.push(options) + setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + }) }) + const resultArray = [] + warningMessage.map(x => { + resultArray.push(x) + }) + function groupBy (objectArray, property) { + return objectArray.reduce((acc, obj) => { + const key = obj[property] + if (!acc[key]) { + acc[key] = [] + } + // Add object to list for given key's value + acc[key].push(obj) + return acc + }, {}) + } + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) }) - const resultArray = [] - warningMessage.map(x => { - resultArray.push(x) - }) - function groupBy (objectArray, property) { - return objectArray.reduce((acc, obj) => { - const key = obj[property] - if (!acc[key]) { - acc[key] = [] - } - // Add object to list for given key's value - acc[key].push(obj) - return acc - }, {}) + if (categoryIndex.length > 0) { + props.event.trigger('staticAnaysisWarning', [warningCount]) } - - const groupedCategory = groupBy(resultArray, 'warningModuleName') - setWarningState(groupedCategory) - }) - if(categoryIndex.length > 0){ - props.event.trigger('staticAnaysisWarning', [warningCount]) - } - } else { - setRunButtonState(true) - if (categoryIndex.length) { - warningContainer.current.innerText = 'No compiled AST available' + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' + } + props.event.trigger('staticAnaysisWarning', [-1]) } - props.event.trigger('staticAnaysisWarning', [-1]) } } @@ -223,9 +217,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex])) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } - } const handleCheckOrUncheckCategory = (category) => { @@ -261,7 +254,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const categoryItem = (categoryId, item, i) => { return (
- { } - expand={true} + expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} />
{category.map((item, i) => { @@ -314,31 +307,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return ( -
+
-
- { - return (value.map(x => { - return x._index.toString() - })) - }).flat().every(el => categoryIndex.includes(el))} - label="Select all" - onClick={() => handleCheckAllModules(groupedModules)} - /> -
-
- -
+ { + return (value.map(x => { + return x._index.toString() + })) + }).flat().every(el => categoryIndex.includes(el))} + label="Select all" + onClick={() => handleCheckAllModules(groupedModules)} + /> +
@@ -368,7 +357,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { <> {element[0]} {element[1].map(x => ( - x.hasWarning ? () : null + x.hasWarning ? ( +
+ +
+ + ) : null ))} ))) diff --git a/nx.json b/nx.json index 802b6fe374..a63c015d64 100644 --- a/nx.json +++ b/nx.json @@ -98,6 +98,9 @@ }, "remix-ui-static-analyser": { "tags": [] + }, + "remix-ui-checkbox": { + "tags": [] } } } diff --git a/package.json b/package.json index 03cd967635..5de719a8cd 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs", diff --git a/tsconfig.json b/tsconfig.json index c90ed09031..75db5bc6ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -39,7 +39,8 @@ "@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"], "@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"], "@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"], - "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"] + "@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"], + "@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] diff --git a/workspace.json b/workspace.json index 9c734f96a7..5d2bf912c0 100644 --- a/workspace.json +++ b/workspace.json @@ -744,6 +744,22 @@ } } } + }, + "remix-ui-checkbox": { + "root": "libs/remix-ui/checkbox", + "sourceRoot": "libs/remix-ui/checkbox/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "tsConfig": ["libs/remix-ui/checkbox/tsconfig.lib.json"], + "exclude": ["**/node_modules/**", "!libs/remix-ui/checkbox/**/*"] + } + } + } } }, "cli": { From 6924eb457d99b306d893da09a105bc462210d01e Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 16:57:24 +0100 Subject: [PATCH 069/199] refactored warning message --- .../src/lib/remix-ui-static-analyser.tsx | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 21acfe376a..383bfa7643 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -105,6 +105,20 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return () => { } }, [autoRun, categoryIndex]) + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) + } + Pos: ${locationString} + ` + ) + } + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) @@ -150,16 +164,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = ` - - ${result.name} - ${item.warning} - ${item.more - ? `more` - : ' ' - } - Pos: ${locationString} - ` + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, From d3cdaaf15354b518d01514403b723714f2a638a3 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 24 Apr 2021 06:10:21 +0100 Subject: [PATCH 070/199] fix editor highlighter --- libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx | 8 ++++---- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index b31a62b9de..46dfd16a15 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -25,9 +25,9 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { return result } - const handlePointToErrorOnClick = () => { - const result = opt.locationString.split(':') - editor._components.registry.get('editor').api.gotoLine(parseInt(result[0]) - 1, parseInt(result[1])) + const handlePointToErrorOnClick = (location, fileName) => { + editor.call('editor', 'discardHighlight') + editor.call('editor', 'highlight', location, fileName) } if (!message) return @@ -48,7 +48,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => {
- + handlePointToErrorOnClick(opt.location, opt.fileName)}> {opt.name} { opt.item.warning } {opt.item.more diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 383bfa7643..7bcdd9d0a3 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -169,12 +169,14 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { type: 'warning', useSpan: true, errFile: fileName, + fileName, errLine: row, errCol: column, item: item, name: result.name, locationString, - more: item.more + more: item.more, + location: location } warningErrors.push(options) setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) @@ -314,7 +316,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (
-
+
Date: Sun, 25 Apr 2021 13:41:17 +0100 Subject: [PATCH 071/199] removed old staticAnalysis from remix-project --- .../tabs/staticanalysis/staticAnalysisView.js | 302 ------------------ .../styles/staticAnalysisView-styles.js | 36 --- .../src/lib/remix-ui-static-analyser.tsx | 42 +-- 3 files changed, 24 insertions(+), 356 deletions(-) delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js delete mode 100644 apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js b/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js deleted file mode 100644 index 668adab89e..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/staticAnalysisView.js +++ /dev/null @@ -1,302 +0,0 @@ -'use strict' -var StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -var yo = require('yo-yo') -var $ = require('jquery') -var remixLib = require('@remix-project/remix-lib') -var utils = remixLib.util -var css = require('./styles/staticAnalysisView-styles') -var Renderer = require('../../ui/renderer') -const SourceHighlighter = require('../../editor/sourceHighlighter') - -var EventManager = require('../../../lib/events') - -function staticAnalysisView (localRegistry, analysisModule) { - var self = this - this.event = new EventManager() - this.view = null - this.runner = new StaticAnalysisRunner() - this.modulesView = this.renderModules() - this.lastCompilationResult = null - this.lastCompilationSource = null - this.currentFile = 'No file compiled' - this.sourceHighlighter = new SourceHighlighter() - this.analysisModule = analysisModule - self._components = { - renderer: new Renderer(analysisModule) - } - self._components.registry = localRegistry - // dependencies - self._deps = { - offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api - } - - analysisModule.on('solidity', 'compilationFinished', (file, source, languageVersion, data) => { - self.lastCompilationResult = null - self.lastCompilationSource = null - if (languageVersion.indexOf('soljson') !== 0) return - self.lastCompilationResult = data - self.lastCompilationSource = source - self.currentFile = file - self.correctRunBtnDisabled() - if (self.view && self.view.querySelector('#autorunstaticanalysis').checked) { - self.run() - } - }) -} - -staticAnalysisView.prototype.render = function () { - this.runBtn = yo`` - const view = yo` -
-
-
-
- - -
-
- - -
- ${this.runBtn} -
-
-
- ${this.modulesView} -
-
- last results for: - ${this.currentFile} -
-
-
- ` - - if (!this.view) { - this.view = view - } - this.correctRunBtnDisabled() - return view -} - -staticAnalysisView.prototype.selectedModules = function () { - if (!this.view) { - return [] - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - var toRun = [] - for (var i = 0; i < selected.length; i++) { - toRun.push(selected[i].attributes.index.value) - } - return toRun -} - -staticAnalysisView.prototype.run = function () { - if (!this.view) { - return - } - const highlightLocation = async (location, fileName) => { - await this.analysisModule.call('editor', 'discardHighlight') - await this.analysisModule.call('editor', 'highlight', location, fileName) - } - const selected = this.selectedModules() - const warningContainer = $('#staticanalysisresult') - warningContainer.empty() - this.view.querySelector('#staticAnalysisCurrentFile').innerText = this.currentFile - var self = this - if (this.lastCompilationResult && selected.length) { - this.runBtn.removeAttribute('disabled') - let warningCount = 0 - this.runner.run(this.lastCompilationResult, selected, (results) => { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - results.map((result, j) => { - let moduleName - Object.keys(groupedModules).map((key) => { - groupedModules[key].forEach((el) => { - if (el.name === result.name) { - moduleName = groupedModules[key][0].categoryDisplayName - } - }) - }) - const alreadyExistedEl = this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`) - if (!alreadyExistedEl) { - warningContainer.append(` -
- ${moduleName} -
- `) - } - - result.report.map((item, i) => { - let location = '' - let locationString = 'not available' - let column = 0 - let row = 0 - let fileName = this.currentFile - if (item.location) { - var split = item.location.split(':') - var file = split[2] - location = { - start: parseInt(split[0]), - length: parseInt(split[1]) - } - location = self._deps.offsetToLineColumnConverter.offsetToLineColumn( - location, - parseInt(file), - self.lastCompilationSource.sources, - self.lastCompilationResult.sources - ) - row = location.start.line - column = location.start.column - locationString = (row + 1) + ':' + column + ':' - fileName = Object.keys(self.lastCompilationResult.contracts)[file] - } - warningCount++ - const msg = yo` - - ${result.name} - ${item.warning} - ${item.more ? yo`more` : yo``} - Pos: ${locationString} - ` - self._components.renderer.error( - msg, - this.view.querySelector(`[id="staticAnalysisModule${moduleName}"]`), - { - click: () => highlightLocation(location, fileName), - type: 'warning', - useSpan: true, - errFile: fileName, - errLine: row, - errCol: column - } - ) - }) - }) - // hide empty staticAnalysisModules sections - this.view.querySelectorAll('[name="staticAnalysisModules"]').forEach((section) => { - if (!section.getElementsByClassName('alert-warning').length) section.hidden = true - }) - self.event.trigger('staticAnaysisWarning', [warningCount]) - }) - } else { - this.runBtn.setAttribute('disabled', 'disabled') - if (selected.length) { - warningContainer.html('No compiled AST available') - } - self.event.trigger('staticAnaysisWarning', [-1]) - } -} -staticAnalysisView.prototype.checkModule = function (event) { - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - const checkAll = this.view.querySelector('[id="checkAllEntries"]') - this.correctRunBtnDisabled() - if (event.target.checked) { - checkAll.checked = true - } else if (!selected.length) { - checkAll.checked = false - } -} -staticAnalysisView.prototype.correctRunBtnDisabled = function () { - if (!this.view) { - return - } - const selected = this.view.querySelectorAll('[name="staticanalysismodule"]:checked') - if (this.lastCompilationResult && selected.length !== 0) { - this.runBtn.removeAttribute('disabled') - } else { - this.runBtn.setAttribute('disabled', 'disabled') - } -} -staticAnalysisView.prototype.checkAll = function (event) { - if (!this.view) { - return - } - // checks/unchecks all - const checkBoxes = this.view.querySelectorAll('[name="staticanalysismodule"]') - checkBoxes.forEach((checkbox) => { checkbox.checked = event.target.checked }) - this.correctRunBtnDisabled() -} - -staticAnalysisView.prototype.handleCollapse = function (e) { - const downs = e.toElement.parentElement.getElementsByClassName('fas fa-angle-double-right') - const iEls = document.getElementsByTagName('i') - for (var i = 0; i < iEls.length; i++) { iEls[i].hidden = false } - downs[0].hidden = true -} - -staticAnalysisView.prototype.renderModules = function () { - const groupedModules = utils.groupBy(preProcessModules(this.runner.modules()), 'categoryId') - const moduleEntries = Object.keys(groupedModules).map((categoryId, i) => { - const category = groupedModules[categoryId] - const entriesDom = category.map((item, i) => { - return yo` -
- - -
- ` - }) - return yo` -
- this.handleCollapse(e)}"/> - -
- ${entriesDom} -
-
- ` - }) - // collaps first module - moduleEntries[0].getElementsByTagName('input')[0].checked = true - moduleEntries[0].getElementsByTagName('i')[0].hidden = true - return yo` -
- ${moduleEntries} -
` -} - -module.exports = staticAnalysisView - -/** - * @dev Process & categorize static analysis modules to show them on UI - * @param arr list of static analysis modules received from remix-analyzer module - */ -function preProcessModules (arr) { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} diff --git a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js b/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js deleted file mode 100644 index bd277a03aa..0000000000 --- a/apps/remix-ide/src/app/tabs/staticanalysis/styles/staticAnalysisView-styles.js +++ /dev/null @@ -1,36 +0,0 @@ -var csjs = require('csjs-inject') - -var css = csjs` - .analysis { - display: flex; - flex-direction: column; - } - .result { - margin-top: 1%; - max-height: 300px; - word-break: break-word; - } - .buttons { - margin: 1rem 0; - } - .label { - display: flex; - align-items: center; - } - .label { - display: flex; - align-items: center; - user-select: none; - } - .block input[type='radio']:checked ~ .entries{ - height: auto; - transition: .5s ease-in; - } - .entries{ - height: 0; - overflow: hidden; - transition: .5s ease-out; - } -` - -module.exports = css diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7bcdd9d0a3..8cae6c9e60 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -81,27 +81,30 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [warningState, setWarningState] = useState([]) - useEffect(() => { - if (autoRun) { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } + const executeCompilation = () => { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } + if (props.analysisModule) { + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (categoryIndex.length > 0) { + run(data, source, file) } - ) - } + } + ) } + } + useEffect(() => { + if (autoRun) { + executeCompilation() + } return () => { } }, [autoRun, categoryIndex]) @@ -270,6 +273,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label={item.description} onClick={event => handleCheckSingle(event, item._index)} checked={categoryIndex.includes(item._index.toString())} + onChange={() => {}} />
) @@ -297,7 +301,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} /> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -327,6 +331,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} + onChange={() => {}} /> { onClick={handleAutoRun} checked={autoRun} label="Autorun" + onChange={() => {}} />
From 43ae28e4e522f8fb8b1294227f79cf08c4d9d0e7 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 03:25:23 +0100 Subject: [PATCH 072/199] created actions and reducer to optimise code --- .../src/lib/actions/staticAnalysisActions.ts | 24 +++ .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++++++++ .../src/lib/remix-ui-static-analyser.tsx | 153 ++++++++++-------- 3 files changed, 172 insertions(+), 70 deletions(-) create mode 100644 libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts create mode 100644 libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts new file mode 100644 index 0000000000..ab9b8d3fc9 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -0,0 +1,24 @@ +import React, { useState } from 'react' //eslint-disable-line + +export const compilation = (analysisModule, state, run) => { +// const setCompilationResult = async (data, source, file) => { +// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) +// } + if (analysisModule) { + analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + if (state.categoryIndex.length > 0) { + run(data, source, file) + } + } + ) + } +} + +export const setCompilationResult = async (data, source, file) => { + return await { data, source, file } +} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts new file mode 100644 index 0000000000..f2f1a8c9d0 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -0,0 +1,65 @@ +import remixLib from '@remix-project/remix-lib' +import * as _ from 'lodash' +const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis + +const utils = remixLib.util + +const runner = new StaticAnalysisRunner() + +const preProcessModules = (arr: any) => { + return arr.map((Item, i) => { + const itemObj = new Item() + itemObj._index = i + itemObj.categoryDisplayName = itemObj.category.displayName + itemObj.categoryId = itemObj.category.id + return itemObj + }) +} + +const groupedModules = utils.groupBy( + preProcessModules(runner.modules()), + 'categoryId' +) + +const getIndex = (modules, array) => { + Object.values(modules).map((value: {_index}) => { + if (Array.isArray(value)) { + value.forEach((x) => { + array.push(x._index.toString()) + }) + } else { + array.push(value._index.toString()) + } + }) +} +const groupedModuleIndex = (modules) => { + const indexOfCategory = [] + if (!_.isEmpty(modules)) { + getIndex(modules, indexOfCategory) + } + return indexOfCategory +} + +export const initialState = { categoryIndex: [] } + +export const analysisReducer = (state, action) => { + switch (action.type) { + case 'initialize': + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + case 'uncheck': + return { + ...state, + categoryIndex: state.categoryIndex.filter((el) => { + return !action.payload.includes(el) + }) + } + case 'check': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + case 'uncheckSingle': + return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + case 'checkSingle': + return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + default: + return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + } +} diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8cae6c9e60..c0c89415c9 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState, useReducer } from 'react' import ReactDOM from 'react-dom' //eslint-disable-line import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line @@ -7,6 +7,9 @@ import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line +import { compilation, setCompilationResult } from './actions/staticAnalysisActions' +import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' + const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util @@ -62,7 +65,32 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + // const initialState = { categoryIndex: [] } + + // const reducer = (state, action) => { + // console.log({ action }) + // switch (action.type) { + // case 'initialize': + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // case 'uncheck': + // return { + // categoryIndex: state.categoryIndex.filter((el) => { + // return !action.payload.includes(el) + // }) + // } + // case 'check': + // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + // case 'uncheckSingle': + // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + // case 'checkSingle': + // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + // default: + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // } + // } + + const [state, dispatch] = useReducer(analysisReducer, initialState) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) @@ -74,63 +102,51 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [, setModuleNameResult] = useState(null) const [, setWarning] = useState({ - msg: '', options: {}, hasWarning: false, warningErrors: [] }) const [warningState, setWarningState] = useState([]) - const executeCompilation = () => { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - } - - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } - } - ) - } - } + // const executeCompilation = (categoryIndex) => { + // const setCompilationResult = async (data, source, file) => { + // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + // } + // if (props.analysisModule) { + // props.analysisModule.on( + // 'solidity', + // 'compilationFinished', + // (file, source, languageVersion, data) => { + // if (languageVersion.indexOf('soljson') !== 0) return + // setCompilationResult(data, source, file) + // console.log(categoryIndex, ' inside execute funtions') + // if (state.categoryIndex.length > 0) { + // run(data, source, file) + // } + // } + // ) + // } + // } useEffect(() => { if (autoRun) { - executeCompilation() + if (props.analysisModule && state.categoryIndex.length > 0) { + compilation(props.analysisModule, state, run) + } } - return () => { } - }, [autoRun, categoryIndex]) - - const message = (name, warning, more, fileName, locationString) : string => { - return (` - - ${name} - ${warning} - ${more - ? (more) - : ( ) + return () => { } - Pos: ${locationString} - ` - ) - } + }, [autoRun, state, props.analysisModule, setWarning]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length > 0) { + if (lastCompilationResult && state.categoryIndex.length > 0) { setRunButtonState(false) let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { + runner.run(lastCompilationResult, state.categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -167,7 +183,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -182,8 +197,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ msg, hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) + setWarning({ hasWarning: true, options, warningErrors: warningErrors }) + warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -201,16 +216,21 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } - const groupedCategory = groupBy(resultArray, 'warningModuleName') + console.log({ warningCount }, ' 221') + console.log({ groupedCategory }) setWarningState(groupedCategory) + console.log({ warningState }) + console.log({ warningCount }, ' 223') }) - if (categoryIndex.length > 0) { + console.log({ warningCount }, ' CategoryIndex outside function') + if (state.categoryIndex.length > 0) { + console.log(state.categoryIndex, ' CategoryIndex in execute funtions') props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { setRunButtonState(true) - if (categoryIndex.length) { + if (state.categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -220,27 +240,19 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } @@ -254,10 +266,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (categoryIndex.includes(_index)) { - setCategoryIndex(categoryIndex.filter(val => val !== _index)) + if (state.categoryIndex.includes(_index)) { + dispatch({ type: 'uncheckSingle', payload: _index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, _index])) + dispatch({ type: 'checkSingle', payload: _index }) } } @@ -272,7 +284,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={categoryIndex.includes(item._index.toString())} + checked={state.categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -301,7 +313,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -328,7 +340,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => categoryIndex.includes(el))} + }).flat().every(el => state.categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -341,7 +353,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -362,10 +374,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {result.currentFile && result.currentFile}
- { categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { console.log({ warningState }) } + { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- { + {/* { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -379,7 +392,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } + } */}
} From 369279cb4014d2a588398ee495b2c8f55a52b30a Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 17:30:40 +0100 Subject: [PATCH 073/199] refactored static analysis to improve performance --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 ----- .../static-analyser/src/lib/ErrorRenderer.tsx | 3 +- .../src/lib/actions/staticAnalysisActions.ts | 16 +- .../src/lib/reducers/staticAnalysisReducer.ts | 65 ++----- .../src/lib/remix-ui-static-analyser.tsx | 163 ++++++------------ 5 files changed, 71 insertions(+), 221 deletions(-) delete mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx deleted file mode 100644 index e42caa4851..0000000000 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' //eslint-disable-line - -interface StaticAnalyserCheckBoxProps { - onClick?: (event) => void - onChange?: (event) => void - label?: string - inputType?: string - name?: string - checked?: boolean - id?: string - itemName?: string - categoryId?: string -} - -const StaticAnalyserCheckedBox = ({ - id, - label, - onClick, - inputType, - name, - checked, - onChange, - itemName, - categoryId -}: StaticAnalyserCheckBoxProps) => { - return ( -
- - -
- ) -} - -export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 46dfd16a15..6f1989e3ac 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line interface ErrorRendererProps { message: any; @@ -32,6 +32,7 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { if (!message) return let position = getPositionDetails(message) + console.log({ position }) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { // Updated error reported includes '-->' before file details const errorDetails = message.split('-->') diff --git a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts index ab9b8d3fc9..4f55437cb6 100644 --- a/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts +++ b/libs/remix-ui/static-analyser/src/lib/actions/staticAnalysisActions.ts @@ -1,24 +1,14 @@ -import React, { useState } from 'react' //eslint-disable-line +import React from 'react' //eslint-disable-line -export const compilation = (analysisModule, state, run) => { -// const setCompilationResult = async (data, source, file) => { -// await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) -// } +export const compilation = (analysisModule, dispatch) => { if (analysisModule) { analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (state.categoryIndex.length > 0) { - run(data, source, file) - } + dispatch({ type: 'compilationFinished', payload: { file, source, languageVersion, data } }) } ) } } - -export const setCompilationResult = async (data, source, file) => { - return await { data, source, file } -} diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts index f2f1a8c9d0..833ef55b39 100644 --- a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -1,65 +1,22 @@ -import remixLib from '@remix-project/remix-lib' -import * as _ from 'lodash' -const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis -const utils = remixLib.util - -const runner = new StaticAnalysisRunner() - -const preProcessModules = (arr: any) => { - return arr.map((Item, i) => { - const itemObj = new Item() - itemObj._index = i - itemObj.categoryDisplayName = itemObj.category.displayName - itemObj.categoryId = itemObj.category.id - return itemObj - }) -} - -const groupedModules = utils.groupBy( - preProcessModules(runner.modules()), - 'categoryId' -) - -const getIndex = (modules, array) => { - Object.values(modules).map((value: {_index}) => { - if (Array.isArray(value)) { - value.forEach((x) => { - array.push(x._index.toString()) - }) - } else { - array.push(value._index.toString()) - } - }) -} -const groupedModuleIndex = (modules) => { - const indexOfCategory = [] - if (!_.isEmpty(modules)) { - getIndex(modules, indexOfCategory) - } - return indexOfCategory +export const initialState = { + file: null, + source: null, + languageVersion: null, + data: null } -export const initialState = { categoryIndex: [] } - export const analysisReducer = (state, action) => { switch (action.type) { - case 'initialize': - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } - case 'uncheck': + case 'compilationFinished': return { ...state, - categoryIndex: state.categoryIndex.filter((el) => { - return !action.payload.includes(el) - }) + file: action.payload.file, + source: action.payload.source, + languageVersion: action.payload.languageVersion, + data: action.payload.data } - case 'check': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - case 'uncheckSingle': - return { ...state, categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - case 'checkSingle': - return { ...state, categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } default: - return { ...state, categoryIndex: groupedModuleIndex(groupedModules) } + return initialState } } diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index c0c89415c9..7725321271 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,30 +1,20 @@ import React, { useEffect, useState, useReducer } from 'react' -import ReactDOM from 'react-dom' //eslint-disable-line -import CheckBox from './Checkbox/StaticAnalyserCheckedBox' // eslint-disable-line import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' import _ from 'lodash' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line import ErrorRenderer from './ErrorRenderer' // eslint-disable-line -import { compilation, setCompilationResult } from './actions/staticAnalysisActions' -import { analysisReducer, initialState } from './reducers/staticAnalysisReducer' - +import { compilation } from './actions/staticAnalysisActions' +import { initialState, analysisReducer } from './reducers/staticAnalysisReducer' const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis const utils = remixLib.util /* eslint-disable-next-line */ export interface RemixUiStaticAnalyserProps { - renderStaticAnalysis: any - staticanalysis: any - analysisRunner: any, - lastCompilationResult: any, - lastCompilationSource: any, registry: any, event: any, analysisModule: any - _deps: any, - emit: any } export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { @@ -65,88 +55,46 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - - // const initialState = { categoryIndex: [] } - - // const reducer = (state, action) => { - // console.log({ action }) - // switch (action.type) { - // case 'initialize': - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // case 'uncheck': - // return { - // categoryIndex: state.categoryIndex.filter((el) => { - // return !action.payload.includes(el) - // }) - // } - // case 'check': - // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - // case 'uncheckSingle': - // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - // case 'checkSingle': - // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } - // default: - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // } - // } - - const [state, dispatch] = useReducer(analysisReducer, initialState) + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) - const [runButtonState, setRunButtonState] = useState(true) - - const [result, setResult] = useState({ - lastCompilationResult: null, - lastCompilationSource: null, - currentFile: 'No file compiled' - }) - const [, setModuleNameResult] = useState(null) - const [, setWarning] = useState({ - options: {}, - hasWarning: false, - warningErrors: [] - }) const [warningState, setWarningState] = useState([]) + const [state, dispatch] = useReducer(analysisReducer, initialState) - // const executeCompilation = (categoryIndex) => { - // const setCompilationResult = async (data, source, file) => { - // await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) - // } - // if (props.analysisModule) { - // props.analysisModule.on( - // 'solidity', - // 'compilationFinished', - // (file, source, languageVersion, data) => { - // if (languageVersion.indexOf('soljson') !== 0) return - // setCompilationResult(data, source, file) - // console.log(categoryIndex, ' inside execute funtions') - // if (state.categoryIndex.length > 0) { - // run(data, source, file) - // } - // } - // ) - // } - // } + useEffect(() => { + compilation(props.analysisModule, dispatch) + }, []) useEffect(() => { if (autoRun) { - if (props.analysisModule && state.categoryIndex.length > 0) { - compilation(props.analysisModule, state, run) + if (state.data !== null) { + run(state.data, state.source, state.file) } } - return () => { + return () => { } + }, [autoRun, categoryIndex, state]) + + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) } - }, [autoRun, state, props.analysisModule, setWarning]) + Pos: ${locationString} + ` + ) + } const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && state.categoryIndex.length > 0) { - setRunButtonState(false) + if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, state.categoryIndex, results => { + runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -156,7 +104,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } }) }) - setModuleNameResult(moduleName) const warningErrors = [] result.report.map((item) => { let location: any = {} @@ -183,6 +130,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -197,8 +145,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { location: location } warningErrors.push(options) - setWarning({ hasWarning: true, options, warningErrors: warningErrors }) - warningMessage.push({ options, hasWarning: true, warningModuleName: moduleName }) + warningMessage.push({ msg, options, hasWarning: true, warningModuleName: moduleName }) }) }) const resultArray = [] @@ -216,21 +163,15 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } + const groupedCategory = groupBy(resultArray, 'warningModuleName') - console.log({ warningCount }, ' 221') - console.log({ groupedCategory }) setWarningState(groupedCategory) - console.log({ warningState }) - console.log({ warningCount }, ' 223') }) - console.log({ warningCount }, ' CategoryIndex outside function') - if (state.categoryIndex.length > 0) { - console.log(state.categoryIndex, ' CategoryIndex in execute funtions') + if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { - setRunButtonState(true) - if (state.categoryIndex.length) { + if (categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) @@ -240,19 +181,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } @@ -266,10 +215,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (state.categoryIndex.includes(_index)) { - dispatch({ type: 'uncheckSingle', payload: _index }) + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) } else { - dispatch({ type: 'checkSingle', payload: _index }) + setCategoryIndex(_.uniq([...categoryIndex, _index])) } } @@ -284,7 +233,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={state.categoryIndex.includes(item._index.toString())} + checked={categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -313,7 +262,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -340,7 +289,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => state.categoryIndex.includes(el))} + }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -353,7 +302,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { label="Autorun" onChange={() => {}} /> -
@@ -371,14 +320,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { className="text-break break-word word-break font-weight-bold" id="staticAnalysisCurrentFile" > - {result.currentFile && result.currentFile}
- { console.log({ warningState }) } - { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- {/* { + { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -392,7 +339,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } */} + }
} From fb1fc3066d0b379a3d1e4373a99abd25fdd57342 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 30 Apr 2021 09:33:50 +0100 Subject: [PATCH 074/199] fix: filename not showing in the result `last result for:` section --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7725321271..a4fc998fad 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -320,6 +320,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { className="text-break break-word word-break font-weight-bold" id="staticAnalysisCurrentFile" > + {state.file}
{ categoryIndex.length > 0 && Object.entries(warningState).length > 0 && From 97663b3859e5519ba41127f362c9d98a983cca30 Mon Sep 17 00:00:00 2001 From: tizah Date: Wed, 5 May 2021 07:56:43 +0100 Subject: [PATCH 075/199] rebasing to manually resolve conflicts --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 +++++++++++++++++++ .../static-analyser/src/lib/ErrorRenderer.tsx | 1 - .../src/lib/remix-ui-static-analyser.tsx | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx new file mode 100644 index 0000000000..2326a39122 --- /dev/null +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -0,0 +1,45 @@ +import React from 'react' //eslint-disable-line + +interface StaticAnalyserCheckBoxProps { + onClick?: (event) => void + onChange?: (event) => void + label?: string + inputType?: string + name?: string + checked?: boolean + id?: string + itemName?: string + categoryId?: string +} + +const StaticAnalyserCheckedBox = ({ + id, + label, + onClick, + inputType, + name, + checked, + onChange, + itemName, + categoryId +}: StaticAnalyserCheckBoxProps) => { + return ( +
+ + +
+ ) +} + +export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index 6f1989e3ac..cee2eaa18f 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -1,5 +1,4 @@ import React from 'react' //eslint-disable-line - interface ErrorRendererProps { message: any; opt: any, diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index a4fc998fad..086b56683b 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,3 +1,4 @@ + import React, { useEffect, useState, useReducer } from 'react' import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' From 2c0fa1dd5090925784f22704b1d56666e9f1634c Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 12 Apr 2021 12:51:49 +0100 Subject: [PATCH 076/199] added warning sign when analysis has runned rebasin --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 086b56683b..9829f5967e 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -1,4 +1,3 @@ - import React, { useEffect, useState, useReducer } from 'react' import Button from './Button/StaticAnalyserButton' // eslint-disable-line import remixLib from '@remix-project/remix-lib' @@ -71,7 +70,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { if (state.data !== null) { run(state.data, state.source, state.file) } + } else { + setAutoRun(true) } + return () => { } }, [autoRun, categoryIndex, state]) From aa943f4e8cdf5ec26e132f4c5cac1dde4a0955b8 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 17:49:24 +0100 Subject: [PATCH 077/199] commiting code to detect failing test rebasing --- .../src/tests/staticAnalysis.spec.ts | 24 +++++++++--------- .../src/lib/remix-ui-static-analyser.tsx | 25 +++++++++++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..480fab63fb 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,18 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) + //.click('#staticanalysisButton button') + // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + // listSelectorContains(['Use of tx.origin', + // 'Fallback function of contract TooMuchGas requires too much gas', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + // '#staticanalysisresult .warning', + // browser, function () { + // browser.end() + // } + // ) + // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 9829f5967e..7050d40301 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -65,10 +65,23 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { compilation(props.analysisModule, dispatch) }, []) +<<<<<<< HEAD useEffect(() => { if (autoRun) { if (state.data !== null) { run(state.data, state.source, state.file) +======= + if (props.analysisModule) { + props.analysisModule.on( + 'solidity', + 'compilationFinished', + (file, source, languageVersion, data) => { + if (languageVersion.indexOf('soljson') !== 0) return + setCompilationResult(data, source, file) + run(data, source, file) + } + ) +>>>>>>> 19de4ba6b (commiting code to detect failing test) } } else { setAutoRun(true) @@ -92,10 +105,22 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } const run = (lastCompilationResult, lastCompilationSource, currentFile) => { +<<<<<<< HEAD if (autoRun) { if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] +======= + // const highlightLocation = async (location, fileName) => { + // await props.analysisModule.call('editor', 'discardHighlight') + // await props.analysisModule.call('editor', 'highlight', location, fileName) + // } + setResult({ lastCompilationResult, lastCompilationSource, currentFile }) + if (lastCompilationResult && categoryIndex.length) { + setRunButtonState(false) + let warningCount = 0 + const warningMessage = [] +>>>>>>> 19de4ba6b (commiting code to detect failing test) runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { From 9f20fe76a70970fc334924e8f37c194394b4fdb8 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:00:14 +0100 Subject: [PATCH 078/199] removed comments --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 480fab63fb..e9777e2970 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,18 +40,6 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - //.click('#staticanalysisButton button') - // .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - // listSelectorContains(['Use of tx.origin', - // 'Fallback function of contract TooMuchGas requires too much gas', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - // 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - // '#staticanalysisresult .warning', - // browser, function () { - // browser.end() - // } - // ) - // }) } function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { From 53d3e2ae139d5796e2618568e1285ed15c1a9f98 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:09:41 +0100 Subject: [PATCH 079/199] removing comments and unused functions --- .../src/tests/staticAnalysis.spec.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index e9777e2970..a10a2a8348 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -42,20 +42,4 @@ function runTests (browser: NightwatchBrowser) { .clickLaunchIcon('solidityStaticAnalysis') } -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) -} + From 2804a0e545e95cd87eaa7c21aaec945ecfefd460 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:20:19 +0100 Subject: [PATCH 080/199] removed extra space at end of file --- apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index a10a2a8348..8fa094273e 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,6 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} - - +} \ No newline at end of file From 64f995ce74434d4faef4d6d221ca61e5f417b928 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:27:17 +0100 Subject: [PATCH 081/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 8fa094273e..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') -} \ No newline at end of file + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) +} From 80cce478b07bc715954e8503e16a07622f64ea29 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:35:52 +0100 Subject: [PATCH 082/199] added new line at end of file --- .../src/tests/staticAnalysis.spec.ts | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 504148b266..55f7329f65 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,34 +40,4 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') - .click('#staticanalysisButton button') - .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { - listSelectorContains(['Use of tx.origin', - 'Fallback function of contract TooMuchGas requires too much gas', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".', - 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], - '#staticanalysisresult .warning', - browser, function () { - browser.end() - } - ) - }) -} - -function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { - browser.execute(function (selector) { - const items = document.querySelectorAll(selector) - const ret = [] - for (let k = 0; k < items.length; k++) { - ret.push(items[k].innerText) - } - return ret - }, [selector], function (result) { - console.log(result.value) - for (const k in textsToFind) { - console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') - browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) - } - callback() - }) } From 2e16a23ab0fcd0eb9ffdb5223f9f04316b7e2871 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 17 Apr 2021 18:37:33 +0100 Subject: [PATCH 083/199] restored staticAnalysis.spec.ts to it previous code structure --- .../src/tests/staticAnalysis.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts index 55f7329f65..504148b266 100644 --- a/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts +++ b/apps/remix-ide-e2e/src/tests/staticAnalysis.spec.ts @@ -40,4 +40,34 @@ function runTests (browser: NightwatchBrowser) { .pause(10000) .testContracts('Untitled.sol', sources[0]['Untitled.sol'], ['TooMuchGas', 'test1', 'test2']) .clickLaunchIcon('solidityStaticAnalysis') + .click('#staticanalysisButton button') + .waitForElementPresent('#staticanalysisresult .warning', 2000, true, function () { + listSelectorContains(['Use of tx.origin', + 'Fallback function of contract TooMuchGas requires too much gas', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".', + 'TooMuchGas.() : Variables have very similar names "test" and "test1".'], + '#staticanalysisresult .warning', + browser, function () { + browser.end() + } + ) + }) +} + +function listSelectorContains (textsToFind: string[], selector: string, browser: NightwatchBrowser, callback: VoidFunction) { + browser.execute(function (selector) { + const items = document.querySelectorAll(selector) + const ret = [] + for (let k = 0; k < items.length; k++) { + ret.push(items[k].innerText) + } + return ret + }, [selector], function (result) { + console.log(result.value) + for (const k in textsToFind) { + console.log('testing `' + result.value[k] + '` against `' + textsToFind[k] + '`') + browser.assert.equal(result.value[k].indexOf(textsToFind[k]) !== -1, true) + } + callback() + }) } From 420eb68b9e8e2d5acc80d7c6011fa9bd50198e61 Mon Sep 17 00:00:00 2001 From: tizah Date: Mon, 19 Apr 2021 14:25:28 +0100 Subject: [PATCH 084/199] fix failing test rebase fix failing test --- .../src/lib/remix-ui-static-analyser.tsx | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7050d40301..8a76b10513 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -62,6 +62,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [state, dispatch] = useReducer(analysisReducer, initialState) useEffect(() => { +<<<<<<< HEAD compilation(props.analysisModule, dispatch) }, []) @@ -71,14 +72,26 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { if (state.data !== null) { run(state.data, state.source, state.file) ======= +======= + + if (autoRun) { + const setCompilationResult = async (data, source, file) => { + await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) + } + +>>>>>>> 8a85ae84e (fix failing test) if (props.analysisModule) { + props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - run(data, source, file) + if(categoryIndex.length > 0){ + run(data, source, file) + } + } ) >>>>>>> 19de4ba6b (commiting code to detect failing test) @@ -88,6 +101,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { } return () => { } +<<<<<<< HEAD }, [autoRun, categoryIndex, state]) const message = (name, warning, more, fileName, locationString) : string => { @@ -103,6 +117,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ` ) } +======= + }, [autoRun, categoryIndex]) +>>>>>>> 8a85ae84e (fix failing test) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { <<<<<<< HEAD @@ -198,11 +215,25 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } +<<<<<<< HEAD } else { if (categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) +======= + + const groupedCategory = groupBy(resultArray, 'warningModuleName') + setWarningState(groupedCategory) + }) + if(categoryIndex.length > 0){ + props.event.trigger('staticAnaysisWarning', [warningCount]) + } + } else { + setRunButtonState(true) + if (categoryIndex.length) { + warningContainer.current.innerText = 'No compiled AST available' +>>>>>>> 8a85ae84e (fix failing test) } } } @@ -216,8 +247,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + setCategoryIndex(_.uniq([...categoryIndex])) } + } const handleCheckOrUncheckCategory = (category) => { From ca85da35e2053e1c168a9a809c193228b8fdc580 Mon Sep 17 00:00:00 2001 From: tizah Date: Fri, 23 Apr 2021 11:23:00 +0100 Subject: [PATCH 085/199] feat_fix_n_refactor: exptracted checkbox as a reusable component and fix selec all and auto run, rebasing extracted checkbox as reusable component --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 8 +-- .../src/lib/remix-ui-static-analyser.tsx | 63 +++++-------------- 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx index 2326a39122..e42caa4851 100644 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx @@ -24,7 +24,7 @@ const StaticAnalyserCheckedBox = ({ categoryId }: StaticAnalyserCheckBoxProps) => { return ( -
+
-
) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 8a76b10513..7938baa71f 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -58,50 +58,50 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) + const [runButtonState, setRunButtonState] = useState(true) + + const [result, setResult] = useState({ + lastCompilationResult: null, + lastCompilationSource: null, + currentFile: 'No file compiled' + }) + const [, setModuleNameResult] = useState(null) + const [, setWarning] = useState({ + msg: '', + options: {}, + hasWarning: false, + warningErrors: [] + }) const [warningState, setWarningState] = useState([]) const [state, dispatch] = useReducer(analysisReducer, initialState) useEffect(() => { -<<<<<<< HEAD compilation(props.analysisModule, dispatch) }, []) -<<<<<<< HEAD useEffect(() => { if (autoRun) { if (state.data !== null) { run(state.data, state.source, state.file) -======= -======= - if (autoRun) { const setCompilationResult = async (data, source, file) => { await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - ->>>>>>> 8a85ae84e (fix failing test) if (props.analysisModule) { - props.analysisModule.on( 'solidity', 'compilationFinished', (file, source, languageVersion, data) => { if (languageVersion.indexOf('soljson') !== 0) return setCompilationResult(data, source, file) - if(categoryIndex.length > 0){ + if (categoryIndex.length > 0) { run(data, source, file) } - } ) ->>>>>>> 19de4ba6b (commiting code to detect failing test) } - } else { - setAutoRun(true) } - return () => { } -<<<<<<< HEAD }, [autoRun, categoryIndex, state]) const message = (name, warning, more, fileName, locationString) : string => { @@ -117,27 +117,12 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ` ) } -======= - }, [autoRun, categoryIndex]) ->>>>>>> 8a85ae84e (fix failing test) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { -<<<<<<< HEAD if (autoRun) { if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] -======= - // const highlightLocation = async (location, fileName) => { - // await props.analysisModule.call('editor', 'discardHighlight') - // await props.analysisModule.call('editor', 'highlight', location, fileName) - // } - setResult({ lastCompilationResult, lastCompilationSource, currentFile }) - if (lastCompilationResult && categoryIndex.length) { - setRunButtonState(false) - let warningCount = 0 - const warningMessage = [] ->>>>>>> 19de4ba6b (commiting code to detect failing test) runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { @@ -215,25 +200,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } -<<<<<<< HEAD } else { if (categoryIndex.length) { warningContainer.current.innerText = 'No compiled AST available' } props.event.trigger('staticAnaysisWarning', [-1]) -======= - - const groupedCategory = groupBy(resultArray, 'warningModuleName') - setWarningState(groupedCategory) - }) - if(categoryIndex.length > 0){ - props.event.trigger('staticAnaysisWarning', [warningCount]) - } - } else { - setRunButtonState(true) - if (categoryIndex.length) { - warningContainer.current.innerText = 'No compiled AST available' ->>>>>>> 8a85ae84e (fix failing test) } } } @@ -247,9 +218,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) ) } else { - setCategoryIndex(_.uniq([...categoryIndex])) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } - } const handleCheckOrUncheckCategory = (category) => { @@ -342,6 +312,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
+
Date: Fri, 23 Apr 2021 16:57:24 +0100 Subject: [PATCH 086/199] refactored warning message --- .../src/lib/remix-ui-static-analyser.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 7938baa71f..337d3eeb89 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -118,6 +118,20 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ) } + const message = (name, warning, more, fileName, locationString) : string => { + return (` + + ${name} + ${warning} + ${more + ? (more) + : ( ) + } + Pos: ${locationString} + ` + ) + } + const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { if (lastCompilationResult && categoryIndex.length > 0) { From 68e41a9a28ea96b0791c58995e33e8562e338abb Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 24 Apr 2021 06:10:21 +0100 Subject: [PATCH 087/199] fix editor highlighter rebasing --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 337d3eeb89..95f05fae01 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -326,7 +326,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
+<<<<<<< HEAD
+======= +>>>>>>> 691f449c6 (fix editor highlighter) Date: Sun, 25 Apr 2021 13:41:17 +0100 Subject: [PATCH 088/199] removed old staticAnalysis from remix-project --- .../static-analyser/src/lib/remix-ui-static-analyser.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 95f05fae01..5956bfa4a5 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -98,8 +98,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { run(data, source, file) } } - ) - } + } + ) } return () => { } }, [autoRun, categoryIndex, state]) @@ -326,10 +326,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
-<<<<<<< HEAD
-======= ->>>>>>> 691f449c6 (fix editor highlighter) Date: Tue, 27 Apr 2021 03:25:23 +0100 Subject: [PATCH 089/199] created actions and reducer to optimise code --- .../src/lib/reducers/staticAnalysisReducer.ts | 1 - .../src/lib/remix-ui-static-analyser.tsx | 84 +++++++++++-------- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts index 833ef55b39..eb59ca7872 100644 --- a/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts +++ b/libs/remix-ui/static-analyser/src/lib/reducers/staticAnalysisReducer.ts @@ -1,4 +1,3 @@ - export const initialState = { file: null, source: null, diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 5956bfa4a5..1a2d365327 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -55,7 +55,32 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) + + // const initialState = { categoryIndex: [] } + + // const reducer = (state, action) => { + // console.log({ action }) + // switch (action.type) { + // case 'initialize': + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // case 'uncheck': + // return { + // categoryIndex: state.categoryIndex.filter((el) => { + // return !action.payload.includes(el) + // }) + // } + // case 'check': + // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } + // case 'uncheckSingle': + // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } + // case 'checkSingle': + // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } + // default: + // return { categoryIndex: groupedModuleIndex(groupedModules) } + // } + // } + + const [state, dispatch] = useReducer(analysisReducer, initialState) const warningContainer = React.useRef(null) const [runButtonState, setRunButtonState] = useState(true) @@ -67,7 +92,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { }) const [, setModuleNameResult] = useState(null) const [, setWarning] = useState({ - msg: '', options: {}, hasWarning: false, warningErrors: [] @@ -127,10 +151,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ? (more) : ( ) } - Pos: ${locationString} - ` - ) - } + }, [autoRun, state, props.analysisModule, setWarning]) const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { @@ -138,7 +159,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, categoryIndex, results => { + runner.run(lastCompilationResult, state.categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -174,7 +195,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ - const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -207,11 +227,16 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } - const groupedCategory = groupBy(resultArray, 'warningModuleName') + console.log({ warningCount }, ' 221') + console.log({ groupedCategory }) setWarningState(groupedCategory) + console.log({ warningState }) + console.log({ warningCount }, ' 223') }) - if (categoryIndex.length > 0) { + console.log({ warningCount }, ' CategoryIndex outside function') + if (state.categoryIndex.length > 0) { + console.log(state.categoryIndex, ' CategoryIndex in execute funtions') props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { @@ -225,27 +250,19 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => categoryIndex.includes(el))) { - setCategoryIndex( - categoryIndex.filter((el) => { - return !index.includes(el) - }) - ) + if (index.every(el => state.categoryIndex.includes(el))) { + dispatch({ type: 'uncheck', payload: index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, ...index])) + dispatch({ type: 'check', payload: index }) } } @@ -259,10 +276,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (categoryIndex.includes(_index)) { - setCategoryIndex(categoryIndex.filter(val => val !== _index)) + if (state.categoryIndex.includes(_index)) { + dispatch({ type: 'uncheckSingle', payload: _index }) } else { - setCategoryIndex(_.uniq([...categoryIndex, _index])) + dispatch({ type: 'checkSingle', payload: _index }) } } @@ -277,7 +294,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={categoryIndex.includes(item._index.toString())} + checked={state.categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -306,7 +323,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -334,7 +351,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => categoryIndex.includes(el))} + }).flat().every(el => state.categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -368,10 +385,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {state.file}
- { categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { console.log({ warningState }) } + { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- { + {/* { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -385,7 +403,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } + } */}
} From 704010894a7e06c36e69d8405ce4bfaa5330c2e8 Mon Sep 17 00:00:00 2001 From: tizah Date: Tue, 27 Apr 2021 17:30:40 +0100 Subject: [PATCH 090/199] refactored static analysis to improve performance --- .../lib/Checkbox/StaticAnalyserCheckedBox.tsx | 45 --------- .../src/lib/remix-ui-static-analyser.tsx | 96 +++++++------------ 2 files changed, 32 insertions(+), 109 deletions(-) delete mode 100644 libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx diff --git a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx b/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx deleted file mode 100644 index e42caa4851..0000000000 --- a/libs/remix-ui/static-analyser/src/lib/Checkbox/StaticAnalyserCheckedBox.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' //eslint-disable-line - -interface StaticAnalyserCheckBoxProps { - onClick?: (event) => void - onChange?: (event) => void - label?: string - inputType?: string - name?: string - checked?: boolean - id?: string - itemName?: string - categoryId?: string -} - -const StaticAnalyserCheckedBox = ({ - id, - label, - onClick, - inputType, - name, - checked, - onChange, - itemName, - categoryId -}: StaticAnalyserCheckBoxProps) => { - return ( -
- - -
- ) -} - -export default StaticAnalyserCheckedBox diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 1a2d365327..27e7e55f1e 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -55,47 +55,9 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return indexOfCategory } const [autoRun, setAutoRun] = useState(true) - - // const initialState = { categoryIndex: [] } - - // const reducer = (state, action) => { - // console.log({ action }) - // switch (action.type) { - // case 'initialize': - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // case 'uncheck': - // return { - // categoryIndex: state.categoryIndex.filter((el) => { - // return !action.payload.includes(el) - // }) - // } - // case 'check': - // return { categoryIndex: _.uniq([...state.categoryIndex, ...action.payload]) } - // case 'uncheckSingle': - // return { categoryIndex: state.categoryIndex.filter(val => val !== action.payload) } - // case 'checkSingle': - // return { categoryIndex: _.uniq([...state.categoryIndex, action.payload]) } - // default: - // return { categoryIndex: groupedModuleIndex(groupedModules) } - // } - // } - - const [state, dispatch] = useReducer(analysisReducer, initialState) + const [categoryIndex, setCategoryIndex] = useState(groupedModuleIndex(groupedModules)) const warningContainer = React.useRef(null) - const [runButtonState, setRunButtonState] = useState(true) - - const [result, setResult] = useState({ - lastCompilationResult: null, - lastCompilationSource: null, - currentFile: 'No file compiled' - }) - const [, setModuleNameResult] = useState(null) - const [, setWarning] = useState({ - options: {}, - hasWarning: false, - warningErrors: [] - }) const [warningState, setWarningState] = useState([]) const [state, dispatch] = useReducer(analysisReducer, initialState) @@ -151,7 +113,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ? (more) : ( ) } - }, [autoRun, state, props.analysisModule, setWarning]) + Pos: ${locationString} + ` + ) + } const run = (lastCompilationResult, lastCompilationSource, currentFile) => { if (autoRun) { @@ -159,7 +124,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { let warningCount = 0 const warningMessage = [] - runner.run(lastCompilationResult, state.categoryIndex, results => { + runner.run(lastCompilationResult, categoryIndex, results => { results.map((result) => { let moduleName Object.keys(groupedModules).map(key => { @@ -195,6 +160,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { fileName = Object.keys(lastCompilationResult.contracts)[file] } warningCount++ + const msg = message(item.name, item.warning, item.more, fileName, locationString) const options = { type: 'warning', useSpan: true, @@ -227,16 +193,11 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return acc }, {}) } + const groupedCategory = groupBy(resultArray, 'warningModuleName') - console.log({ warningCount }, ' 221') - console.log({ groupedCategory }) setWarningState(groupedCategory) - console.log({ warningState }) - console.log({ warningCount }, ' 223') }) - console.log({ warningCount }, ' CategoryIndex outside function') - if (state.categoryIndex.length > 0) { - console.log(state.categoryIndex, ' CategoryIndex in execute funtions') + if (categoryIndex.length > 0) { props.event.trigger('staticAnaysisWarning', [warningCount]) } } else { @@ -250,19 +211,27 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckAllModules = (groupedModules) => { const index = groupedModuleIndex(groupedModules) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } const handleCheckOrUncheckCategory = (category) => { const index = groupedModuleIndex(category) - if (index.every(el => state.categoryIndex.includes(el))) { - dispatch({ type: 'uncheck', payload: index }) + if (index.every(el => categoryIndex.includes(el))) { + setCategoryIndex( + categoryIndex.filter((el) => { + return !index.includes(el) + }) + ) } else { - dispatch({ type: 'check', payload: index }) + setCategoryIndex(_.uniq([...categoryIndex, ...index])) } } @@ -276,10 +245,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { const handleCheckSingle = (event, _index) => { _index = _index.toString() - if (state.categoryIndex.includes(_index)) { - dispatch({ type: 'uncheckSingle', payload: _index }) + if (categoryIndex.includes(_index)) { + setCategoryIndex(categoryIndex.filter(val => val !== _index)) } else { - dispatch({ type: 'checkSingle', payload: _index }) + setCategoryIndex(_.uniq([...categoryIndex, _index])) } } @@ -294,7 +263,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { itemName={item.name} label={item.description} onClick={event => handleCheckSingle(event, item._index)} - checked={state.categoryIndex.includes(item._index.toString())} + checked={categoryIndex.includes(item._index.toString())} onChange={() => {}} />
@@ -323,7 +292,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { expand={false} >
- handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => state.categoryIndex.includes(el))} onChange={() => {}}/> + handleCheckOrUncheckCategory(category)} id={categoryId} inputType="checkbox" label={`Select ${category[0].categoryDisplayName}`} name='checkCategoryEntry' checked={category.map(x => x._index.toString()).every(el => categoryIndex.includes(el))} onChange={() => {}}/>
{category.map((item, i) => { @@ -351,7 +320,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { return (value.map(x => { return x._index.toString() })) - }).flat().every(el => state.categoryIndex.includes(el))} + }).flat().every(el => categoryIndex.includes(el))} label="Select all" onClick={() => handleCheckAllModules(groupedModules)} onChange={() => {}} @@ -385,11 +354,10 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { {state.file}
- { console.log({ warningState }) } - { state.categoryIndex.length > 0 && Object.entries(warningState).length > 0 && + { categoryIndex.length > 0 && Object.entries(warningState).length > 0 &&
- {/* { + { (Object.entries(warningState).map((element) => ( <> {element[0]} @@ -403,7 +371,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ))} ))) - } */} + }
} From 2f31e64e17c26ee4f739c6a9197cd6b25973234f Mon Sep 17 00:00:00 2001 From: tizah Date: Wed, 5 May 2021 13:02:29 +0100 Subject: [PATCH 091/199] resolving conflict manually from rebase --- .../static-analyser/src/lib/ErrorRenderer.tsx | 1 - .../src/lib/remix-ui-static-analyser.tsx | 33 +------------------ 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx index cee2eaa18f..6364007668 100644 --- a/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx +++ b/libs/remix-ui/static-analyser/src/lib/ErrorRenderer.tsx @@ -31,7 +31,6 @@ const ErrorRenderer = ({ message, opt, editor }: ErrorRendererProps) => { if (!message) return let position = getPositionDetails(message) - console.log({ position }) if (!position.errFile || (opt.errorType && opt.errorType === position.errFile)) { // Updated error reported includes '-->' before file details const errorDetails = message.split('-->') diff --git a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx index 27e7e55f1e..5bb91441af 100644 --- a/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx +++ b/libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx @@ -69,23 +69,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { if (autoRun) { if (state.data !== null) { run(state.data, state.source, state.file) - if (autoRun) { - const setCompilationResult = async (data, source, file) => { - await setResult({ lastCompilationResult: data, lastCompilationSource: source, currentFile: file }) } - if (props.analysisModule) { - props.analysisModule.on( - 'solidity', - 'compilationFinished', - (file, source, languageVersion, data) => { - if (languageVersion.indexOf('soljson') !== 0) return - setCompilationResult(data, source, file) - if (categoryIndex.length > 0) { - run(data, source, file) - } - } - } - ) } return () => { } }, [autoRun, categoryIndex, state]) @@ -104,22 +88,8 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { ) } - const message = (name, warning, more, fileName, locationString) : string => { - return (` - - ${name} - ${warning} - ${more - ? (more) - : ( ) - } - Pos: ${locationString} - ` - ) - } - const run = (lastCompilationResult, lastCompilationSource, currentFile) => { - if (autoRun) { + if (state.data !== null) { if (lastCompilationResult && categoryIndex.length > 0) { let warningCount = 0 const warningMessage = [] @@ -312,7 +282,6 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
-
Date: Thu, 6 May 2021 20:18:17 +0200 Subject: [PATCH 092/199] adding pause --- apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts index ec65abce49..b60cd045e4 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts @@ -81,6 +81,7 @@ module.exports = { .waitForElementPresent('*[data-id="testTabRunTestsTabRunAction"]') .clickElementAtPosition('.singleTestLabel', 0) .clickElementAtPosition('.singleTestLabel', 1) + .pause(5000) .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') .pause(5000) .click('*[data-id="testTabRunTestsTabStopAction"]') From 7d612e2bb7c7a560c80ed54f156cd08bf1094793 Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 10 May 2021 11:24:46 +0200 Subject: [PATCH 093/199] cleaning old results og SUT plugin --- apps/remix-ide/src/app/tabs/test-tab.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js index f1ff124df5..eb6edd4efb 100644 --- a/apps/remix-ide/src/app/tabs/test-tab.js +++ b/apps/remix-ide/src/app/tabs/test-tab.js @@ -76,6 +76,7 @@ module.exports = class TestTab extends ViewPlugin { this.updateGenerateFileAction() if (!this.areTestsRunning) this.updateRunAction(file) this.updateTestFileList() + this.clearResults() this.testTabLogic.getTests((error, tests) => { if (error) return tooltip(error) this.data.allTests = tests @@ -434,21 +435,26 @@ module.exports = class TestTab extends ViewPlugin { this.uiPathList.appendChild(yo``) } + clearResults () { + yo.update(this.resultStatistics, yo``) + this.call('editor', 'clearAnnotations') + this.testsOutput.innerHTML = '' + this.testsOutput.hidden = true + this.testsExecutionStopped.hidden = true + this.testsExecutionStoppedError.hidden = true + } + runTests () { this.areTestsRunning = true this.hasBeenStopped = false this.readyTestsNumber = 0 this.runningTestsNumber = this.data.selectedTests.length - yo.update(this.resultStatistics, this.createResultLabel()) const stopBtn = document.getElementById('runTestsTabStopAction') stopBtn.removeAttribute('disabled') const runBtn = document.getElementById('runTestsTabRunAction') runBtn.setAttribute('disabled', 'disabled') - this.call('editor', 'clearAnnotations') - this.testsOutput.innerHTML = '' - this.testsOutput.hidden = true - this.testsExecutionStopped.hidden = true - this.testsExecutionStoppedError.hidden = true + this.clearResults() + yo.update(this.resultStatistics, this.createResultLabel()) const tests = this.data.selectedTests if (!tests) return this.resultStatistics.hidden = tests.length === 0 From f5b1816630e2e258dc2f9ac9c657dabaa10e51b2 Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 10 May 2021 11:45:04 +0200 Subject: [PATCH 094/199] test --- apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts index b60cd045e4..3601539f3d 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts @@ -81,9 +81,8 @@ module.exports = { .waitForElementPresent('*[data-id="testTabRunTestsTabRunAction"]') .clickElementAtPosition('.singleTestLabel', 0) .clickElementAtPosition('.singleTestLabel', 1) - .pause(5000) .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') - .pause(5000) + .pause(2000) .click('*[data-id="testTabRunTestsTabStopAction"]') .waitForElementContainsText('*[data-id="testTabRunTestsTabStopAction"]', 'Stopping', 60000) .waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', '/tests/ks2b_test.sol', 120000) From d9d8ad53f63b50535634c7b61ea345bc804ddb65 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 May 2021 21:27:57 +0200 Subject: [PATCH 095/199] fix extracting parentScope (#1157) fix https://github.com/ethereum/remix-project/issues/1153 --- libs/remix-debug/src/solidity-decoder/internalCallTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/remix-debug/src/solidity-decoder/internalCallTree.ts b/libs/remix-debug/src/solidity-decoder/internalCallTree.ts index f798b7beff..acdeae4749 100644 --- a/libs/remix-debug/src/solidity-decoder/internalCallTree.ts +++ b/libs/remix-debug/src/solidity-decoder/internalCallTree.ts @@ -108,7 +108,8 @@ export class InternalCallTree { } parentScope (scopeId) { - return scopeId.replace(/(.\d|\d)$/, '') + if (scopeId.indexOf('.') === -1) return '' + return scopeId.replace(/(\.\d+)$/, '') } findScopeId (vmtraceIndex) { From 7c80d0d6e1af842ab1b2ed85189791edc9c8602b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 May 2021 21:40:57 +0200 Subject: [PATCH 096/199] Warn if current is not the last version (#1161) fix https://github.com/ethereum/remix-project/issues/938 --- libs/remixd/package.json | 4 +++- libs/remixd/src/bin/remixd.ts | 16 ++++++++++++++++ package-lock.json | 20 ++++++-------------- package.json | 3 ++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libs/remixd/package.json b/libs/remixd/package.json index 607b0a7ff2..6bbfed0109 100644 --- a/libs/remixd/package.json +++ b/libs/remixd/package.json @@ -44,7 +44,9 @@ "commander": "^2.20.3", "fs-extra": "^3.0.1", "isbinaryfile": "^3.0.2", - "ws": "^7.3.0" + "ws": "^7.3.0", + "latest-version": "^5.1.0", + "semver": "^6.3.0" }, "python": { "execPath": "python3", diff --git a/libs/remixd/src/bin/remixd.ts b/libs/remixd/src/bin/remixd.ts index ae240a8cdf..5b7076fd0d 100644 --- a/libs/remixd/src/bin/remixd.ts +++ b/libs/remixd/src/bin/remixd.ts @@ -1,4 +1,6 @@ #!/usr/bin/env node +import latestVersion from 'latest-version' +import * as semver from 'semver' import WebSocket from '../websocket' import * as servicesList from '../serviceList' import * as WS from 'ws' // eslint-disable-line @@ -8,6 +10,18 @@ import * as fs from 'fs-extra' import * as path from 'path' import * as program from 'commander' +async function warnLatestVersion () { + const latest = await latestVersion('@remix-project/remixd') + const pjson = require('../package.json') + if (semver.eq(latest, pjson.version)) { + console.log('\x1b[32m%s\x1b[0m', `[INFO] you are using the latest version ${latest}`) + } else if (semver.gt(latest, pjson.version)) { + console.log('\x1b[33m%s\x1b[0m', `[WARN] latest version of remixd is ${latest}, you are using ${pjson.version}`) + console.log('\x1b[33m%s\x1b[0m', '[WARN] please update using the following command:') + console.log('\x1b[33m%s\x1b[0m', '[WARN] npm install @remix-project/remixd -g') + } +} + const services = { git: (readOnly: boolean) => new servicesList.GitClient(readOnly), folder: (readOnly: boolean) => new servicesList.Sharedfolder(readOnly) @@ -40,6 +54,8 @@ function startService (service: S, callback: (ws: WS }).parse(process.argv) // eslint-disable-next-line + await warnLatestVersion() + if (!program.remixIde) { console.log('\x1b[33m%s\x1b[0m', '[WARN] You can only connect to remixd from one of the supported origins.') } else { diff --git a/package-lock.json b/package-lock.json index b2c38f3b0f..4f92e09fa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15178,8 +15178,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", @@ -21217,8 +21216,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "init-package-json": { "version": "1.10.3", @@ -24668,7 +24666,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, "requires": { "package-json": "^6.3.0" } @@ -33827,7 +33824,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, "requires": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", @@ -35709,7 +35705,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -36217,10 +36212,9 @@ } }, "registry-auth-token": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", - "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", - "dev": true, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "requires": { "rc": "^1.2.8" } @@ -36229,7 +36223,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, "requires": { "rc": "^1.2.8" } @@ -39088,8 +39081,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "strong-log-transformer": { "version": "2.1.0", diff --git a/package.json b/package.json index bd2a0e8aa6..2587e3bfbf 100644 --- a/package.json +++ b/package.json @@ -159,6 +159,7 @@ "isbinaryfile": "^3.0.2", "jquery": "^3.3.1", "jszip": "^3.6.0", + "latest-version": "^5.1.0", "merge": "^1.2.0", "npm-install-version": "^6.0.2", "react": "16.13.1", @@ -273,7 +274,7 @@ "request": "^2.83.0", "rimraf": "^2.6.1", "selenium-standalone": "^6.17.0", - "semver": "^6.1.2", + "semver": "^6.3.0", "solc": "0.7.4", "swarmgw": "^0.3.1", "tap-spec": "^5.0.0", From 09c23bd319d54bacba35ab7d180fb79ee8d2aa3e Mon Sep 17 00:00:00 2001 From: filip mertens Date: Tue, 11 May 2021 06:12:38 +0200 Subject: [PATCH 097/199] hide errors when creating new workspace --- libs/remix-ui/file-explorer/src/lib/file-explorer.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 33bfd203fa..17f78d79fc 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -261,8 +261,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const fetchDirectoryContent = async (folderPath: string): Promise => { return new Promise((resolve) => { - filesProvider.resolveDirectory(folderPath, (error, fileTree) => { - if (error) console.error(error) + filesProvider.resolveDirectory(folderPath, (_error, fileTree) => { const files = normalize(fileTree) resolve(files) From 9c42776f27e1af8ff96844135d2bb4f59e74d6e0 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 May 2021 11:33:13 +0200 Subject: [PATCH 098/199] fix ipfs deploy of the debugger (#1170) --- apps/debugger/src/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/debugger/src/index.html b/apps/debugger/src/index.html index e44825a34e..848097620c 100644 --- a/apps/debugger/src/index.html +++ b/apps/debugger/src/index.html @@ -3,7 +3,7 @@ Debugger - + From 0284623e8f1180b5276a0a7d7d4489bb2adf6a70 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 May 2021 15:52:53 +0200 Subject: [PATCH 099/199] validate input using BigNumber --- .../remix-ide/src/app/tabs/runTab/settings.js | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index c4ee816bc8..bf32b6ec27 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -1,3 +1,4 @@ +import { BN } from 'ethereumjs-util' const $ = require('jquery') const yo = require('yo-yo') const remixLib = require('@remix-project/remix-lib') @@ -65,14 +66,19 @@ class SettingsUI { validateValue () { const valueEl = this.el.querySelector('#value') - valueEl.value = parseInt(valueEl.value) - // assign 0 if given value is - // - empty - // - not valid (for ex 4345-54) - // - contains only '0's (for ex 0000) copy past or edit - if (!valueEl.value) valueEl.value = 0 + let v + try { + v = new BN(valueEl.value, 10) + } catch (e) { + // assign 0 if given value is + // - empty + // - not valid (for ex 4345-54) + // - contains only '0's (for ex 0000) copy past or edit + valueEl.value = 0 + } + // if giveen value is negative(possible with copy-pasting) set to 0 - if (valueEl.value < 0) valueEl.value = 0 + if (v.lt(0)) valueEl.value = 0 } render () { From b84a0086b0d9659d332550bf6bdf4a80c1807f43 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 May 2021 22:09:38 +0200 Subject: [PATCH 100/199] use BN --- libs/remix-lib/src/execution/txRunner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-lib/src/execution/txRunner.ts b/libs/remix-lib/src/execution/txRunner.ts index ddc2456fb5..2606fcc01d 100644 --- a/libs/remix-lib/src/execution/txRunner.ts +++ b/libs/remix-lib/src/execution/txRunner.ts @@ -118,7 +118,7 @@ export class TxRunner { this.executionContext.vm().stateManager.getAccount(Address.fromString(from)).then((res) => { // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor // for initialization fields and their types - value = value ? parseInt(value) : 0 + value = value ? new BN(value, 10) : 0 const tx = Transaction.fromTxData({ nonce: new BN(res.nonce), gasPrice: '0x1', From e6ab097779d0104cd8e1b0494c7b601cf651e96b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 10 May 2021 22:36:53 +0200 Subject: [PATCH 101/199] linting --- apps/remix-ide/src/app/tabs/runTab/settings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index bf32b6ec27..cb98a4fedc 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -75,8 +75,8 @@ class SettingsUI { // - not valid (for ex 4345-54) // - contains only '0's (for ex 0000) copy past or edit valueEl.value = 0 - } - + } + // if giveen value is negative(possible with copy-pasting) set to 0 if (v.lt(0)) valueEl.value = 0 } From 3dbc10c0caf6a3320b65d55a216b485937487628 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 May 2021 10:30:36 +0200 Subject: [PATCH 102/199] handle hex --- libs/remix-lib/src/execution/txRunner.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/remix-lib/src/execution/txRunner.ts b/libs/remix-lib/src/execution/txRunner.ts index 2606fcc01d..ff514d437b 100644 --- a/libs/remix-lib/src/execution/txRunner.ts +++ b/libs/remix-lib/src/execution/txRunner.ts @@ -118,7 +118,17 @@ export class TxRunner { this.executionContext.vm().stateManager.getAccount(Address.fromString(from)).then((res) => { // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor // for initialization fields and their types - value = value ? new BN(value, 10) : 0 + if (!value) value = 0 + if (typeof value === 'string') { + if (value.startsWith('0x')) value = new BN(value.replace('0x', ''), 'hex') + else { + try { + value = new BN(value, 10) + } catch (e) { + return callback('Unable to parse the value ' + e.message) + } + } + } const tx = Transaction.fromTxData({ nonce: new BN(res.nonce), gasPrice: '0x1', From 5292526633392507f4c55bd22d3d5b5672cf6790 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 May 2021 10:37:55 +0200 Subject: [PATCH 103/199] linting --- libs/remix-lib/src/execution/txRunner.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-lib/src/execution/txRunner.ts b/libs/remix-lib/src/execution/txRunner.ts index ff514d437b..498f6ece11 100644 --- a/libs/remix-lib/src/execution/txRunner.ts +++ b/libs/remix-lib/src/execution/txRunner.ts @@ -120,14 +120,14 @@ export class TxRunner { // for initialization fields and their types if (!value) value = 0 if (typeof value === 'string') { - if (value.startsWith('0x')) value = new BN(value.replace('0x', ''), 'hex') + if (value.startsWith('0x')) value = new BN(value.replace('0x', ''), 'hex') else { try { value = new BN(value, 10) } catch (e) { return callback('Unable to parse the value ' + e.message) } - } + } } const tx = Transaction.fromTxData({ nonce: new BN(res.nonce), From 9411dec11cec0bdab4a4891825a660658c7cc2fb Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 May 2021 11:09:37 +0200 Subject: [PATCH 104/199] fix e2e --- apps/remix-ide/src/app/tabs/runTab/settings.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index cb98a4fedc..634605dec4 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -66,12 +66,18 @@ class SettingsUI { validateValue () { const valueEl = this.el.querySelector('#value') + if (!valueEl.value) { + // assign 0 if given value is + // - empty + valueEl.value = 0 + return + } + let v try { v = new BN(valueEl.value, 10) } catch (e) { // assign 0 if given value is - // - empty // - not valid (for ex 4345-54) // - contains only '0's (for ex 0000) copy past or edit valueEl.value = 0 From a00d13500e663e4c736b6b8d2dbe0a8c48ebf151 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 11 May 2021 12:31:03 +0200 Subject: [PATCH 105/199] set input value --- apps/remix-ide/src/app/tabs/runTab/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index 634605dec4..4cc9ff4f00 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -76,6 +76,7 @@ class SettingsUI { let v try { v = new BN(valueEl.value, 10) + valueEl.value = v.toString(10) } catch (e) { // assign 0 if given value is // - not valid (for ex 4345-54) From 44eac57b930745a781c49c922687b0e98665dc86 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 14 Jan 2021 10:57:52 +0100 Subject: [PATCH 106/199] refactor_send_txs --- apps/remix-ide/src/app/tabs/network-module.js | 12 - .../src/app/tabs/runTab/model/recorder.js | 4 +- apps/remix-ide/src/blockchain/blockchain.js | 69 ++-- apps/remix-ide/src/blockchain/providers/vm.js | 8 +- .../src/blockchain/txResultHelper.js | 46 --- jest.config.js | 15 +- .../src/execution/execution-context.ts | 36 +- libs/remix-lib/src/execution/txExecution.ts | 10 +- libs/remix-lib/src/execution/txFormat.ts | 2 +- libs/remix-lib/src/execution/txListener.ts | 37 +- libs/remix-lib/src/execution/txRunner.ts | 252 +----------- libs/remix-lib/src/execution/txRunnerVM.ts | 120 ++++++ libs/remix-lib/src/execution/txRunnerWeb3.ts | 156 +++++++ libs/remix-lib/src/helpers/txResultHelper.ts | 8 +- libs/remix-lib/src/index.ts | 18 +- libs/remix-lib/src/universalDapp.ts | 379 ------------------ .../src/web3Provider/web3VmProvider.ts | 6 + libs/remix-lib/test/txFormat.ts | 4 +- libs/remix-lib/test/txResultHelper.ts | 37 +- libs/remix-simulator/src/genesis.ts | 8 +- libs/remix-simulator/src/index.ts | 2 +- libs/remix-simulator/src/methods/accounts.ts | 16 +- libs/remix-simulator/src/methods/blocks.ts | 18 +- libs/remix-simulator/src/methods/debug.ts | 12 +- libs/remix-simulator/src/methods/filters.ts | 24 +- .../src/methods/transactions.ts | 69 +++- libs/remix-simulator/src/methods/txProcess.ts | 25 +- libs/remix-simulator/src/provider.ts | 57 ++- libs/remix-simulator/src/vm-context.ts | 147 +++++++ libs/remix-tests/jest.config.js | 4 +- libs/remix-tests/src/deployer.ts | 2 +- libs/remix-tests/tests/testRunner.cli.spec.ts | 8 +- libs/remix-tests/tsconfig.json | 2 +- libs/remix-tests/tsconfig.lib.json | 27 +- libs/remix-tests/tsconfig.spec.json | 29 +- 35 files changed, 770 insertions(+), 899 deletions(-) delete mode 100644 apps/remix-ide/src/blockchain/txResultHelper.js create mode 100644 libs/remix-lib/src/execution/txRunnerVM.ts create mode 100644 libs/remix-lib/src/execution/txRunnerWeb3.ts delete mode 100644 libs/remix-lib/src/universalDapp.ts create mode 100644 libs/remix-simulator/src/vm-context.ts diff --git a/apps/remix-ide/src/app/tabs/network-module.js b/apps/remix-ide/src/app/tabs/network-module.js index fdae172c15..c1cc1e12b5 100644 --- a/apps/remix-ide/src/app/tabs/network-module.js +++ b/apps/remix-ide/src/app/tabs/network-module.js @@ -22,18 +22,6 @@ export class NetworkModule extends Plugin { this.blockchain.event.register('contextChanged', (provider) => { this.emit('providerChanged', provider) }) - /* - // Events that could be implemented later - executionContext.event.register('removeProvider', (provider) => { - this.events.emit('networkRemoved', provider) - }) - executionContext.event.register('addProvider', (provider) => { - this.events.emit('networkAdded', provider) - }) - executionContext.event.register('web3EndpointChanged', (provider) => { - this.events.emit('web3EndpointChanged', provider) - }) - */ } /** Return the current network provider (web3, vm, injected) */ diff --git a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js index 126b354927..f9a5d9aa78 100644 --- a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js +++ b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js @@ -63,10 +63,10 @@ class Recorder { } }) - this.blockchain.event.register('transactionExecuted', (error, from, to, data, call, txResult, timestamp, _payload, rawAddress) => { + this.blockchain.event.register('transactionExecuted', (error, from, to, data, call, txResult, timestamp, _payload) => { if (error) return console.log(error) if (call) return - + const rawAddress = txResult.receipt.contractAddress if (!rawAddress) return // not a contract creation const address = helper.addressToString(rawAddress) // save back created addresses for the convertion from tokens to real adresses diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 84062f7ac4..09ca8a05a2 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -3,7 +3,8 @@ const txFormat = remixLib.execution.txFormat const txExecution = remixLib.execution.txExecution const typeConversion = remixLib.execution.typeConversion const Txlistener = remixLib.execution.txListener -const TxRunner = remixLib.execution.txRunner +const TxRunner = remixLib.execution.TxRunner +const TxRunnerWeb3 = remixLib.execution.TxRunnerWeb3 const txHelper = remixLib.execution.txHelper const EventManager = remixLib.EventManager const executionContext = remixLib.execution.executionContext @@ -12,7 +13,7 @@ const Web3 = require('web3') const async = require('async') const { EventEmitter } = require('events') -const { resultToRemixTx } = require('./txResultHelper') +const { resultToRemixTx } = remixLib.helpers.txResultHelper const VMProvider = require('./providers/vm.js') const InjectedProvider = require('./providers/injected.js') @@ -26,8 +27,7 @@ class Blockchain { this.events = new EventEmitter() this.config = config - - this.txRunner = new TxRunner({}, { + const web3Runner = new TxRunnerWeb3({ config: config, detectNetwork: (cb) => { this.executionContext.detectNetwork(cb) @@ -35,7 +35,9 @@ class Blockchain { personalMode: () => { return this.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false } - }, this.executionContext) + }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) + this.txRunner = new TxRunner(web3Runner, { runAsync: true }) + this.executionContext.event.register('contextChanged', this.resetEnvironment.bind(this)) this.networkcallid = 0 @@ -123,7 +125,7 @@ class Blockchain { if (error) { return finalCb(`creation of ${selectedContract.name} errored: ${(error.message ? error.message : error)}`) } - if (txResult.result.status && txResult.result.status === '0x0') { + if (txResult.receipt.status === false || txResult.receipt.status === '0x0') { return finalCb(`creation of ${selectedContract.name} errored: transaction execution failed`) } finalCb(null, selectedContract, address) @@ -309,18 +311,17 @@ class Blockchain { resetEnvironment () { this.getCurrentProvider().resetEnvironment() // TODO: most params here can be refactored away in txRunner - // this.txRunner = new TxRunner(this.providers.vm.accounts, { - this.txRunner = new TxRunner(this.providers.vm.RemixSimulatorProvider.Accounts.accounts, { - // TODO: only used to check value of doNotShowTransactionConfirmationAgain property + const web3Runner = new TxRunnerWeb3({ config: this.config, - // TODO: to refactor, TxRunner already has access to executionContext detectNetwork: (cb) => { this.executionContext.detectNetwork(cb) }, personalMode: () => { return this.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false } - }, this.executionContext) + }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) + + this.txRunner = new TxRunner(web3Runner, { runAsync: true }) this.txRunner.event.register('transactionBroadcasted', (txhash) => { this.executionContext.detectNetwork((error, network) => { if (error || !network) return @@ -372,10 +373,11 @@ class Blockchain { (network, tx, gasEstimation, continueTxExecution, cancelCb) => { continueTxExecution() }, (error, continueTxExecution, cancelCb) => { if (error) { reject(error) } else { continueTxExecution() } }, (okCb, cancelCb) => { okCb() }, - (error, result) => { + async (error, result) => { if (error) return reject(error) try { - resolve(resultToRemixTx(result)) + const execResult = await this.web3().eth.getExecutionResultFromSimulator(result.transactionHash) + resolve(resultToRemixTx(result, execResult)) } catch (e) { reject(e) } @@ -429,19 +431,24 @@ class Blockchain { function runTransaction (fromAddress, value, gasLimit, next) { const tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: fromAddress, value: value, gasLimit: gasLimit, timestamp: args.data.timestamp } const payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName, contractABI: args.data.contractABI, linkReferences: args.data.linkReferences } - let timestamp = Date.now() - if (tx.timestamp) { - timestamp = tx.timestamp - } + if (!tx.timestamp) tx.timestamp = Date.now() + const timestamp = tx.timestamp self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) self.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb, - function (error, result) { + async (error, result) => { if (error) return next(error) - const rawAddress = self.executionContext.isVM() ? (result.result.createdAddress && result.result.createdAddress.toBuffer()) : result.result.contractAddress + const isVM = self.executionContext.isVM() + if (isVM && tx.useCall) { + try { + result.transactionHash = await self.web3().eth.getHashFromTagBySimulator(timestamp) + } catch (e) { + console.log('unable to retrieve back the "call" hash', e) + } + } const eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') - self.event.trigger(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad, rawAddress]) + self.event.trigger(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) if (error && (typeof (error) !== 'string')) { if (error.message) error = error.message @@ -454,25 +461,29 @@ class Blockchain { ) } ], - (error, txResult) => { + async (error, txResult) => { if (error) { return cb(error) } const isVM = this.executionContext.isVM() + let execResult + let returnValue = null if (isVM) { - const vmError = txExecution.checkVMError(txResult) - if (vmError.error) { - return cb(vmError.message) + execResult = await this.web3().eth.getExecutionResultFromSimulator(txResult.transactionHash) + if (execResult) { + // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. + returnValue = (execResult && isVM) ? execResult.returnValue : txResult + const vmError = txExecution.checkVMError(execResult) + if (vmError.error) { + return cb(vmError.message) + } } } let address = null - let returnValue = null - if (txResult && txResult.result) { - address = isVM ? (txResult.result.createdAddress && txResult.result.createdAddress.toBuffer()) : txResult.result.contractAddress - // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. - returnValue = (txResult.result.execResult && isVM) ? txResult.result.execResult.returnValue : txResult.result + if (txResult && txResult.receipt) { + address = txResult.receipt.contractAddress } cb(error, txResult, address, returnValue) diff --git a/apps/remix-ide/src/blockchain/providers/vm.js b/apps/remix-ide/src/blockchain/providers/vm.js index 8ec6583ff7..c251743e2b 100644 --- a/apps/remix-ide/src/blockchain/providers/vm.js +++ b/apps/remix-ide/src/blockchain/providers/vm.js @@ -1,14 +1,16 @@ const Web3 = require('web3') -const { BN, privateToAddress, hashPersonalMessage } = require('ethereumjs-util') -const RemixSimulator = require('@remix-project/remix-simulator') +const { BN, privateToAddress, stripHexPrefix, hashPersonalMessage } = require('ethereumjs-util') +const { Provider, extend } = require('@remix-project/remix-simulator') class VMProvider { constructor (executionContext) { this.executionContext = executionContext - this.RemixSimulatorProvider = new RemixSimulator.Provider({ executionContext: this.executionContext }) + this.RemixSimulatorProvider = new Provider({}) this.RemixSimulatorProvider.init() this.web3 = new Web3(this.RemixSimulatorProvider) + extend(this.web3) this.accounts = {} + this.executionContext.setWeb3('vm', this.web3) } getAccounts (cb) { diff --git a/apps/remix-ide/src/blockchain/txResultHelper.js b/apps/remix-ide/src/blockchain/txResultHelper.js deleted file mode 100644 index f608324062..0000000000 --- a/apps/remix-ide/src/blockchain/txResultHelper.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' -const { bufferToHex, isHexString } = require('ethereumjs-util') - -function convertToPrefixedHex (input) { - if (input === undefined || input === null || isHexString(input)) { - return input - } else if (Buffer.isBuffer(input)) { - return bufferToHex(input) - } - return '0x' + input.toString(16) -} - -/* - txResult.result can be 3 different things: - - VM call or tx: ethereumjs-vm result object - - Node transaction: object returned from eth.getTransactionReceipt() - - Node call: return value from function call (not an object) - - Also, VM results use BN and Buffers, Node results use hex strings/ints, - So we need to normalize the values to prefixed hex strings -*/ -function resultToRemixTx (txResult) { - const { result, transactionHash } = txResult - const { status, execResult, gasUsed, createdAddress, contractAddress } = result - let returnValue, errorMessage - - if (isHexString(result)) { - returnValue = result - } else if (execResult !== undefined) { - returnValue = execResult.returnValue - errorMessage = execResult.exceptionError - } - - return { - transactionHash, - status, - gasUsed: convertToPrefixedHex(gasUsed), - error: errorMessage, - return: convertToPrefixedHex(returnValue), - createdAddress: convertToPrefixedHex(createdAddress || contractAddress) - } -} - -module.exports = { - resultToRemixTx -} diff --git a/jest.config.js b/jest.config.js index 30b91f3cbe..4b90409756 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,5 +5,18 @@ module.exports = { }, resolver: '@nrwl/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'html'], - coverageReporters: ['html'] + coverageReporters: ['html'], + moduleNameMapper:{ + "@remix-project/remix-analyzer": "/../../dist/libs/remix-analyzer/index.js", + "@remix-project/remix-astwalker": "/../../dist/libs/remix-astwalker/index.js", + "@remix-project/remix-debug": "/../../dist/libs/remix-debug/src/index.js", + "@remix-project/remix-lib": "/../../dist/libs/remix-lib/src/index.js", + "@remix-project/remix-simulator": "/../../dist/libs/remix-simulator/src/index.js", + "@remix-project/remix-solidity": "/../../dist/libs/remix-solidity/index.js", + "@remix-project/remix-tests": "/../../dist/libs/remix-tests/src/index.js", + "@remix-project/remix-url-resolver": + "/../../dist/libs/remix-url-resolver/index.js" + , + "@remix-project/remixd": "/../../dist/libs/remixd/index.js" + } }; diff --git a/libs/remix-lib/src/execution/execution-context.ts b/libs/remix-lib/src/execution/execution-context.ts index 31212412ff..ba067e7035 100644 --- a/libs/remix-lib/src/execution/execution-context.ts +++ b/libs/remix-lib/src/execution/execution-context.ts @@ -4,7 +4,6 @@ import Web3 from 'web3' import { EventManager } from '../eventManager' import { rlp, keccak, bufferToHex } from 'ethereumjs-util' import { Web3VmProvider } from '../web3Provider/web3VmProvider' -import { LogsManager } from './logsManager' import VM from '@ethereumjs/vm' import Common from '@ethereumjs/common' import StateManager from '@ethereumjs/vm/dist/state/stateManager' @@ -100,22 +99,21 @@ class StateManagerCommonStorageDump extends StateManager { */ export class ExecutionContext { event - logsManager - blockGasLimitDefault - blockGasLimit + blockGasLimitDefault: number + blockGasLimit: number customNetWorks blocks latestBlockNumber txs - executionContext + executionContext: string listenOnLastBlockId currentFork: string vms mainNetGenesisHash: string + customWeb3: { [key: string]: Web3 } constructor () { this.event = new EventManager() - this.logsManager = new LogsManager() this.executionContext = null this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault @@ -134,6 +132,7 @@ export class ExecutionContext { this.blocks = {} this.latestBlockNumber = 0 this.txs = {} + this.customWeb3 = {} // mapping between a context name and a web3.js instance } init (config) { @@ -172,7 +171,12 @@ export class ExecutionContext { return this.executionContext === 'vm' } + setWeb3 (context: string, web3: Web3) { + this.customWeb3[context] = web3 + } + web3 () { + if (this.customWeb3[this.executionContext]) return this.customWeb3[this.executionContext] return this.isVM() ? this.vms[this.currentFork].web3vm : web3 } @@ -339,23 +343,5 @@ export class ExecutionContext { if (transactionDetailsLinks[network]) { return transactionDetailsLinks[network] + hash } - } - - addBlock (block) { - let blockNumber = '0x' + block.header.number.toString('hex') - if (blockNumber === '0x') { - blockNumber = '0x0' - } - blockNumber = web3.utils.toHex(web3.utils.toBN(blockNumber)) - - this.blocks['0x' + block.hash().toString('hex')] = block - this.blocks[blockNumber] = block - this.latestBlockNumber = blockNumber - - this.logsManager.checkBlock(blockNumber, block, this.web3()) - } - - trackTx (tx, block) { - this.txs[tx] = block - } + } } diff --git a/libs/remix-lib/src/execution/txExecution.ts b/libs/remix-lib/src/execution/txExecution.ts index 84edfc1f8e..8eb1c927dd 100644 --- a/libs/remix-lib/src/execution/txExecution.ts +++ b/libs/remix-lib/src/execution/txExecution.ts @@ -53,10 +53,10 @@ export function callFunction (from, to, data, value, gasLimit, funAbi, txRunner, /** * check if the vm has errored * - * @param {Object} txResult - the value returned by the vm + * @param {Object} execResult - execution result given by the VM * @return {Object} - { error: true/false, message: DOMNode } */ -export function checkVMError (txResult) { +export function checkVMError (execResult) { const errorCode = { OUT_OF_GAS: 'out of gas', STACK_UNDERFLOW: 'stack underflow', @@ -74,10 +74,10 @@ export function checkVMError (txResult) { error: false, message: '' } - if (!txResult.result.execResult.exceptionError) { + if (!execResult.exceptionError) { return ret } - const exceptionError = txResult.result.execResult.exceptionError.error || '' + const exceptionError = execResult.exceptionError.error || '' const error = `VM error: ${exceptionError}.\n` let msg if (exceptionError === errorCode.INVALID_OPCODE) { @@ -87,7 +87,7 @@ export function checkVMError (txResult) { msg = '\tThe transaction ran out of gas. Please increase the Gas Limit.\n' ret.error = true } else if (exceptionError === errorCode.REVERT) { - const returnData = txResult.result.execResult.returnValue + const returnData = execResult.returnValue // It is the hash of Error(string) if (returnData && (returnData.slice(0, 4).toString('hex') === '08c379a0')) { const abiCoder = new ethers.utils.AbiCoder() diff --git a/libs/remix-lib/src/execution/txFormat.ts b/libs/remix-lib/src/execution/txFormat.ts index 7d3188a1d0..62f90be1a8 100644 --- a/libs/remix-lib/src/execution/txFormat.ts +++ b/libs/remix-lib/src/execution/txFormat.ts @@ -314,7 +314,7 @@ export function deployLibrary (libraryName, libraryShortName, library, contracts if (err) { return callback(err) } - const address = txResult.result.createdAddress || txResult.result.contractAddress + const address = txResult.receipt.contractAddress library.address = address callback(err, address) }) diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index fea5cdf270..967b8ee3a8 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -8,13 +8,13 @@ import { ExecutionContext } from './execution-context' import { decodeResponse } from './txFormat' import { getFunction, getReceiveInterface, getConstructorInterface, visitContracts, makeFullTypeDefinition } from './txHelper' -function addExecutionCosts (txResult, tx) { - if (txResult && txResult.result) { - if (txResult.result.execResult) { - tx.returnValue = txResult.result.execResult.returnValue - if (txResult.result.execResult.gasUsed) tx.executionCost = txResult.result.execResult.gasUsed.toString(10) +function addExecutionCosts (txResult, tx, execResult) { + if (txResult) { + if (execResult) { + tx.returnValue = execResult.returnValue + if (execResult.gasUsed) tx.executionCost = execResult.gasUsed.toString(10) } - if (txResult.result.gasUsed) tx.transactionCost = txResult.result.gasUsed.toString(10) + if (txResult.receipt && txResult.receipt.gasUsed) tx.transactionCost = txResult.receipt.gasUsed.toString(10) } } @@ -55,7 +55,7 @@ export class TxListener { } }) - opt.event.udapp.register('callExecuted', (error, from, to, data, lookupOnly, txResult) => { + opt.event.udapp.register('callExecuted', async (error, from, to, data, lookupOnly, txResult) => { if (error) return // we go for that case if // in VM mode @@ -63,17 +63,25 @@ export class TxListener { if (!this._isListening) return // we don't listen if (this._loopId && this.executionContext.getProvider() !== 'vm') return // we seems to already listen on a "web3" network + let returnValue + let execResult + if (this.executionContext.isVM()) { + execResult = await this.executionContext.web3().eth.getExecutionResultFromSimulator(txResult.transactionHash) + returnValue = execResult.returnValue + } else { + returnValue = toBuffer(txResult.result) + } const call = { from: from, to: to, input: data, hash: txResult.transactionHash ? txResult.transactionHash : 'call' + (from || '') + to + data, isCall: true, - returnValue: this.executionContext.isVM() ? txResult.result.execResult.returnValue : toBuffer(txResult.result), + returnValue, envMode: this.executionContext.getProvider() } - addExecutionCosts(txResult, call) + addExecutionCosts(txResult, call, execResult) this._resolveTx(call, call, (error, resolvedData) => { if (!error) { this.event.trigger('newCall', [call]) @@ -89,12 +97,17 @@ export class TxListener { // in web3 mode && listen remix txs only if (!this._isListening) return // we don't listen if (this._loopId && this.executionContext.getProvider() !== 'vm') return // we seems to already listen on a "web3" network - this.executionContext.web3().eth.getTransaction(txResult.transactionHash, (error, tx) => { + this.executionContext.web3().eth.getTransaction(txResult.transactionHash, async (error, tx) => { if (error) return console.log(error) - addExecutionCosts(txResult, tx) + let execResult + if (this.executionContext.isVM()) { + execResult = await this.executionContext.web3().eth.getExecutionResultFromSimulator(txResult.transactionHash) + } + + addExecutionCosts(txResult, tx, execResult) tx.envMode = this.executionContext.getProvider() - tx.status = txResult.result.status // 0x0 or 0x1 + tx.status = txResult.receipt.status // 0x0 or 0x1 this._resolve([tx], () => { }) }) diff --git a/libs/remix-lib/src/execution/txRunner.ts b/libs/remix-lib/src/execution/txRunner.ts index ddc2456fb5..254b4b0474 100644 --- a/libs/remix-lib/src/execution/txRunner.ts +++ b/libs/remix-lib/src/execution/txRunner.ts @@ -1,91 +1,26 @@ 'use strict' -import { Transaction } from '@ethereumjs/tx' -import { Block } from '@ethereumjs/block' -import { BN, bufferToHex, Address } from 'ethereumjs-util' -import { ExecutionContext } from './execution-context' import { EventManager } from '../eventManager' export class TxRunner { event - executionContext - _api - blockNumber runAsync pendingTxs - vmaccounts queusTxs - blocks - commonContext - - constructor (vmaccounts, api, executionContext) { + opt + internalRunner + constructor (internalRunner, opt) { + this.opt = opt || {} + this.internalRunner = internalRunner this.event = new EventManager() - // has a default for now for backwards compatability - this.executionContext = executionContext || new ExecutionContext() - this.commonContext = this.executionContext.vmObject().common - this._api = api - this.blockNumber = 0 - this.runAsync = true - if (this.executionContext.isVM()) { - // this.blockNumber = 1150000 // The VM is running in Homestead mode, which started at this block. - this.blockNumber = 0 // The VM is running in Homestead mode, which started at this block. - this.runAsync = false // We have to run like this cause the VM Event Manager does not support running multiple txs at the same time. - } + + this.runAsync = this.opt.runAsync || true // We have to run like this cause the VM Event Manager does not support running multiple txs at the same time. + this.pendingTxs = {} - this.vmaccounts = vmaccounts this.queusTxs = [] - this.blocks = [] } rawRun (args, confirmationCb, gasEstimationForceSend, promptCb, cb) { - let timestamp = Date.now() - if (args.timestamp) { - timestamp = args.timestamp - } - run(this, args, timestamp, confirmationCb, gasEstimationForceSend, promptCb, cb) - } - - _executeTx (tx, gasPrice, api, promptCb, callback) { - if (gasPrice) tx.gasPrice = this.executionContext.web3().utils.toHex(gasPrice) - if (api.personalMode()) { - promptCb( - (value) => { - this._sendTransaction(this.executionContext.web3().personal.sendTransaction, tx, value, callback) - }, - () => { - return callback('Canceled by user.') - } - ) - } else { - this._sendTransaction(this.executionContext.web3().eth.sendTransaction, tx, null, callback) - } - } - - _sendTransaction (sendTx, tx, pass, callback) { - const cb = (err, resp) => { - if (err) { - return callback(err, resp) - } - this.event.trigger('transactionBroadcasted', [resp]) - var listenOnResponse = () => { - // eslint-disable-next-line no-async-promise-executor - return new Promise(async (resolve, reject) => { - const result = await tryTillReceiptAvailable(resp, this.executionContext) - tx = await tryTillTxAvailable(resp, this.executionContext) - resolve({ - result, - tx, - transactionHash: result ? result['transactionHash'] : null - }) - }) - } - listenOnResponse().then((txData) => { callback(null, txData) }).catch((error) => { callback(error) }) - } - const args = pass !== null ? [tx, pass, cb] : [tx, cb] - try { - sendTx.apply({}, args) - } catch (e) { - return callback(`Send transaction failed: ${e.message} . if you use an injected provider, please check it is properly unlocked. `) - } + run(this, args, args.timestamp || Date.now(), confirmationCb, gasEstimationForceSend, promptCb, cb) } execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) { @@ -93,175 +28,10 @@ export class TxRunner { if (data.slice(0, 2) !== '0x') { data = '0x' + data } - - if (!this.executionContext.isVM()) { - return this.runInNode(args.from, args.to, data, args.value, args.gasLimit, args.useCall, confirmationCb, gasEstimationForceSend, promptCb, callback) - } - try { - this.runInVm(args.from, args.to, data, args.value, args.gasLimit, args.useCall, args.timestamp, callback) - } catch (e) { - callback(e, null) - } + this.internalRunner.execute(args, confirmationCb, gasEstimationForceSend, promptCb, callback) } - - runInVm (from, to, data, value, gasLimit, useCall, timestamp, callback) { - const self = this - const account = self.vmaccounts[from] - if (!account) { - return callback('Invalid account selected') - } - - if (Number.isInteger(gasLimit)) { - gasLimit = '0x' + gasLimit.toString(16) - } - - this.executionContext.vm().stateManager.getAccount(Address.fromString(from)).then((res) => { - // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor - // for initialization fields and their types - value = value ? parseInt(value) : 0 - const tx = Transaction.fromTxData({ - nonce: new BN(res.nonce), - gasPrice: '0x1', - gasLimit: gasLimit, - to: to, - value: value, - data: Buffer.from(data.slice(2), 'hex') - }, { common: this.commonContext }).sign(account.privateKey) - - const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] - const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] - - var block = Block.fromBlockData({ - header: { - timestamp: timestamp || (new Date().getTime() / 1000 | 0), - number: self.blockNumber, - coinbase: coinbases[self.blockNumber % coinbases.length], - difficulty: difficulties[self.blockNumber % difficulties.length], - gasLimit: new BN(gasLimit.replace('0x', ''), 16).imuln(2) - }, - transactions: [tx] - }, { common: this.commonContext }) - - if (!useCall) { - ++self.blockNumber - this.runBlockInVm(tx, block, callback) - } else { - this.executionContext.vm().stateManager.checkpoint().then(() => { - this.runBlockInVm(tx, block, (err, result) => { - this.executionContext.vm().stateManager.revert().then(() => { - callback(err, result) - }) - }) - }) - } - }).catch((e) => { - callback(e) - }) - } - - runBlockInVm (tx, block, callback) { - this.executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then((results) => { - const result = results.results[0] - if (result) { - const status = result.execResult.exceptionError ? 0 : 1 - result.status = `0x${status}` - } - this.executionContext.addBlock(block) - this.executionContext.trackTx('0x' + tx.hash().toString('hex'), block) - callback(null, { - result: result, - transactionHash: bufferToHex(Buffer.from(tx.hash())) - }) - }).catch((err) => { - callback(err) - }) - } - - runInNode (from, to, data, value, gasLimit, useCall, confirmCb, gasEstimationForceSend, promptCb, callback) { - const tx = { from: from, to: to, data: data, value: value } - - if (useCall) { - tx['gas'] = gasLimit - return this.executionContext.web3().eth.call(tx, function (error, result) { - callback(error, { - result: result, - transactionHash: result ? result.transactionHash : null - }) - }) - } - this.executionContext.web3().eth.estimateGas(tx, (err, gasEstimation) => { - if (err && err.message.indexOf('Invalid JSON RPC response') !== -1) { - // // @todo(#378) this should be removed when https://github.com/WalletConnect/walletconnect-monorepo/issues/334 is fixed - err = 'Gas estimation failed because of an unknown internal error. This may indicated that the transaction will fail.' - } - gasEstimationForceSend(err, () => { - // callback is called whenever no error - tx['gas'] = !gasEstimation ? gasLimit : gasEstimation - - if (this._api.config.getUnpersistedProperty('doNotShowTransactionConfirmationAgain')) { - return this._executeTx(tx, null, this._api, promptCb, callback) - } - - this._api.detectNetwork((err, network) => { - if (err) { - console.log(err) - return - } - - confirmCb(network, tx, tx['gas'], (gasPrice) => { - return this._executeTx(tx, gasPrice, this._api, promptCb, callback) - }, (error) => { - callback(error) - }) - }) - }, () => { - const blockGasLimit = this.executionContext.currentblockGasLimit() - // NOTE: estimateGas very likely will return a large limit if execution of the code failed - // we want to be able to run the code in order to debug and find the cause for the failure - if (err) return callback(err) - - let warnEstimation = ' An important gas estimation might also be the sign of a problem in the contract code. Please check loops and be sure you did not sent value to a non payable function (that\'s also the reason of strong gas estimation). ' - warnEstimation += ' ' + err - - if (gasEstimation > gasLimit) { - return callback('Gas required exceeds limit: ' + gasLimit + '. ' + warnEstimation) - } - if (gasEstimation > blockGasLimit) { - return callback('Gas required exceeds block gas limit: ' + gasLimit + '. ' + warnEstimation) - } - }) - }) - } -} - -async function tryTillReceiptAvailable (txhash, executionContext) { - return new Promise((resolve, reject) => { - executionContext.web3().eth.getTransactionReceipt(txhash, async (err, receipt) => { - if (err || !receipt) { - // Try again with a bit of delay if error or if result still null - await pause() - return resolve(await tryTillReceiptAvailable(txhash, executionContext)) - } - return resolve(receipt) - }) - }) } -async function tryTillTxAvailable (txhash, executionContext) { - return new Promise((resolve, reject) => { - executionContext.web3().eth.getTransaction(txhash, async (err, tx) => { - if (err || !tx) { - // Try again with a bit of delay if error or if result still null - await pause() - return resolve(await tryTillTxAvailable(txhash, executionContext)) - } - return resolve(tx) - }) - }) -} - -async function pause () { return new Promise((resolve, reject) => { setTimeout(resolve, 500) }) } - function run (self, tx, stamp, confirmationCb, gasEstimationForceSend = null, promptCb = null, callback = null) { if (!self.runAsync && Object.keys(self.pendingTxs).length) { return self.queusTxs.push({ tx, stamp, callback }) @@ -275,4 +45,4 @@ function run (self, tx, stamp, confirmationCb, gasEstimationForceSend = null, pr run(self, next.tx, next.stamp, next.callback) } }) -} +} \ No newline at end of file diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts new file mode 100644 index 0000000000..3b221f8b75 --- /dev/null +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -0,0 +1,120 @@ +'use strict' +import { Transaction } from 'ethereumjs-tx' +import Block from 'ethereumjs-block' +import { BN, bufferToHex } from 'ethereumjs-util' +import { EventManager } from '../eventManager' +import { LogsManager } from './logsManager' + +export class TxRunnerVM { + event + _api + blockNumber + runAsync + pendingTxs + vmaccounts + queusTxs + blocks + txs + logsManager + getVM: () => any + + constructor (vmaccounts, api, getVM) { + this.event = new EventManager() + this.logsManager = new LogsManager() + // has a default for now for backwards compatability + this.getVM = getVM + this._api = api + this.blockNumber = 0 + this.runAsync = true + this.blockNumber = 0 // The VM is running in Homestead mode, which started at this block. + this.runAsync = false // We have to run like this cause the VM Event Manager does not support running multiple txs at the same time. + this.pendingTxs = {} + this.vmaccounts = vmaccounts + this.queusTxs = [] + this.blocks = [] + } + + execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) { + let data = args.data + if (data.slice(0, 2) !== '0x') { + data = '0x' + data + } + + try { + this.runInVm(args.from, args.to, data, args.value, args.gasLimit, args.useCall, args.timestamp, callback) + } catch (e) { + callback(e, null) + } + } + + runInVm (from, to, data, value, gasLimit, useCall, timestamp, callback) { + const self = this + const account = self.vmaccounts[from] + if (!account) { + return callback('Invalid account selected') + } + + this.getVM().stateManager.getAccount(Buffer.from(from.replace('0x', ''), 'hex'), (err, res) => { + if (err) { + callback('Account not found') + } else { + // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor + // for initialization fields and their types + value = value ? parseInt(value) : 0 + const tx = new Transaction({ + nonce: new BN(res.nonce), + gasPrice: '0x1', + gasLimit: gasLimit, + to: to, + value: value, + data: Buffer.from(data.slice(2), 'hex') + }) + tx.sign(account.privateKey) + const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] + const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] + const block = new Block({ + header: { + timestamp: timestamp || (new Date().getTime() / 1000 | 0), + number: self.blockNumber, + coinbase: coinbases[self.blockNumber % coinbases.length], + difficulty: difficulties[self.blockNumber % difficulties.length], + gasLimit: new BN(gasLimit, 10).imuln(2) + }, + transactions: [tx], + uncleHeaders: [] + }) + if (!useCall) { + ++self.blockNumber + this.runBlockInVm(tx, block, callback) + } else { + this.getVM().stateManager.checkpoint(() => { + this.runBlockInVm(tx, block, (err, result) => { + this.getVM().stateManager.revert(() => { + callback(err, result) + }) + }) + }) + } + } + }) + } + + runBlockInVm (tx, block, callback) { + this.getVM().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then((results) => { + const result = results.results[0] + if (result) { + const status = result.execResult.exceptionError ? 0 : 1 + result.status = `0x${status}` + } + callback(null, { + result: result, + transactionHash: bufferToHex(Buffer.from(tx.hash())), + block, + tx, + }) + }).catch(function (err) { + callback(err) + }) + } +} + diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts new file mode 100644 index 0000000000..f735b3401c --- /dev/null +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -0,0 +1,156 @@ +'use strict' +import { EventManager } from '../eventManager' +import Web3 from 'web3' + +export class TxRunnerWeb3 { + event + _api + getWeb3: () => Web3 + currentblockGasLimit: () => number + + constructor (api, getWeb3, currentblockGasLimit) { + this.event = new EventManager() + this.getWeb3 = getWeb3 + this.currentblockGasLimit = currentblockGasLimit + this._api = api + } + + _executeTx (tx, gasPrice, api, promptCb, callback) { + if (gasPrice) tx.gasPrice = this.getWeb3().utils.toHex(gasPrice) + if (api.personalMode()) { + promptCb( + (value) => { + this._sendTransaction((this.getWeb3() as any).personal.sendTransaction, tx, value, callback) + }, + () => { + return callback('Canceled by user.') + } + ) + } else { + this._sendTransaction(this.getWeb3().eth.sendTransaction, tx, null, callback) + } + } + + _sendTransaction (sendTx, tx, pass, callback) { + const cb = (err, resp) => { + if (err) { + return callback(err, resp) + } + this.event.trigger('transactionBroadcasted', [resp]) + var listenOnResponse = () => { + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { + const receipt = await tryTillReceiptAvailable(resp, this.getWeb3()) + tx = await tryTillTxAvailable(resp, this.getWeb3()) + resolve({ + receipt, + tx, + transactionHash: receipt ? receipt['transactionHash'] : null + }) + }) + } + listenOnResponse().then((txData) => { callback(null, txData) }).catch((error) => { callback(error) }) + } + const args = pass !== null ? [tx, pass, cb] : [tx, cb] + try { + sendTx.apply({}, args) + } catch (e) { + return callback(`Send transaction failed: ${e.message} . if you use an injected provider, please check it is properly unlocked. `) + } + } + + execute (args, confirmationCb, gasEstimationForceSend, promptCb, callback) { + let data = args.data + if (data.slice(0, 2) !== '0x') { + data = '0x' + data + } + + return this.runInNode(args.from, args.to, data, args.value, args.gasLimit, args.useCall, args.timestamp, confirmationCb, gasEstimationForceSend, promptCb, callback) + } + + runInNode (from, to, data, value, gasLimit, useCall, timestamp, confirmCb, gasEstimationForceSend, promptCb, callback) { + const tx = { from: from, to: to, data: data, value: value } + + if (useCall) { + const tag = Date.now() // for e2e reference + tx['gas'] = gasLimit + tx['timestamp'] = timestamp + return this.getWeb3().eth.call(tx, function (error, result: any) { + if (error) return callback(error) + callback(null, { + result: result + }) + }) + } + this.getWeb3().eth.estimateGas(tx, (err, gasEstimation) => { + if (err && err.message.indexOf('Invalid JSON RPC response') !== -1) { + // // @todo(#378) this should be removed when https://github.com/WalletConnect/walletconnect-monorepo/issues/334 is fixed + new Error('Gas estimation failed because of an unknown internal error. This may indicated that the transaction will fail.') + } + gasEstimationForceSend(err, () => { + // callback is called whenever no error + tx['gas'] = !gasEstimation ? gasLimit : gasEstimation + + if (this._api.config.getUnpersistedProperty('doNotShowTransactionConfirmationAgain')) { + return this._executeTx(tx, null, this._api, promptCb, callback) + } + + this._api.detectNetwork((err, network) => { + if (err) { + console.log(err) + return + } + + confirmCb(network, tx, tx['gas'], (gasPrice) => { + return this._executeTx(tx, gasPrice, this._api, promptCb, callback) + }, (error) => { + callback(error) + }) + }) + }, () => { + const blockGasLimit = this.currentblockGasLimit() + // NOTE: estimateGas very likely will return a large limit if execution of the code failed + // we want to be able to run the code in order to debug and find the cause for the failure + if (err) return callback(err) + + let warnEstimation = ' An important gas estimation might also be the sign of a problem in the contract code. Please check loops and be sure you did not sent value to a non payable function (that\'s also the reason of strong gas estimation). ' + warnEstimation += ' ' + err + + if (gasEstimation > gasLimit) { + return callback('Gas required exceeds limit: ' + gasLimit + '. ' + warnEstimation) + } + if (gasEstimation > blockGasLimit) { + return callback('Gas required exceeds block gas limit: ' + gasLimit + '. ' + warnEstimation) + } + }) + }) + } +} + +async function tryTillReceiptAvailable (txhash, web3) { + return new Promise((resolve, reject) => { + web3.eth.getTransactionReceipt(txhash, async (err, receipt) => { + if (err || !receipt) { + // Try again with a bit of delay if error or if result still null + await pause() + return resolve(await tryTillReceiptAvailable(txhash, web3)) + } + return resolve(receipt) + }) + }) +} + +async function tryTillTxAvailable (txhash, web3) { + return new Promise((resolve, reject) => { + web3.eth.getTransaction(txhash, async (err, tx) => { + if (err || !tx) { + // Try again with a bit of delay if error or if result still null + await pause() + return resolve(await tryTillTxAvailable(txhash, web3)) + } + return resolve(tx) + }) + }) +} + +async function pause () { return new Promise((resolve, reject) => { setTimeout(resolve, 500) }) } diff --git a/libs/remix-lib/src/helpers/txResultHelper.ts b/libs/remix-lib/src/helpers/txResultHelper.ts index 7aa7967f0d..3264e5b771 100644 --- a/libs/remix-lib/src/helpers/txResultHelper.ts +++ b/libs/remix-lib/src/helpers/txResultHelper.ts @@ -20,9 +20,9 @@ function convertToPrefixedHex (input) { Also, VM results use BN and Buffers, Node results use hex strings/ints, So we need to normalize the values to prefixed hex strings */ -export function resultToRemixTx (txResult) { - const { result, transactionHash } = txResult - const { status, execResult, gasUsed, createdAddress, contractAddress } = result +export function resultToRemixTx (txResult, execResult) { + const { receipt, transactionHash, result } = txResult + const { status, gasUsed, contractAddress } = receipt let returnValue, errorMessage if (isHexString(result)) { @@ -38,6 +38,6 @@ export function resultToRemixTx (txResult) { gasUsed: convertToPrefixedHex(gasUsed), error: errorMessage, return: convertToPrefixedHex(returnValue), - createdAddress: convertToPrefixedHex(createdAddress || contractAddress) + createdAddress: convertToPrefixedHex(contractAddress) } } diff --git a/libs/remix-lib/src/index.ts b/libs/remix-lib/src/index.ts index 5b1108ff70..afcd0beae6 100644 --- a/libs/remix-lib/src/index.ts +++ b/libs/remix-lib/src/index.ts @@ -12,9 +12,12 @@ import * as txHelper from './execution/txHelper' import * as txFormat from './execution/txFormat' import { TxListener } from './execution/txListener' import { TxRunner } from './execution/txRunner' +import { LogsManager } from './execution/logsManager' import { ExecutionContext } from './execution/execution-context' import * as typeConversion from './execution/typeConversion' -import { UniversalDApp } from './universalDapp' +import { TxRunnerVM } from './execution/txRunnerVM' +import { TxRunnerWeb3 } from './execution/txRunnerWeb3' +import * as txResultHelper from './helpers/txResultHelper' export = modules() @@ -23,7 +26,8 @@ function modules () { EventManager: EventManager, helpers: { ui: uiHelper, - compiler: compilerHelper + compiler: compilerHelper, + txResultHelper }, vm: { Web3Providers: Web3Providers, @@ -39,9 +43,11 @@ function modules () { executionContext: new ExecutionContext(), txFormat: txFormat, txListener: TxListener, - txRunner: TxRunner, - typeConversion: typeConversion - }, - UniversalDApp: UniversalDApp + TxRunner: TxRunner, + TxRunnerWeb3: TxRunnerWeb3, + TxRunnerVM: TxRunnerVM, + typeConversion: typeConversion, + LogsManager + } } } diff --git a/libs/remix-lib/src/universalDapp.ts b/libs/remix-lib/src/universalDapp.ts deleted file mode 100644 index 030a8da811..0000000000 --- a/libs/remix-lib/src/universalDapp.ts +++ /dev/null @@ -1,379 +0,0 @@ -import { waterfall } from 'async' -import { BN, privateToAddress, isValidPrivate, toChecksumAddress, Address } from 'ethereumjs-util' -import { randomBytes } from 'crypto' -import { EventEmitter } from 'events' -import { TxRunner } from './execution/txRunner' -import { sortAbiFunction, getFallbackInterface, getReceiveInterface, inputParametersDeclarationToString } from './execution/txHelper' -import { EventManager } from './eventManager' -import { ExecutionContext } from './execution/execution-context' -import { resultToRemixTx } from './helpers/txResultHelper' - -export class UniversalDApp { - events - event - executionContext - config - txRunner - accounts - transactionContextAPI - - constructor (config, executionContext) { - this.events = new EventEmitter() - this.event = new EventManager() - // has a default for now for backwards compatability - this.executionContext = executionContext || new ExecutionContext() - this.config = config - - this.txRunner = new TxRunner({}, { - config: config, - detectNetwork: (cb) => { - this.executionContext.detectNetwork(cb) - }, - personalMode: () => { - return this.executionContext.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false - } - }, this.executionContext) - this.accounts = {} - this.executionContext.event.register('contextChanged', this.resetEnvironment.bind(this)) - } - - // TODO : event should be triggered by Udapp instead of TxListener - /** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */ - startListening (txlistener) { - txlistener.event.register('newTransaction', (tx) => { - this.events.emit('newTransaction', tx) - }) - } - - resetEnvironment () { - this.accounts = {} - if (this.executionContext.isVM()) { - this._addAccount('3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511', '0x56BC75E2D63100000') - this._addAccount('2ac6c190b09897cd8987869cc7b918cfea07ee82038d492abce033c75c1b1d0c', '0x56BC75E2D63100000') - this._addAccount('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', '0x56BC75E2D63100000') - this._addAccount('d74aa6d18aa79a05f3473dd030a97d3305737cbc8337d940344345c1f6b72eea', '0x56BC75E2D63100000') - this._addAccount('71975fbf7fe448e004ac7ae54cad0a383c3906055a65468714156a07385e96ce', '0x56BC75E2D63100000') - } - // TODO: most params here can be refactored away in txRunner - this.txRunner = new TxRunner(this.accounts, { - // TODO: only used to check value of doNotShowTransactionConfirmationAgain property - config: this.config, - // TODO: to refactor, TxRunner already has access to executionContext - detectNetwork: (cb) => { - this.executionContext.detectNetwork(cb) - }, - personalMode: () => { - return this.executionContext.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false - } - }, this.executionContext) - this.txRunner.event.register('transactionBroadcasted', (txhash) => { - this.executionContext.detectNetwork((error, network) => { - if (error || !network) return - this.event.trigger('transactionBroadcasted', [txhash, network.name]) - }) - }) - } - - resetAPI (transactionContextAPI) { - this.transactionContextAPI = transactionContextAPI - } - - /** - * Create a VM Account - * @param {{privateKey: string, balance: string}} newAccount The new account to create - */ - createVMAccount (newAccount) { - const { privateKey, balance } = newAccount - if (this.executionContext.getProvider() !== 'vm') { - throw new Error('plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed') - } - this._addAccount(privateKey, balance) - const privKey = Buffer.from(privateKey, 'hex') - return '0x' + privateToAddress(privKey).toString('hex') - } - - newAccount (password, passwordPromptCb, cb) { - if (!this.executionContext.isVM()) { - if (!this.config.get('settings/personal-mode')) { - return cb('Not running in personal mode') - } - return passwordPromptCb((passphrase) => { - this.executionContext.web3().personal.newAccount(passphrase, cb) - }) - } - let privateKey - do { - privateKey = randomBytes(32) - } while (!isValidPrivate(privateKey)) - this._addAccount(privateKey, '0x56BC75E2D63100000') - cb(null, '0x' + privateToAddress(privateKey).toString('hex')) - } - - /** Add an account to the list of account (only for Javascript VM) */ - _addAccount (privateKey, balance) { - if (!this.executionContext.isVM()) { - throw new Error('_addAccount() cannot be called in non-VM mode') - } - - if (!this.accounts) { - return - } - privateKey = Buffer.from(privateKey, 'hex') - const address = privateToAddress(privateKey) - - // FIXME: we don't care about the callback, but we should still make this proper - const stateManager = this.executionContext.vm().stateManager - stateManager.getAccount(address).then((account) => { - account.balance = new BN(balance.replace('0x', '') || 'f00000000000000001', 16) - stateManager.putAccount(address, account).catch((error) => { - console.log(error) - }) - }).catch((error) => { - console.log(error) - }) - - this.accounts[toChecksumAddress('0x' + address.toString('hex'))] = { privateKey, nonce: 0 } - } - - /** Return the list of accounts */ - getAccounts (cb) { - return new Promise((resolve, reject) => { - const provider = this.executionContext.getProvider() - switch (provider) { - case 'vm': - if (!this.accounts) { - if (cb) cb('No accounts?') - reject(new Error('No accounts?')) - return - } - if (cb) cb(null, Object.keys(this.accounts)) - resolve(Object.keys(this.accounts)) - break - case 'web3': - if (this.config.get('settings/personal-mode')) { - return this.executionContext.web3().personal.getListAccounts((error, accounts) => { - if (cb) cb(error, accounts) - if (error) return reject(error) - resolve(accounts) - }) - } else { - this.executionContext.web3().eth.getAccounts((error, accounts) => { - if (cb) cb(error, accounts) - if (error) return reject(error) - resolve(accounts) - }) - } - break - case 'injected': { - this.executionContext.web3().eth.getAccounts((error, accounts) => { - if (cb) cb(error, accounts) - if (error) return reject(error) - resolve(accounts) - }) - } - } - }) - } - - /** Get the balance of an address */ - getBalance (address, cb) { - if (!this.executionContext.isVM()) { - return this.executionContext.web3().eth.getBalance(address, (err, res) => { - if (err) { - return cb(err) - } - cb(null, res.toString(10)) - }) - } - if (!this.accounts) { - return cb('No accounts?') - } - - this.executionContext.vm().stateManager.getAccount(Address.fromString(address)).then((res) => { - cb(null, new BN(res.balance).toString(10)) - }).catch(() => { - cb('Account not found') - }) - } - - /** Get the balance of an address, and convert wei to ether */ - getBalanceInEther (address, callback) { - this.getBalance(address, (error, balance) => { - if (error) { - return callback(error) - } - callback(null, this.executionContext.web3().utils.fromWei(balance, 'ether')) - }) - } - - pendingTransactionsCount () { - return Object.keys(this.txRunner.pendingTxs).length - } - - /** - * deploy the given contract - * - * @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ). - * @param {Function} callback - callback. - */ - createContract (data, confirmationCb, continueCb, promptCb, callback) { - this.runTx({ data: data, useCall: false }, confirmationCb, continueCb, promptCb, callback) - } - - /** - * call the current given contract - * - * @param {String} to - address of the contract to call. - * @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ). - * @param {Object} funAbi - abi definition of the function to call. - * @param {Function} callback - callback. - */ - callFunction (to, data, funAbi, confirmationCb, continueCb, promptCb, callback) { - const useCall = funAbi.stateMutability === 'view' || funAbi.stateMutability === 'pure' - this.runTx({ to, data, useCall }, confirmationCb, continueCb, promptCb, callback) - } - - /** - * call the current given contract - * - * @param {String} to - address of the contract to call. - * @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ). - * @param {Function} callback - callback. - */ - sendRawTransaction (to, data, confirmationCb, continueCb, promptCb, callback) { - this.runTx({ to, data, useCall: false }, confirmationCb, continueCb, promptCb, callback) - } - - context () { - return (this.executionContext.isVM() ? 'memory' : 'blockchain') - } - - getABI (contract) { - return sortAbiFunction(contract.abi) - } - - getFallbackInterface (contractABI) { - return getFallbackInterface(contractABI) - } - - getReceiveInterface (contractABI) { - return getReceiveInterface(contractABI) - } - - getInputs (funABI) { - if (!funABI.inputs) { - return '' - } - return inputParametersDeclarationToString(funABI.inputs) - } - - /** - * This function send a tx only to javascript VM or testnet, will return an error for the mainnet - * SHOULD BE TAKEN CAREFULLY! - * - * @param {Object} tx - transaction. - */ - sendTransaction (tx) { - return new Promise((resolve, reject) => { - this.executionContext.detectNetwork((error, network) => { - if (error) return reject(error) - if (network.name === 'Main' && network.id === '1') { - return reject(new Error('It is not allowed to make this action against mainnet')) - } - this.silentRunTx(tx, (error, result) => { - if (error) return reject(error) - try { - resolve(resultToRemixTx(result)) - } catch (e) { - reject(e) - } - }) - }) - }) - } - - /** - * This function send a tx without alerting the user (if mainnet or if gas estimation too high). - * SHOULD BE TAKEN CAREFULLY! - * - * @param {Object} tx - transaction. - * @param {Function} callback - callback. - */ - silentRunTx (tx, cb) { - this.txRunner.rawRun( - tx, - (network, tx, gasEstimation, continueTxExecution, cancelCb) => { continueTxExecution() }, - (error, continueTxExecution, cancelCb) => { if (error) { cb(error) } else { continueTxExecution() } }, - (okCb, cancelCb) => { okCb() }, - cb - ) - } - - runTx (args, confirmationCb, continueCb, promptCb, cb) { - const self = this - waterfall([ - function getGasLimit (next) { - if (self.transactionContextAPI.getGasLimit) { - return self.transactionContextAPI.getGasLimit(next) - } - next(null, 3000000) - }, - function queryValue (gasLimit, next) { - if (args.value) { - return next(null, args.value, gasLimit) - } - if (args.useCall || !self.transactionContextAPI.getValue) { - return next(null, 0, gasLimit) - } - self.transactionContextAPI.getValue(function (err, value) { - next(err, value, gasLimit) - }) - }, - function getAccount (value, gasLimit, next) { - if (args.from) { - return next(null, args.from, value, gasLimit) - } - if (self.transactionContextAPI.getAddress) { - return self.transactionContextAPI.getAddress(function (err, address) { - next(err, address, value, gasLimit) - }) - } - self.getAccounts(function (err, accounts) { - const address = accounts[0] - - if (err) return next(err) - if (!address) return next('No accounts available') - if (self.executionContext.isVM() && !self.accounts[address]) { - return next('Invalid account selected') - } - next(null, address, value, gasLimit) - }) - }, - function runTransaction (fromAddress, value, gasLimit, next) { - const tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: fromAddress, value: value, gasLimit: gasLimit, timestamp: args.data.timestamp } - const payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName, contractABI: args.data.contractABI, linkReferences: args.data.linkReferences } - let timestamp = Date.now() - if (tx.timestamp) { - timestamp = tx.timestamp - } - - self.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) - self.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb, - function (error, result) { - const eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') - self.event.trigger(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) - - if (error && (typeof (error) !== 'string')) { - if (error.message) error = error.message - else { - // eslint-disable-next-line no-empty - try { error = 'error: ' + JSON.stringify(error) } catch (e) {} - } - } - next(error, result) - } - ) - } - ], cb) - } -} diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-lib/src/web3Provider/web3VmProvider.ts index 367370f928..361c2b7161 100644 --- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts +++ b/libs/remix-lib/src/web3Provider/web3VmProvider.ts @@ -31,6 +31,9 @@ export class Web3VmProvider { toBigNumber isAddress utils + txsMapBlock + blocks + latestBlockNumber constructor () { this.web3 = new Web3() @@ -69,6 +72,9 @@ export class Web3VmProvider { this.toBigNumber = (...args) => this.web3.utils.toBN(...args) this.isAddress = (...args) => this.web3.utils.isAddress(...args) this.utils = Web3.utils || [] + this.txsMapBlock = {} + this.blocks = {} + this.latestBlockNumber } setVM (vm) { diff --git a/libs/remix-lib/test/txFormat.ts b/libs/remix-lib/test/txFormat.ts index d33760f9f9..2ab4a59b63 100644 --- a/libs/remix-lib/test/txFormat.ts +++ b/libs/remix-lib/test/txFormat.ts @@ -161,8 +161,8 @@ tape('ContractParameters - (TxFormat.buildData) - link Libraries', function (t) } const callbackDeployLibraries = (param, callback) => { callback(null, { - result: { - createdAddress: fakeDeployedContracts[param.data.contractName] + receipt: { + contractAddress: fakeDeployedContracts[param.data.contractName] } }) } // fake diff --git a/libs/remix-lib/test/txResultHelper.ts b/libs/remix-lib/test/txResultHelper.ts index 8fa2e5cdf2..67a136dc84 100644 --- a/libs/remix-lib/test/txResultHelper.ts +++ b/libs/remix-lib/test/txResultHelper.ts @@ -18,12 +18,13 @@ const GAS_USED_INT = 75427 const GAS_USED_HEX = '0x126a3' const NODE_CALL_RESULT = { + receipt: {}, result: RETURN_VALUE_HEX, transactionHash: undefined } const NODE_TX_RESULT = { - result: { + receipt: { blockHash: '0x380485a4e6372a42e36489783c7f7cb66257612133cd245859c206fd476e9c44', blockNumber: 5994, contractAddress: CONTRACT_ADDRESS_HEX, @@ -39,26 +40,31 @@ const NODE_TX_RESULT = { } const VM_RESULT = { - result: { + receipt: { amountSpent: new BN(1), - createdAddress: CONTRACT_ADDRESS_BUFFER, + contractAddress: CONTRACT_ADDRESS_BUFFER, gasRefund: new BN(0), gasUsed: new BN(GAS_USED_INT), status: STATUS_OK, - execResult: { - exceptionError: null, - gasRefund: new BN(0), - gasUsed: new BN(GAS_USED_INT), - returnValue: RETURN_VALUE_BUFFER - } }, transactionHash: TRANSACTION_HASH } +const EXEC_RESULT = { + exceptionError: null, + gasRefund: new BN(0), + gasUsed: new BN(GAS_USED_INT), + returnValue: RETURN_VALUE_BUFFER +} + +const EXEC_RESULT_ERROR = { + exceptionError: 'this is an error' +} + tape('converts node transaction result to RemixTx', function (t) { // contract creation let txResult = { ...NODE_TX_RESULT } - let remixTx = resultToRemixTx(txResult) + let remixTx = resultToRemixTx(txResult, {}) t.equal(remixTx.transactionHash, TRANSACTION_HASH) t.equal(remixTx.createdAddress, CONTRACT_ADDRESS_HEX) @@ -68,8 +74,8 @@ tape('converts node transaction result to RemixTx', function (t) { t.equal(remixTx.error, undefined) // contract method tx - txResult.result.contractAddress = null - remixTx = resultToRemixTx(txResult) + txResult.receipt.contractAddress = null + remixTx = resultToRemixTx(txResult, {}) t.equal(remixTx.createdAddress, null) t.end() @@ -77,7 +83,7 @@ tape('converts node transaction result to RemixTx', function (t) { tape('converts node call result to RemixTx', function (t) { let txResult = { ...NODE_CALL_RESULT } - let remixTx = resultToRemixTx(txResult) + let remixTx = resultToRemixTx(txResult, {}) t.equal(remixTx.transactionHash, undefined) t.equal(remixTx.createdAddress, undefined) @@ -91,7 +97,7 @@ tape('converts node call result to RemixTx', function (t) { tape('converts VM result to RemixTx', function (t) { let txResult = { ...VM_RESULT } - let remixTx = resultToRemixTx(txResult) + let remixTx = resultToRemixTx(txResult, EXEC_RESULT) t.equal(remixTx.transactionHash, TRANSACTION_HASH) @@ -101,8 +107,7 @@ tape('converts VM result to RemixTx', function (t) { t.equal(remixTx.return, RETURN_VALUE_HEX) t.equal(remixTx.error, null) - txResult.result.execResult.exceptionError = 'this is an error' - remixTx = resultToRemixTx(txResult) + remixTx = resultToRemixTx(VM_RESULT, EXEC_RESULT_ERROR) t.equal(remixTx.error, 'this is an error') t.end() diff --git a/libs/remix-simulator/src/genesis.ts b/libs/remix-simulator/src/genesis.ts index f3d7d0509e..839a0c4cb6 100644 --- a/libs/remix-simulator/src/genesis.ts +++ b/libs/remix-simulator/src/genesis.ts @@ -1,7 +1,7 @@ import { Block } from '@ethereumjs/block' import { BN } from 'ethereumjs-util' -export function generateBlock (executionContext) { +export function generateBlock (vmContext) { return new Promise((resolve, reject) => { const block: Block = Block.fromBlockData({ header: { @@ -11,10 +11,10 @@ export function generateBlock (executionContext) { difficulty: new BN('69762765929000', 10), gasLimit: new BN('8000000').imuln(1) } - }, { common: executionContext.vmObject().common }) + }, { common: vmContext.vmObject().common }) - executionContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then(() => { - executionContext.addBlock(block) + vmContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then(() => { + vmContext.addBlock(block) resolve({}) }).catch((e) => reject(e)) }) diff --git a/libs/remix-simulator/src/index.ts b/libs/remix-simulator/src/index.ts index fd73199808..19ca3ab802 100644 --- a/libs/remix-simulator/src/index.ts +++ b/libs/remix-simulator/src/index.ts @@ -1 +1 @@ -export { Provider } from './provider' +export { Provider, extend } from './provider' diff --git a/libs/remix-simulator/src/methods/accounts.ts b/libs/remix-simulator/src/methods/accounts.ts index 6fd359594b..8d18498afc 100644 --- a/libs/remix-simulator/src/methods/accounts.ts +++ b/libs/remix-simulator/src/methods/accounts.ts @@ -6,22 +6,20 @@ export class Accounts { web3 accounts: Record accountsKeys: Record - executionContext + vmContext - constructor (executionContext) { + constructor (vmContext) { this.web3 = new Web3() - this.executionContext = executionContext + this.vmContext = vmContext // TODO: make it random and/or use remix-libs this.accounts = {} this.accountsKeys = {} - this.executionContext.init({ get: () => { return true } }) } async resetAccounts (): Promise { - // TODO: setting this to {} breaks the app currently, unclear why still - // this.accounts = {} - // this.accountsKeys = {} + this.accounts = {} + this.accountsKeys = {} await this._addAccount('503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb', '0x56BC75E2D63100000') await this._addAccount('7e5bfb82febc4c2c8529167104271ceec190eafdca277314912eaabdb67c6e5f', '0x56BC75E2D63100000') await this._addAccount('cc6d63f85de8fef05446ebdd3c537c72152d0fc437fd7aa62b3019b79bd1fdd4', '0x56BC75E2D63100000') @@ -47,7 +45,7 @@ export class Accounts { this.accounts[addressStr] = { privateKey, nonce: 0 } this.accountsKeys[addressStr] = '0x' + privateKey.toString('hex') - const stateManager = this.executionContext.vm().stateManager + const stateManager = this.vmContext.vm().stateManager stateManager.getAccount(Address.fromString(addressStr)).then((account) => { account.balance = new BN(balance.replace('0x', '') || 'f00000000000000001', 16) stateManager.putAccount(Address.fromString(addressStr), account).catch((error) => { @@ -85,7 +83,7 @@ export class Accounts { eth_getBalance (payload, cb) { const address = payload.params[0] - this.executionContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => { + this.vmContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => { cb(null, new BN(account.balance).toString(10)) }).catch((error) => { cb(error) diff --git a/libs/remix-simulator/src/methods/blocks.ts b/libs/remix-simulator/src/methods/blocks.ts index bfed840284..7ac7bc179f 100644 --- a/libs/remix-simulator/src/methods/blocks.ts +++ b/libs/remix-simulator/src/methods/blocks.ts @@ -1,10 +1,10 @@ export class Blocks { - executionContext + vmContext coinbase: string blockNumber: number - constructor (executionContext, _options) { - this.executionContext = executionContext + constructor (vmContext, _options) { + this.vmContext = vmContext const options = _options || {} this.coinbase = options.coinbase || '0x0000000000000000000000000000000000000000' this.blockNumber = 0 @@ -28,13 +28,13 @@ export class Blocks { eth_getBlockByNumber (payload, cb) { let blockIndex = payload.params[0] if (blockIndex === 'latest') { - blockIndex = this.executionContext.latestBlockNumber + blockIndex = this.vmContext.latestBlockNumber } if (Number.isInteger(blockIndex)) { blockIndex = '0x' + blockIndex.toString(16) } - const block = this.executionContext.blocks[blockIndex] + const block = this.vmContext.blocks[blockIndex] if (!block) { return cb(new Error('block not found')) @@ -70,7 +70,7 @@ export class Blocks { } eth_getBlockByHash (payload, cb) { - const block = this.executionContext.blocks[payload.params[0]] + const block = this.vmContext.blocks[payload.params[0]] const b = { number: this.toHex(block.header.number), @@ -109,13 +109,13 @@ export class Blocks { } eth_getBlockTransactionCountByHash (payload, cb) { - const block = this.executionContext.blocks[payload.params[0]] + const block = this.vmContext.blocks[payload.params[0]] cb(null, block.transactions.length) } eth_getBlockTransactionCountByNumber (payload, cb) { - const block = this.executionContext.blocks[payload.params[0]] + const block = this.vmContext.blocks[payload.params[0]] cb(null, block.transactions.length) } @@ -131,7 +131,7 @@ export class Blocks { eth_getStorageAt (payload, cb) { const [address, position, blockNumber] = payload.params - this.executionContext.web3().debug.storageRangeAt(blockNumber, 'latest', address.toLowerCase(), position, 1, (err, result) => { + this.vmContext.web3().debug.storageRangeAt(blockNumber, 'latest', address.toLowerCase(), position, 1, (err, result) => { if (err || (result.storage && Object.values(result.storage).length === 0)) { return cb(err, '') } diff --git a/libs/remix-simulator/src/methods/debug.ts b/libs/remix-simulator/src/methods/debug.ts index ae7f3067b8..b9bf886e50 100644 --- a/libs/remix-simulator/src/methods/debug.ts +++ b/libs/remix-simulator/src/methods/debug.ts @@ -1,8 +1,8 @@ export class Debug { - executionContext + vmContext - constructor (executionContext) { - this.executionContext = executionContext + constructor (vmContext) { + this.vmContext = vmContext } methods () { @@ -14,15 +14,15 @@ export class Debug { } debug_traceTransaction (payload, cb) { - this.executionContext.web3().debug.traceTransaction(payload.params[0], {}, cb) + this.vmContext.web3().debug.traceTransaction(payload.params[0], {}, cb) } debug_preimage (payload, cb) { - this.executionContext.web3().debug.preimage(payload.params[0], cb) + this.vmContext.web3().debug.preimage(payload.params[0], cb) } debug_storageRangeAt (payload, cb) { - this.executionContext.web3().debug.storageRangeAt( + this.vmContext.web3().debug.storageRangeAt( payload.params[0], payload.params[1], payload.params[2], diff --git a/libs/remix-simulator/src/methods/filters.ts b/libs/remix-simulator/src/methods/filters.ts index c27cc49bd6..43404a1c31 100644 --- a/libs/remix-simulator/src/methods/filters.ts +++ b/libs/remix-simulator/src/methods/filters.ts @@ -1,8 +1,8 @@ export class Filters { - executionContext + vmContext - constructor (executionContext) { - this.executionContext = executionContext + constructor (vmContext) { + this.vmContext = vmContext } methods () { @@ -14,49 +14,49 @@ export class Filters { } eth_getLogs (payload, cb) { - const results = this.executionContext.logsManager.getLogsFor(payload.params[0]) + const results = this.vmContext.logsManager.getLogsFor(payload.params[0]) cb(null, results) } eth_subscribe (payload, cb) { - const subscriptionId = this.executionContext.logsManager.subscribe(payload.params) + const subscriptionId = this.vmContext.logsManager.subscribe(payload.params) cb(null, subscriptionId) } eth_unsubscribe (payload, cb) { - this.executionContext.logsManager.unsubscribe(payload.params[0]) + this.vmContext.logsManager.unsubscribe(payload.params[0]) cb(null, true) } eth_newFilter (payload, cb) { - const filterId = this.executionContext.logsManager.newFilter('filter', payload.params[0]) + const filterId = this.vmContext.logsManager.newFilter('filter', payload.params[0]) cb(null, filterId) } eth_newBlockFilter (payload, cb) { - const filterId = this.executionContext.logsManager.newFilter('block') + const filterId = this.vmContext.logsManager.newFilter('block') cb(null, filterId) } eth_newPendingTransactionFilter (payload, cb) { - const filterId = this.executionContext.logsManager.newFilter('pendingTransactions') + const filterId = this.vmContext.logsManager.newFilter('pendingTransactions') cb(null, filterId) } eth_uninstallfilter (payload, cb) { - const result = this.executionContext.logsManager.uninstallFilter(payload.params[0]) + const result = this.vmContext.logsManager.uninstallFilter(payload.params[0]) cb(null, result) } eth_getFilterChanges (payload, cb) { const filterId = payload.params[0] - const results = this.executionContext.logsManager.getLogsForFilter(filterId) + const results = this.vmContext.logsManager.getLogsForFilter(filterId) cb(null, results) } eth_getFilterLogs (payload, cb) { const filterId = payload.params[0] - const results = this.executionContext.logsManager.getLogsForFilter(filterId, true) + const results = this.vmContext.logsManager.getLogsForFilter(filterId, true) cb(null, results) } } diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index f3e8ca3f43..04ef986403 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -3,11 +3,14 @@ import { toChecksumAddress, BN, Address } from 'ethereumjs-util' import { processTx } from './txProcess' export class Transactions { - executionContext + vmContext accounts + tags - constructor (executionContext) { - this.executionContext = executionContext + + constructor (vmContext) { + this.vmContext = vmContext + this.tags = {} } init (accounts) { @@ -24,7 +27,9 @@ export class Transactions { eth_getTransactionCount: this.eth_getTransactionCount.bind(this), eth_getTransactionByHash: this.eth_getTransactionByHash.bind(this), eth_getTransactionByBlockHashAndIndex: this.eth_getTransactionByBlockHashAndIndex.bind(this), - eth_getTransactionByBlockNumberAndIndex: this.eth_getTransactionByBlockNumberAndIndex.bind(this) + eth_getTransactionByBlockNumberAndIndex: this.eth_getTransactionByBlockNumberAndIndex.bind(this), + eth_getExecutionResultFromSimulator: this.eth_getExecutionResultFromSimulator.bind(this), + eth_getHashFromTagBySimulator: this.eth_getHashFromTagBySimulator.bind(this) } } @@ -33,16 +38,30 @@ export class Transactions { if (payload.params && payload.params.length > 0 && payload.params[0].from) { payload.params[0].from = toChecksumAddress(payload.params[0].from) } - processTx(this.executionContext, this.accounts, payload, false, cb) + processTx(this.vmContext, this.accounts, payload, false, (error, result) => { + if (!error && result) { + this.vmContext.addBlock(result.block) + const hash = '0x' + result.tx.hash().toString('hex') + this.vmContext.trackTx(hash, result.block) + this.vmContext.trackExecResult(hash, result.result.execResult) + return cb (null, result.transactionHash) + } + cb(error) + }) + } + + eth_getExecutionResultFromSimulator (payload, cb) { + const txHash = payload.params[0] + cb(null, this.vmContext.exeResults[txHash]) } eth_getTransactionReceipt (payload, cb) { - this.executionContext.web3().eth.getTransactionReceipt(payload.params[0], (error, receipt) => { + this.vmContext.web3().eth.getTransactionReceipt(payload.params[0], (error, receipt) => { if (error) { return cb(error) } - const txBlock = this.executionContext.txs[receipt.hash] + const txBlock = this.vmContext.txs[receipt.hash] const r: Record = { transactionHash: receipt.hash, @@ -72,7 +91,7 @@ export class Transactions { eth_getCode (payload, cb) { const address = payload.params[0] - this.executionContext.web3().eth.getCode(address, (error, result) => { + this.vmContext.web3().eth.getCode(address, (error, result) => { if (error) { console.dir('error getting code') console.dir(error) @@ -91,14 +110,32 @@ export class Transactions { } payload.params[0].value = undefined + + const tag = payload.params[0].timestamp // e2e reference + + processTx(this.vmContext, this.accounts, payload, true, (error, result) => { + if (!error && result) { + this.vmContext.addBlock(result.block) + const hash = '0x' + result.tx.hash().toString('hex') + this.vmContext.trackTx(hash, result.block) + this.vmContext.trackExecResult(hash, result.result.execResult) + this.tags[tag] = result.transactionHash + // calls are not supposed to return a transaction hash. we do this for keeping track of it and allowing debugging calls. + const returnValue = `0x${result.result.execResult.returnValue.toString('hex') || '0'}` + return cb (null, returnValue) + } + cb(error) + }) + } - processTx(this.executionContext, this.accounts, payload, true, cb) + eth_getHashFromTagBySimulator (payload, cb) { + return cb(null, this.tags[payload.params[0]]) } eth_getTransactionCount (payload, cb) { const address = payload.params[0] - this.executionContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => { + this.vmContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => { const nonce = new BN(account.nonce).toString(10) cb(null, nonce) }).catch((error) => { @@ -109,12 +146,12 @@ export class Transactions { eth_getTransactionByHash (payload, cb) { const address = payload.params[0] - this.executionContext.web3().eth.getTransactionReceipt(address, (error, receipt) => { + this.vmContext.web3().eth.getTransactionReceipt(address, (error, receipt) => { if (error) { return cb(error) } - const txBlock = this.executionContext.txs[receipt.transactionHash] + const txBlock = this.vmContext.txs[receipt.transactionHash] // TODO: params to add later const r: Record = { @@ -154,10 +191,10 @@ export class Transactions { eth_getTransactionByBlockHashAndIndex (payload, cb) { const txIndex = payload.params[1] - const txBlock = this.executionContext.blocks[payload.params[0]] + const txBlock = this.vmContext.blocks[payload.params[0]] const txHash = '0x' + txBlock.transactions[Web3.utils.toDecimal(txIndex)].hash().toString('hex') - this.executionContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { + this.vmContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { if (error) { return cb(error) } @@ -196,10 +233,10 @@ export class Transactions { eth_getTransactionByBlockNumberAndIndex (payload, cb) { const txIndex = payload.params[1] - const txBlock = this.executionContext.blocks[payload.params[0]] + const txBlock = this.vmContext.blocks[payload.params[0]] const txHash = '0x' + txBlock.transactions[Web3.utils.toDecimal(txIndex)].hash().toString('hex') - this.executionContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { + this.vmContext.web3().eth.getTransactionReceipt(txHash, (error, receipt) => { if (error) { return cb(error) } diff --git a/libs/remix-simulator/src/methods/txProcess.ts b/libs/remix-simulator/src/methods/txProcess.ts index 8f8acb5b2f..821206eae8 100644 --- a/libs/remix-simulator/src/methods/txProcess.ts +++ b/libs/remix-simulator/src/methods/txProcess.ts @@ -1,15 +1,15 @@ import { execution } from '@remix-project/remix-lib' const TxExecution = execution.txExecution -const TxRunner = execution.txRunner +const TxRunnerVM = execution.TxRunnerVM +const TxRunner = execution.TxRunner + function runCall (payload, from, to, data, value, gasLimit, txRunner, callbacks, callback) { const finalCallback = function (err, result) { if (err) { return callback(err) - } - const returnValue = result.result.execResult.returnValue.toString('hex') - const toReturn = `0x${returnValue || '0'}` - return callback(null, toReturn) + } + return callback(null, result) } TxExecution.callFunction(from, to, data, value, gasLimit, { constant: true }, txRunner, callbacks, finalCallback) @@ -20,7 +20,7 @@ function runTx (payload, from, to, data, value, gasLimit, txRunner, callbacks, c if (err) { return callback(err) } - callback(null, result.transactionHash) + callback(null, result) } TxExecution.callFunction(from, to, data, value, gasLimit, { constant: false }, txRunner, callbacks, finalCallback) @@ -31,15 +31,16 @@ function createContract (payload, from, data, value, gasLimit, txRunner, callbac if (err) { return callback(err) } - callback(null, result.transactionHash) + callback(null, result) } TxExecution.createContract(from, data, value, gasLimit, txRunner, callbacks, finalCallback) } +let txRunnerVMInstance let txRunnerInstance -export function processTx (executionContext, accounts, payload, isCall, callback) { +export function processTx (vmContext, accounts, payload, isCall, callback) { const api = { logMessage: (msg) => { }, @@ -61,11 +62,11 @@ export function processTx (executionContext, accounts, payload, isCall, callback } } - executionContext.init(api.config) - - // let txRunner = new TxRunner(accounts, api) + if (!txRunnerVMInstance) { + txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => vmContext.vm()) + } if (!txRunnerInstance) { - txRunnerInstance = new TxRunner(accounts, api, executionContext) + txRunnerInstance = new TxRunner(txRunnerVMInstance, { runAsync: false }) } txRunnerInstance.vmaccounts = accounts let { from, to, data, value, gas } = payload.params[0] diff --git a/libs/remix-simulator/src/provider.ts b/libs/remix-simulator/src/provider.ts index 8fdb5b5aba..5046660d7f 100644 --- a/libs/remix-simulator/src/provider.ts +++ b/libs/remix-simulator/src/provider.ts @@ -1,5 +1,4 @@ import { Blocks } from './methods/blocks' -import { execution } from '@remix-project/remix-lib' import { info } from './utils/logs' import merge from 'merge' @@ -11,11 +10,11 @@ import { methods as netMethods } from './methods/net' import { Transactions } from './methods/transactions' import { Debug } from './methods/debug' import { generateBlock } from './genesis' -const { executionContext } = execution +import { VMContext } from './vm-context' export class Provider { options: Record - executionContext + vmContext Accounts Transactions methods @@ -26,23 +25,23 @@ export class Provider { this.options = options this.host = host this.connected = true - // TODO: init executionContext here - this.executionContext = executionContext - this.Accounts = new Accounts(this.executionContext) - this.Transactions = new Transactions(this.executionContext) + this.vmContext = new VMContext() + + this.Accounts = new Accounts(this.vmContext) + this.Transactions = new Transactions(this.vmContext) this.methods = {} this.methods = merge(this.methods, this.Accounts.methods()) - this.methods = merge(this.methods, (new Blocks(this.executionContext, options)).methods()) + this.methods = merge(this.methods, (new Blocks(this.vmContext, options)).methods()) this.methods = merge(this.methods, miscMethods()) - this.methods = merge(this.methods, (new Filters(this.executionContext)).methods()) + this.methods = merge(this.methods, (new Filters(this.vmContext)).methods()) this.methods = merge(this.methods, netMethods()) this.methods = merge(this.methods, this.Transactions.methods()) - this.methods = merge(this.methods, (new Debug(this.executionContext)).methods()) + this.methods = merge(this.methods, (new Debug(this.vmContext)).methods()) } async init () { - await generateBlock(this.executionContext) + await generateBlock(this.vmContext) await this.Accounts.resetAccounts() this.Transactions.init(this.Accounts.accounts) } @@ -87,6 +86,40 @@ export class Provider { }; on (type, cb) { - this.executionContext.logsManager.addListener(type, cb) + this.vmContext.logsManager.addListener(type, cb) } } + +export function extend (web3) { + if (!web3.extend) { + return + } + // DEBUG + const methods = [] + if (!(web3.eth && web3.eth.getExecutionResultFromSimulator)) { + methods.push(new web3.extend.Method({ + name: 'getExecutionResultFromSimulator', + call: 'eth_getExecutionResultFromSimulator', + inputFormatter: [null], + params: 1 + })) + } + + if (!(web3.eth && web3.eth.getHashFromTagBySimulator)) { + methods.push(new web3.extend.Method({ + name: 'getHashFromTagBySimulator', + call: 'eth_getHashFromTagBySimulator', + inputFormatter: [null], + params: 1 + })) + } + + if (methods.length > 0) { + web3.extend({ + property: 'eth', + methods: methods, + properties: [] + }) + } +} + diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts new file mode 100644 index 0000000000..481f5f4057 --- /dev/null +++ b/libs/remix-simulator/src/vm-context.ts @@ -0,0 +1,147 @@ +/* global ethereum */ +'use strict' +import Web3 from 'web3' +import { rlp, keccak, bufferToHex } from 'ethereumjs-util' +import { vm, execution } from '@remix-project/remix-lib' +const EthJSVM = require('ethereumjs-vm').default +const StateManager = require('ethereumjs-vm/dist/state/stateManager').default + +/* + extend vm state manager and instanciate VM +*/ + +class StateManagerCommonStorageDump extends StateManager { + constructor (arg) { + super(arg) + this.keyHashes = {} + } + + putContractStorage (address, key, value, cb) { + this.keyHashes[keccak(key).toString('hex')] = bufferToHex(key) + super.putContractStorage(address, key, value, cb) + } + + dumpStorage (address, cb) { + this._getStorageTrie(address, (err, trie) => { + if (err) { + return cb(err) + } + const storage = {} + const stream = trie.createReadStream() + stream.on('data', (val) => { + const value = rlp.decode(val.value) + storage['0x' + val.key.toString('hex')] = { + key: this.keyHashes[val.key.toString('hex')], + value: '0x' + value.toString('hex') + } + }) + stream.on('end', function () { + cb(storage) + }) + }) + } + + getStateRoot (cb) { + const checkpoint = this._checkpointCount + this._checkpointCount = 0 + super.getStateRoot((err, stateRoot) => { + this._checkpointCount = checkpoint + cb(err, stateRoot) + }) + } + + setStateRoot (stateRoot, cb) { + const checkpoint = this._checkpointCount + this._checkpointCount = 0 + super.setStateRoot(stateRoot, (err) => { + this._checkpointCount = checkpoint + cb(err) + }) + } +} + +/* + trigger contextChanged, web3EndpointChanged +*/ +export class VMContext { + currentFork: string + blockGasLimitDefault: number + blockGasLimit: number + customNetWorks + blocks + latestBlockNumber + txs + vms + web3vm + logsManager + exeResults + + constructor () { + this.blockGasLimitDefault = 4300000 + this.blockGasLimit = this.blockGasLimitDefault + this.currentFork = 'muirGlacier' + this.vms = { + /* + byzantium: createVm('byzantium'), + constantinople: createVm('constantinople'), + petersburg: createVm('petersburg'), + istanbul: createVm('istanbul'), + */ + muirGlacier: this.createVm('muirGlacier') + } + this.blocks = {} + this.latestBlockNumber = 0 + this.txs = {} + this.exeResults = {} + this.logsManager = new execution.LogsManager() + + } + + createVm (hardfork) { + const stateManager = new StateManagerCommonStorageDump({}) + stateManager.checkpoint(() => {}) + const ethvm = new EthJSVM({ + activatePrecompiles: true, + blockchain: stateManager.blockchain, + stateManager: stateManager, + hardfork: hardfork + }) + ethvm.blockchain.validate = false + this.web3vm = new vm.Web3VMProvider() + this.web3vm.setVM(ethvm) + return { vm: ethvm, web3vm: this.web3vm, stateManager } + } + + web3 () { + return this.web3vm + } + + blankWeb3 () { + return new Web3() + } + + vm () { + return this.vms[this.currentFork].vm + } + + addBlock (block) { + let blockNumber = '0x' + block.header.number.toString('hex') + if (blockNumber === '0x') { + blockNumber = '0x0' + } + + this.blocks['0x' + block.hash().toString('hex')] = block + this.blocks[blockNumber] = block + this.latestBlockNumber = blockNumber + + this.logsManager.checkBlock(blockNumber, block, this.web3vm) + } + + trackTx (tx, block) { + this.txs[tx] = block + } + + trackExecResult (tx, execReult) { + this.exeResults[tx] = execReult + } +} diff --git a/libs/remix-tests/jest.config.js b/libs/remix-tests/jest.config.js index 7923ddf044..dcbd823a5c 100644 --- a/libs/remix-tests/jest.config.js +++ b/libs/remix-tests/jest.config.js @@ -1,7 +1,7 @@ module.exports = { name: 'remix-tests', preset: '../../jest.config.js', - verbose: true, + verbose: false, silent: false, // Silent console messages, specially the 'remix-simulator' ones transform: { '^.+\\.[tj]sx?$': 'ts-jest', @@ -18,6 +18,6 @@ module.exports = { "!src/types.ts", "!src/logger.ts" ], - coverageDirectory: '../../coverage/libs/remix-tests', + coverageDirectory: '../../coverage/libs/remix-tests' }; \ No newline at end of file diff --git a/libs/remix-tests/src/deployer.ts b/libs/remix-tests/src/deployer.ts index c6e00456fa..1e3fcb8d88 100644 --- a/libs/remix-tests/src/deployer.ts +++ b/libs/remix-tests/src/deployer.ts @@ -79,7 +79,7 @@ export function deployAll (compileResult: compilationInterface, web3: Web3, with contracts[contractName] = contractObject contracts[contractName].filename = filename - callback(null, { result: { createdAddress: receipt.contractAddress } }) // TODO this will only work with JavaScriptV VM + callback(null, { receipt: { contractAddress: receipt.contractAddress } }) // TODO this will only work with JavaScriptV VM }).on('error', function (err) { console.error(err) callback(err) diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index 3d906095f3..a865bbc649 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -3,17 +3,23 @@ import { resolve } from 'path' describe('testRunner: remix-tests CLI', () => { // remix-tests binary, after build, is used as executable + const executablePath = resolve(__dirname + '/../../../dist/libs/remix-tests/bin/remix-tests') + const result = spawnSync('ls', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) if(result) { const dirContent = result.stdout.toString() // Install dependencies if 'node_modules' is not already present - if(!dirContent.includes('node_modules')) execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) + if(!dirContent.includes('node_modules')) execSync( + 'ln -s ' + __dirname + '/../../../node_modules node_modules', + { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) } + describe('test various CLI options', () => { test('remix-tests version', () => { const res = spawnSync(executablePath, ['-V']) + console.log(res.stdout.toString()) expect(res.stdout.toString().trim()).toBe(require('../package.json').version) }) diff --git a/libs/remix-tests/tsconfig.json b/libs/remix-tests/tsconfig.json index 4422abf942..cf7076c1d1 100644 --- a/libs/remix-tests/tsconfig.json +++ b/libs/remix-tests/tsconfig.json @@ -3,9 +3,9 @@ "compilerOptions": { "types": ["node", "jest"], "module": "commonjs", + "esModuleInterop": true, "allowJs": true, "rootDir": "./", - "esModuleInterop": true }, "include": ["**/*.ts"] } \ No newline at end of file diff --git a/libs/remix-tests/tsconfig.lib.json b/libs/remix-tests/tsconfig.lib.json index ac117282b1..aec3a4c785 100644 --- a/libs/remix-tests/tsconfig.lib.json +++ b/libs/remix-tests/tsconfig.lib.json @@ -1,16 +1,15 @@ { - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "outDir": "../../dist/out-tsc", - "declaration": true, - "rootDir": "./", - "types": ["node"] - }, - "exclude": [ - "**/*.spec.ts", - "tests/" - ], - "include": ["**/*.ts"] + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../dist/out-tsc", + "declaration": true, + "rootDir": "./", + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "test/" + ], + "include": ["**/*.ts"] } - \ No newline at end of file diff --git a/libs/remix-tests/tsconfig.spec.json b/libs/remix-tests/tsconfig.spec.json index 118a64f08e..559410b96a 100644 --- a/libs/remix-tests/tsconfig.spec.json +++ b/libs/remix-tests/tsconfig.spec.json @@ -1,16 +1,15 @@ { - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "include": [ - "**/*.spec.ts", - "**/*.spec.tsx", - "**/*.spec.js", - "**/*.spec.jsx", - "**/*.d.ts" - ] - } - \ No newline at end of file + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.spec.ts", + "**/*.spec.tsx", + "**/*.spec.js", + "**/*.spec.jsx", + "**/*.d.ts" + ] +} From 6ad6a25916c3ff60688272b5e13391f280964843 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 10 Mar 2021 12:57:39 +0100 Subject: [PATCH 107/199] linting --- .../src/execution/execution-context.ts | 2 +- libs/remix-lib/src/execution/txRunnerVM.ts | 7 ++--- libs/remix-lib/src/execution/txRunnerWeb3.ts | 10 +++---- .../src/web3Provider/web3VmProvider.ts | 2 +- .../src/methods/transactions.ts | 7 ++--- libs/remix-simulator/src/methods/txProcess.ts | 3 +- libs/remix-simulator/src/provider.ts | 9 +++--- libs/remix-simulator/src/vm-context.ts | 29 +++++++++---------- 8 files changed, 32 insertions(+), 37 deletions(-) diff --git a/libs/remix-lib/src/execution/execution-context.ts b/libs/remix-lib/src/execution/execution-context.ts index ba067e7035..7644081040 100644 --- a/libs/remix-lib/src/execution/execution-context.ts +++ b/libs/remix-lib/src/execution/execution-context.ts @@ -343,5 +343,5 @@ export class ExecutionContext { if (transactionDetailsLinks[network]) { return transactionDetailsLinks[network] + hash } - } + } } diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts index 3b221f8b75..bc7e1403a7 100644 --- a/libs/remix-lib/src/execution/txRunnerVM.ts +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -27,7 +27,7 @@ export class TxRunnerVM { this.blockNumber = 0 this.runAsync = true this.blockNumber = 0 // The VM is running in Homestead mode, which started at this block. - this.runAsync = false // We have to run like this cause the VM Event Manager does not support running multiple txs at the same time. + this.runAsync = false // We have to run like this cause the VM Event Manager does not support running multiple txs at the same time. this.pendingTxs = {} this.vmaccounts = vmaccounts this.queusTxs = [] @@ -110,11 +110,10 @@ export class TxRunnerVM { result: result, transactionHash: bufferToHex(Buffer.from(tx.hash())), block, - tx, + tx }) }).catch(function (err) { callback(err) }) - } + } } - diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index f735b3401c..4554c396e8 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -65,8 +65,8 @@ export class TxRunnerWeb3 { data = '0x' + data } - return this.runInNode(args.from, args.to, data, args.value, args.gasLimit, args.useCall, args.timestamp, confirmationCb, gasEstimationForceSend, promptCb, callback) - } + return this.runInNode(args.from, args.to, data, args.value, args.gasLimit, args.useCall, args.timestamp, confirmationCb, gasEstimationForceSend, promptCb, callback) + } runInNode (from, to, data, value, gasLimit, useCall, timestamp, confirmCb, gasEstimationForceSend, promptCb, callback) { const tx = { from: from, to: to, data: data, value: value } @@ -76,16 +76,16 @@ export class TxRunnerWeb3 { tx['gas'] = gasLimit tx['timestamp'] = timestamp return this.getWeb3().eth.call(tx, function (error, result: any) { - if (error) return callback(error) + if (error) return callback(error) callback(null, { - result: result + result: result }) }) } this.getWeb3().eth.estimateGas(tx, (err, gasEstimation) => { if (err && err.message.indexOf('Invalid JSON RPC response') !== -1) { // // @todo(#378) this should be removed when https://github.com/WalletConnect/walletconnect-monorepo/issues/334 is fixed - new Error('Gas estimation failed because of an unknown internal error. This may indicated that the transaction will fail.') + callback(new Error('Gas estimation failed because of an unknown internal error. This may indicated that the transaction will fail.')) } gasEstimationForceSend(err, () => { // callback is called whenever no error diff --git a/libs/remix-lib/src/web3Provider/web3VmProvider.ts b/libs/remix-lib/src/web3Provider/web3VmProvider.ts index 361c2b7161..59b0e7e909 100644 --- a/libs/remix-lib/src/web3Provider/web3VmProvider.ts +++ b/libs/remix-lib/src/web3Provider/web3VmProvider.ts @@ -74,7 +74,7 @@ export class Web3VmProvider { this.utils = Web3.utils || [] this.txsMapBlock = {} this.blocks = {} - this.latestBlockNumber + this.latestBlockNumber = 0 } setVM (vm) { diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index 04ef986403..969eb0ff6f 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -7,7 +7,6 @@ export class Transactions { accounts tags - constructor (vmContext) { this.vmContext = vmContext this.tags = {} @@ -44,7 +43,7 @@ export class Transactions { const hash = '0x' + result.tx.hash().toString('hex') this.vmContext.trackTx(hash, result.block) this.vmContext.trackExecResult(hash, result.result.execResult) - return cb (null, result.transactionHash) + return cb(null, result.transactionHash) } cb(error) }) @@ -110,7 +109,7 @@ export class Transactions { } payload.params[0].value = undefined - + const tag = payload.params[0].timestamp // e2e reference processTx(this.vmContext, this.accounts, payload, true, (error, result) => { @@ -122,7 +121,7 @@ export class Transactions { this.tags[tag] = result.transactionHash // calls are not supposed to return a transaction hash. we do this for keeping track of it and allowing debugging calls. const returnValue = `0x${result.result.execResult.returnValue.toString('hex') || '0'}` - return cb (null, returnValue) + return cb(null, returnValue) } cb(error) }) diff --git a/libs/remix-simulator/src/methods/txProcess.ts b/libs/remix-simulator/src/methods/txProcess.ts index 821206eae8..d51bbf9c73 100644 --- a/libs/remix-simulator/src/methods/txProcess.ts +++ b/libs/remix-simulator/src/methods/txProcess.ts @@ -3,12 +3,11 @@ const TxExecution = execution.txExecution const TxRunnerVM = execution.TxRunnerVM const TxRunner = execution.TxRunner - function runCall (payload, from, to, data, value, gasLimit, txRunner, callbacks, callback) { const finalCallback = function (err, result) { if (err) { return callback(err) - } + } return callback(null, result) } diff --git a/libs/remix-simulator/src/provider.ts b/libs/remix-simulator/src/provider.ts index 5046660d7f..276b66ca15 100644 --- a/libs/remix-simulator/src/provider.ts +++ b/libs/remix-simulator/src/provider.ts @@ -26,7 +26,7 @@ export class Provider { this.host = host this.connected = true this.vmContext = new VMContext() - + this.Accounts = new Accounts(this.vmContext) this.Transactions = new Transactions(this.vmContext) @@ -102,7 +102,7 @@ export function extend (web3) { call: 'eth_getExecutionResultFromSimulator', inputFormatter: [null], params: 1 - })) + })) } if (!(web3.eth && web3.eth.getHashFromTagBySimulator)) { @@ -111,9 +111,9 @@ export function extend (web3) { call: 'eth_getHashFromTagBySimulator', inputFormatter: [null], params: 1 - })) + })) } - + if (methods.length > 0) { web3.extend({ property: 'eth', @@ -122,4 +122,3 @@ export function extend (web3) { }) } } - diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index 481f5f4057..e59eb68cdd 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -75,8 +75,8 @@ export class VMContext { web3vm logsManager exeResults - - constructor () { + + constructor () { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault this.currentFork = 'muirGlacier' @@ -94,7 +94,6 @@ export class VMContext { this.txs = {} this.exeResults = {} this.logsManager = new execution.LogsManager() - } createVm (hardfork) { @@ -124,20 +123,20 @@ export class VMContext { return this.vms[this.currentFork].vm } - addBlock (block) { - let blockNumber = '0x' + block.header.number.toString('hex') - if (blockNumber === '0x') { - blockNumber = '0x0' - } - - this.blocks['0x' + block.hash().toString('hex')] = block - this.blocks[blockNumber] = block - this.latestBlockNumber = blockNumber + addBlock (block) { + let blockNumber = '0x' + block.header.number.toString('hex') + if (blockNumber === '0x') { + blockNumber = '0x0' + } + + this.blocks['0x' + block.hash().toString('hex')] = block + this.blocks[blockNumber] = block + this.latestBlockNumber = blockNumber - this.logsManager.checkBlock(blockNumber, block, this.web3vm) - } + this.logsManager.checkBlock(blockNumber, block, this.web3vm) + } - trackTx (tx, block) { + trackTx (tx, block) { this.txs[tx] = block } From 19cfcb294dfe151d18c35fd33957e499843b8f33 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 11 Mar 2021 13:02:39 +0100 Subject: [PATCH 108/199] fix tests --- .circleci/config.yml | 1 + libs/remix-simulator/package.json | 2 +- libs/remix-solidity/package.json | 2 +- libs/remix-tests/jest.config.js | 3 ++- libs/remix-tests/package.json | 6 +++--- libs/remix-tests/tests/testRunner.cli.spec.ts | 4 +--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ab5e15436f..49aada7eb0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,6 +51,7 @@ jobs: - checkout - run: npm install - run: npm run build:libs + - run: export NODE_OPTIONS="--max_old_space_size=8192" - run: npm run test:libs remix-ide-chrome-1: diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index eb09b20106..b39deedf5a 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -14,7 +14,7 @@ ], "main": "src/index.js", "dependencies": { - "@remix-project/remix-lib": "^0.4.34", + "@remix-project/remix-lib": "../remix-lib", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index ddb834e951..7a54cfe8d7 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -15,7 +15,7 @@ } ], "dependencies": { - "@remix-project/remix-lib": "^0.4.34", + "@remix-project/remix-lib": "../remix-lib", "eslint-scope": "^5.0.0", "@ethereumjs/vm": "^5.3.2", "@ethereumjs/block": "^3.2.1", diff --git a/libs/remix-tests/jest.config.js b/libs/remix-tests/jest.config.js index dcbd823a5c..0f08d413b7 100644 --- a/libs/remix-tests/jest.config.js +++ b/libs/remix-tests/jest.config.js @@ -1,11 +1,12 @@ module.exports = { name: 'remix-tests', preset: '../../jest.config.js', - verbose: false, + verbose: true, silent: false, // Silent console messages, specially the 'remix-simulator' ones transform: { '^.+\\.[tj]sx?$': 'ts-jest', }, + transformIgnorePatterns: ["/node_modules/", "\\.pnp\\.[^\\\/]+$"], rootDir: "./", testTimeout: 40000, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html', 'json'], diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index a2480bfa46..9adf364e2d 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -35,9 +35,9 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-tests#readme", "dependencies": { - "@remix-project/remix-lib": "^0.4.34", - "@remix-project/remix-simulator": "^0.1.10-beta.0", - "@remix-project/remix-solidity": "^0.3.35", + "@remix-project/remix-lib": "../remix-lib", + "@remix-project/remix-simulator": "../remix-simulator", + "@remix-project/remix-solidity": "../remix-solidity", "ansi-gray": "^0.1.1", "async": "^2.6.0", "axios": ">=0.21.1", diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index a865bbc649..21ce34afdb 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -10,9 +10,7 @@ describe('testRunner: remix-tests CLI', () => { if(result) { const dirContent = result.stdout.toString() // Install dependencies if 'node_modules' is not already present - if(!dirContent.includes('node_modules')) execSync( - 'ln -s ' + __dirname + '/../../../node_modules node_modules', - { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) + if(!dirContent.includes('node_modules')) execSync('npm install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) } From 4665cc7dd24e3c2f0ccd09f2cf1fb5734391bbd5 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 11 Mar 2021 14:17:47 +0100 Subject: [PATCH 109/199] linting --- .vscode/settings.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..2fb99dc19e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "ethcode.keystore.keyStorePath": "/home/yann/.vscode/extensions/ethential.ethcode-0.2.2", + "ethcode.userConfig.defaultAccount": null +} \ No newline at end of file From aefc8975b2f19dce7b238a0663bc72d4fd7e3c12 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 11 Mar 2021 14:42:28 +0100 Subject: [PATCH 110/199] fix e2e tests --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 448642f4b5..dc4fc9d462 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -62,7 +62,8 @@ module.exports = { 'Call web3.eth.getAccounts() using JavaScript VM': function (browser: NightwatchBrowser) { browser .executeScript('web3.eth.getAccounts()') - .waitForElementContainsText('*[data-id="terminalJournal"]', '[ "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678", "0x03C6FcED478cBbC9a4FAB34eF9f40767739D1Ff7", "0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C", "0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC", "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148" ]', 60000) + .pause(2000) + .waitForElementContainsText('*[data-id="terminalJournal"]', '[ "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678", "0x03C6FcED478cBbC9a4FAB34eF9f40767739D1Ff7", "0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C", "0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC", "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148" ]', 60000) }, 'Call web3.eth.getAccounts() using Web3 Provider': function (browser: NightwatchBrowser) { From c77a3e109b62e6a8b7a5af3f0fc3dfdccfa383fb Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Mar 2021 11:13:47 +0100 Subject: [PATCH 111/199] move execution-context --- apps/remix-ide/src/blockchain/blockchain.js | 4 +- .../src/blockchain/execution-context.js | 39 ++++++------------- libs/remix-lib/src/execution/txListener.ts | 3 +- libs/remix-lib/src/index.ts | 2 - libs/remix-lib/test/txFormat.ts | 3 -- 5 files changed, 15 insertions(+), 36 deletions(-) rename libs/remix-lib/src/execution/execution-context.ts => apps/remix-ide/src/blockchain/execution-context.js (90%) diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 09ca8a05a2..973e267683 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -7,7 +7,7 @@ const TxRunner = remixLib.execution.TxRunner const TxRunnerWeb3 = remixLib.execution.TxRunnerWeb3 const txHelper = remixLib.execution.txHelper const EventManager = remixLib.EventManager -const executionContext = remixLib.execution.executionContext +const { ExecutionContext } = require('./execution-context') const Web3 = require('web3') const async = require('async') @@ -23,7 +23,7 @@ class Blockchain { // NOTE: the config object will need to be refactored out in remix-lib constructor (config) { this.event = new EventManager() - this.executionContext = executionContext + this.executionContext = new ExecutionContext() this.events = new EventEmitter() this.config = config diff --git a/libs/remix-lib/src/execution/execution-context.ts b/apps/remix-ide/src/blockchain/execution-context.js similarity index 90% rename from libs/remix-lib/src/execution/execution-context.ts rename to apps/remix-ide/src/blockchain/execution-context.js index 7644081040..df2d9421bb 100644 --- a/libs/remix-lib/src/execution/execution-context.ts +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -1,19 +1,17 @@ /* global ethereum */ 'use strict' import Web3 from 'web3' -import { EventManager } from '../eventManager' +import EventManager from '../lib/events' import { rlp, keccak, bufferToHex } from 'ethereumjs-util' import { Web3VmProvider } from '../web3Provider/web3VmProvider' import VM from '@ethereumjs/vm' import Common from '@ethereumjs/common' import StateManager from '@ethereumjs/vm/dist/state/stateManager' -import { StorageDump } from '@ethereumjs/vm/dist/state/interface' -declare let ethereum: any let web3 -if (typeof window !== 'undefined' && typeof window['ethereum'] !== 'undefined') { - var injectedProvider = window['ethereum'] +if (typeof window !== 'undefined' && typeof window.ethereum !== 'undefined') { + var injectedProvider = window.ethereum web3 = new Web3(injectedProvider) } else { web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) @@ -24,12 +22,13 @@ if (typeof window !== 'undefined' && typeof window['ethereum'] !== 'undefined') */ class StateManagerCommonStorageDump extends StateManager { - /* - * dictionary containing keccak(b) as key and b as value. used to get the initial value from its hash - */ - keyHashes: { [key: string]: string } + constructor () { super() + /* + * dictionary containing keccak(b) as key and b as value. used to get the initial value from its hash. + * type: { [key: string]: string } + */ this.keyHashes = {} } @@ -46,7 +45,7 @@ class StateManagerCommonStorageDump extends StateManager { console.log(e) throw e } - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { try { const storage = {} const stream = trie.createReadStream() @@ -66,14 +65,14 @@ class StateManagerCommonStorageDump extends StateManager { }) } - async getStateRoot (force: boolean = false): Promise { + async getStateRoot (force = false) { await this._cache.flush() const stateRoot = this._trie.root return stateRoot } - async setStateRoot (stateRoot: Buffer): Promise { + async setStateRoot (stateRoot) { await this._cache.flush() if (stateRoot === this._trie.EMPTY_TRIE_ROOT) { @@ -98,20 +97,6 @@ class StateManagerCommonStorageDump extends StateManager { trigger contextChanged, web3EndpointChanged */ export class ExecutionContext { - event - blockGasLimitDefault: number - blockGasLimit: number - customNetWorks - blocks - latestBlockNumber - txs - executionContext: string - listenOnLastBlockId - currentFork: string - vms - mainNetGenesisHash: string - customWeb3: { [key: string]: Web3 } - constructor () { this.event = new EventManager() this.executionContext = null @@ -171,7 +156,7 @@ export class ExecutionContext { return this.executionContext === 'vm' } - setWeb3 (context: string, web3: Web3) { + setWeb3 (context, web3) { this.customWeb3[context] = web3 } diff --git a/libs/remix-lib/src/execution/txListener.ts b/libs/remix-lib/src/execution/txListener.ts index 967b8ee3a8..2ec85c3fc9 100644 --- a/libs/remix-lib/src/execution/txListener.ts +++ b/libs/remix-lib/src/execution/txListener.ts @@ -4,7 +4,6 @@ import { ethers } from 'ethers' import { toBuffer } from 'ethereumjs-util' import { EventManager } from '../eventManager' import { compareByteCode } from '../util' -import { ExecutionContext } from './execution-context' import { decodeResponse } from './txFormat' import { getFunction, getReceiveInterface, getConstructorInterface, visitContracts, makeFullTypeDefinition } from './txHelper' @@ -40,7 +39,7 @@ export class TxListener { constructor (opt, executionContext) { this.event = new EventManager() // has a default for now for backwards compatability - this.executionContext = executionContext || new ExecutionContext() + this.executionContext = executionContext this._api = opt.api this._resolvedTransactions = {} this._resolvedContracts = {} diff --git a/libs/remix-lib/src/index.ts b/libs/remix-lib/src/index.ts index afcd0beae6..ae3864a8c9 100644 --- a/libs/remix-lib/src/index.ts +++ b/libs/remix-lib/src/index.ts @@ -13,7 +13,6 @@ import * as txFormat from './execution/txFormat' import { TxListener } from './execution/txListener' import { TxRunner } from './execution/txRunner' import { LogsManager } from './execution/logsManager' -import { ExecutionContext } from './execution/execution-context' import * as typeConversion from './execution/typeConversion' import { TxRunnerVM } from './execution/txRunnerVM' import { TxRunnerWeb3 } from './execution/txRunnerWeb3' @@ -40,7 +39,6 @@ function modules () { EventsDecoder: EventsDecoder, txExecution: txExecution, txHelper: txHelper, - executionContext: new ExecutionContext(), txFormat: txFormat, txListener: TxListener, TxRunner: TxRunner, diff --git a/libs/remix-lib/test/txFormat.ts b/libs/remix-lib/test/txFormat.ts index 2ab4a59b63..8bff069fc2 100644 --- a/libs/remix-lib/test/txFormat.ts +++ b/libs/remix-lib/test/txFormat.ts @@ -5,8 +5,6 @@ import * as txHelper from '../src/execution/txHelper' import { hexToIntArray } from '../src/util' let compiler = require('solc') import { compilerInput } from '../src/helpers/compilerHelper' -import { ExecutionContext } from '../src/execution/execution-context' -const executionContext = new ExecutionContext() const solidityVersion = 'v0.6.0+commit.26b70077' /* tape *********************************************************** */ @@ -151,7 +149,6 @@ function testInvalidTupleInput (st, params) { /* tape *********************************************************** */ tape('ContractParameters - (TxFormat.buildData) - link Libraries', function (t) { - executionContext.setContext('vm', null, null, null) const compileData = compiler.compile(compilerInput(deploySimpleLib)) const fakeDeployedContracts = { From 165bc81cd01a70cb01d5b951aafc7339ebf46376 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Mar 2021 13:44:16 +0100 Subject: [PATCH 112/199] remove uneeded execution-context reference --- .../src/methods/transactions.ts | 33 +++++++++++++++-- libs/remix-simulator/src/methods/txProcess.ts | 35 +------------------ 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index 969eb0ff6f..ef72acfe09 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -1,11 +1,16 @@ import Web3 from 'web3' import { toChecksumAddress, BN, Address } from 'ethereumjs-util' import { processTx } from './txProcess' +import { execution } from '@remix-project/remix-lib' +const TxRunnerVM = execution.TxRunnerVM +const TxRunner = execution.TxRunner export class Transactions { vmContext accounts tags + txRunnerVMInstance + txRunnerInstance constructor (vmContext) { this.vmContext = vmContext @@ -14,6 +19,30 @@ export class Transactions { init (accounts) { this.accounts = accounts + const api = { + logMessage: (msg) => { + }, + logHtmlMessage: (msg) => { + }, + config: { + getUnpersistedProperty: (key) => { + return true + }, + get: () => { + return true + } + }, + detectNetwork: (cb) => { + cb() + }, + personalMode: () => { + return false + } + } + + this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vm()) + this.txRunnerInstance = new TxRunner(this.txRunnerVMInstance, { runAsync: false }) + this.txRunnerInstance.vmaccounts = accounts } methods () { @@ -37,7 +66,7 @@ export class Transactions { if (payload.params && payload.params.length > 0 && payload.params[0].from) { payload.params[0].from = toChecksumAddress(payload.params[0].from) } - processTx(this.vmContext, this.accounts, payload, false, (error, result) => { + processTx(this.txRunnerInstance, payload, false, (error, result) => { if (!error && result) { this.vmContext.addBlock(result.block) const hash = '0x' + result.tx.hash().toString('hex') @@ -112,7 +141,7 @@ export class Transactions { const tag = payload.params[0].timestamp // e2e reference - processTx(this.vmContext, this.accounts, payload, true, (error, result) => { + processTx(this.txRunnerInstance, payload, true, (error, result) => { if (!error && result) { this.vmContext.addBlock(result.block) const hash = '0x' + result.tx.hash().toString('hex') diff --git a/libs/remix-simulator/src/methods/txProcess.ts b/libs/remix-simulator/src/methods/txProcess.ts index d51bbf9c73..75173af309 100644 --- a/libs/remix-simulator/src/methods/txProcess.ts +++ b/libs/remix-simulator/src/methods/txProcess.ts @@ -1,7 +1,5 @@ import { execution } from '@remix-project/remix-lib' const TxExecution = execution.txExecution -const TxRunnerVM = execution.TxRunnerVM -const TxRunner = execution.TxRunner function runCall (payload, from, to, data, value, gasLimit, txRunner, callbacks, callback) { const finalCallback = function (err, result) { @@ -36,38 +34,7 @@ function createContract (payload, from, data, value, gasLimit, txRunner, callbac TxExecution.createContract(from, data, value, gasLimit, txRunner, callbacks, finalCallback) } -let txRunnerVMInstance -let txRunnerInstance - -export function processTx (vmContext, accounts, payload, isCall, callback) { - const api = { - logMessage: (msg) => { - }, - logHtmlMessage: (msg) => { - }, - config: { - getUnpersistedProperty: (key) => { - return true - }, - get: () => { - return true - } - }, - detectNetwork: (cb) => { - cb() - }, - personalMode: () => { - return false - } - } - - if (!txRunnerVMInstance) { - txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => vmContext.vm()) - } - if (!txRunnerInstance) { - txRunnerInstance = new TxRunner(txRunnerVMInstance, { runAsync: false }) - } - txRunnerInstance.vmaccounts = accounts +export function processTx (txRunnerInstance, payload, isCall, callback) { let { from, to, data, value, gas } = payload.params[0] gas = gas || 3000000 From e5a0f5c95685201bff38ad97843c0b8f999e71ce Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Mar 2021 13:55:30 +0100 Subject: [PATCH 113/199] linting --- libs/remix-simulator/src/methods/transactions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index ef72acfe09..fee5059d96 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -39,7 +39,7 @@ export class Transactions { return false } } - + this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vm()) this.txRunnerInstance = new TxRunner(this.txRunnerVMInstance, { runAsync: false }) this.txRunnerInstance.vmaccounts = accounts From 7abd9e5004b5eaa82370aef07fa5fa404e2af89e Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Mar 2021 15:35:20 +0100 Subject: [PATCH 114/199] fix e2e --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index dc4fc9d462..2a17251179 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -63,7 +63,7 @@ module.exports = { browser .executeScript('web3.eth.getAccounts()') .pause(2000) - .waitForElementContainsText('*[data-id="terminalJournal"]', '[ "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4", "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB", "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2", "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db", "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678", "0x03C6FcED478cBbC9a4FAB34eF9f40767739D1Ff7", "0x1aE0EA34a72D944a8C7603FfB3eC30a6669E454C", "0x0A098Eda01Ce92ff4A4CCb7A4fFFb5A43EBC70DC", "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148" ]', 60000) + .waitForElementContainsText('*[data-id="terminalJournal"]', '"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148"', 60000) }, 'Call web3.eth.getAccounts() using Web3 Provider': function (browser: NightwatchBrowser) { From d839c5197f42fcdca27b03cb6f6478b01d44f939 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 3 May 2021 15:35:26 +0200 Subject: [PATCH 115/199] fix vmContext & txRunnerVM --- .../src/blockchain/execution-context.js | 112 ---------------- libs/remix-lib/src/execution/txRunnerVM.ts | 96 ++++++------- .../src/methods/transactions.ts | 2 +- libs/remix-simulator/src/vm-context.ts | 126 +++++++++++------- 4 files changed, 125 insertions(+), 211 deletions(-) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index df2d9421bb..41588e3708 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -2,11 +2,6 @@ 'use strict' import Web3 from 'web3' import EventManager from '../lib/events' -import { rlp, keccak, bufferToHex } from 'ethereumjs-util' -import { Web3VmProvider } from '../web3Provider/web3VmProvider' -import VM from '@ethereumjs/vm' -import Common from '@ethereumjs/common' -import StateManager from '@ethereumjs/vm/dist/state/stateManager' let web3 @@ -17,82 +12,6 @@ if (typeof window !== 'undefined' && typeof window.ethereum !== 'undefined') { web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')) } -/* - extend vm state manager and instanciate VM -*/ - -class StateManagerCommonStorageDump extends StateManager { - - constructor () { - super() - /* - * dictionary containing keccak(b) as key and b as value. used to get the initial value from its hash. - * type: { [key: string]: string } - */ - this.keyHashes = {} - } - - putContractStorage (address, key, value) { - this.keyHashes[keccak(key).toString('hex')] = bufferToHex(key) - return super.putContractStorage(address, key, value) - } - - async dumpStorage (address) { - let trie - try { - trie = await this._getStorageTrie(address) - } catch (e) { - console.log(e) - throw e - } - return new Promise((resolve, reject) => { - try { - const storage = {} - const stream = trie.createReadStream() - stream.on('data', (val) => { - const value = rlp.decode(val.value) - storage['0x' + val.key.toString('hex')] = { - key: this.keyHashes[val.key.toString('hex')], - value: '0x' + value.toString('hex') - } - }) - stream.on('end', function () { - resolve(storage) - }) - } catch (e) { - reject(e) - } - }) - } - - async getStateRoot (force = false) { - await this._cache.flush() - - const stateRoot = this._trie.root - return stateRoot - } - - async setStateRoot (stateRoot) { - await this._cache.flush() - - if (stateRoot === this._trie.EMPTY_TRIE_ROOT) { - this._trie.root = stateRoot - this._cache.clear() - this._storageTries = {} - return - } - - const hasRoot = await this._trie.checkRoot(stateRoot) - if (!hasRoot) { - throw new Error('State trie does not contain state root') - } - - this._trie.root = stateRoot - this._cache.clear() - this._storageTries = {} - } -} - /* trigger contextChanged, web3EndpointChanged */ @@ -103,15 +22,6 @@ export class ExecutionContext { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault this.currentFork = 'berlin' - this.vms = { - /* - byzantium: createVm('byzantium'), - constantinople: createVm('constantinople'), - petersburg: createVm('petersburg'), - istanbul: createVm('istanbul'), - */ - berlin: this.createVm('berlin') - } this.mainNetGenesisHash = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' this.customNetWorks = {} this.blocks = {} @@ -129,20 +39,6 @@ export class ExecutionContext { } } - createVm (hardfork) { - const stateManager = new StateManagerCommonStorageDump() - const common = new Common({ chain: 'mainnet', hardfork }) - const vm = new VM({ - common, - activatePrecompiles: true, - stateManager: stateManager - }) - - const web3vm = new Web3VmProvider() - web3vm.setVM(vm) - return { vm, web3vm, stateManager, common } - } - askPermission () { // metamask if (ethereum && typeof ethereum.enable === 'function') ethereum.enable() @@ -217,14 +113,6 @@ export class ExecutionContext { return new Web3() } - vm () { - return this.vms[this.currentFork].vm - } - - vmObject () { - return this.vms[this.currentFork] - } - setContext (context, endPointUrl, confirmCb, infoCb) { this.executionContext = context this.executionContextChange(context, endPointUrl, confirmCb, infoCb, null) diff --git a/libs/remix-lib/src/execution/txRunnerVM.ts b/libs/remix-lib/src/execution/txRunnerVM.ts index bc7e1403a7..ba021a7d0e 100644 --- a/libs/remix-lib/src/execution/txRunnerVM.ts +++ b/libs/remix-lib/src/execution/txRunnerVM.ts @@ -1,13 +1,12 @@ 'use strict' -import { Transaction } from 'ethereumjs-tx' -import Block from 'ethereumjs-block' -import { BN, bufferToHex } from 'ethereumjs-util' +import { Transaction } from '@ethereumjs/tx' +import { Block } from '@ethereumjs/block' +import { BN, bufferToHex, Address } from 'ethereumjs-util' import { EventManager } from '../eventManager' import { LogsManager } from './logsManager' export class TxRunnerVM { event - _api blockNumber runAsync pendingTxs @@ -16,14 +15,15 @@ export class TxRunnerVM { blocks txs logsManager - getVM: () => any + commonContext + getVMObject: () => any - constructor (vmaccounts, api, getVM) { + constructor (vmaccounts, api, getVMObject) { this.event = new EventManager() this.logsManager = new LogsManager() // has a default for now for backwards compatability - this.getVM = getVM - this._api = api + this.getVMObject = getVMObject + this.commonContext = this.getVMObject().common this.blockNumber = 0 this.runAsync = true this.blockNumber = 0 // The VM is running in Homestead mode, which started at this block. @@ -53,54 +53,56 @@ export class TxRunnerVM { if (!account) { return callback('Invalid account selected') } + if (Number.isInteger(gasLimit)) { + gasLimit = '0x' + gasLimit.toString(16) + } + + this.getVMObject().stateManager.getAccount(Address.fromString(from)).then((res) => { + // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor + // for initialization fields and their types + value = value ? parseInt(value) : 0 + const tx = Transaction.fromTxData({ + nonce: new BN(res.nonce), + gasPrice: '0x1', + gasLimit: gasLimit, + to: to, + value: value, + data: Buffer.from(data.slice(2), 'hex') + }, { common: this.commonContext }).sign(account.privateKey) + + const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] + const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] + + var block = Block.fromBlockData({ + header: { + timestamp: timestamp || (new Date().getTime() / 1000 | 0), + number: self.blockNumber, + coinbase: coinbases[self.blockNumber % coinbases.length], + difficulty: difficulties[self.blockNumber % difficulties.length], + gasLimit: new BN(gasLimit.replace('0x', ''), 16).imuln(2) + }, + transactions: [tx] + }, { common: this.commonContext }) - this.getVM().stateManager.getAccount(Buffer.from(from.replace('0x', ''), 'hex'), (err, res) => { - if (err) { - callback('Account not found') + if (!useCall) { + ++self.blockNumber + this.runBlockInVm(tx, block, callback) } else { - // See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor - // for initialization fields and their types - value = value ? parseInt(value) : 0 - const tx = new Transaction({ - nonce: new BN(res.nonce), - gasPrice: '0x1', - gasLimit: gasLimit, - to: to, - value: value, - data: Buffer.from(data.slice(2), 'hex') - }) - tx.sign(account.privateKey) - const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e'] - const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)] - const block = new Block({ - header: { - timestamp: timestamp || (new Date().getTime() / 1000 | 0), - number: self.blockNumber, - coinbase: coinbases[self.blockNumber % coinbases.length], - difficulty: difficulties[self.blockNumber % difficulties.length], - gasLimit: new BN(gasLimit, 10).imuln(2) - }, - transactions: [tx], - uncleHeaders: [] - }) - if (!useCall) { - ++self.blockNumber - this.runBlockInVm(tx, block, callback) - } else { - this.getVM().stateManager.checkpoint(() => { - this.runBlockInVm(tx, block, (err, result) => { - this.getVM().stateManager.revert(() => { - callback(err, result) - }) + this.getVMObject().stateManager.checkpoint().then(() => { + this.runBlockInVm(tx, block, (err, result) => { + this.getVMObject().stateManager.revert().then(() => { + callback(err, result) }) }) - } + }) } + }).catch((e) => { + callback(e) }) } runBlockInVm (tx, block, callback) { - this.getVM().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then((results) => { + this.getVMObject().vm.runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then((results) => { const result = results.results[0] if (result) { const status = result.execResult.exceptionError ? 0 : 1 diff --git a/libs/remix-simulator/src/methods/transactions.ts b/libs/remix-simulator/src/methods/transactions.ts index fee5059d96..c3a43f5bc4 100644 --- a/libs/remix-simulator/src/methods/transactions.ts +++ b/libs/remix-simulator/src/methods/transactions.ts @@ -40,7 +40,7 @@ export class Transactions { } } - this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vm()) + this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vmObject()) this.txRunnerInstance = new TxRunner(this.txRunnerVMInstance, { runAsync: false }) this.txRunnerInstance.vmaccounts = accounts } diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index e59eb68cdd..43f5f6f8c9 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -2,61 +2,82 @@ 'use strict' import Web3 from 'web3' import { rlp, keccak, bufferToHex } from 'ethereumjs-util' -import { vm, execution } from '@remix-project/remix-lib' -const EthJSVM = require('ethereumjs-vm').default -const StateManager = require('ethereumjs-vm/dist/state/stateManager').default +import { vm as remixLibVm, execution } from '@remix-project/remix-lib' +import VM from '@ethereumjs/vm' +import Common from '@ethereumjs/common' +import StateManager from '@ethereumjs/vm/dist/state/stateManager' +import { StorageDump } from '@ethereumjs/vm/dist/state/interface' /* extend vm state manager and instanciate VM */ class StateManagerCommonStorageDump extends StateManager { - constructor (arg) { - super(arg) + + keyHashes: { [key: string]: string } + constructor () { + super() this.keyHashes = {} } - putContractStorage (address, key, value, cb) { + putContractStorage (address, key, value) { this.keyHashes[keccak(key).toString('hex')] = bufferToHex(key) - super.putContractStorage(address, key, value, cb) + return super.putContractStorage(address, key, value) } - dumpStorage (address, cb) { - this._getStorageTrie(address, (err, trie) => { - if (err) { - return cb(err) + async dumpStorage (address) { + let trie + try { + trie = await this._getStorageTrie(address) + } catch (e) { + console.log(e) + throw e + } + return new Promise((resolve, reject) => { + try { + const storage = {} + const stream = trie.createReadStream() + stream.on('data', (val) => { + const value = rlp.decode(val.value) + storage['0x' + val.key.toString('hex')] = { + key: this.keyHashes[val.key.toString('hex')], + value: '0x' + value.toString('hex') + } + }) + stream.on('end', function () { + resolve(storage) + }) + } catch (e) { + reject(e) } - const storage = {} - const stream = trie.createReadStream() - stream.on('data', (val) => { - const value = rlp.decode(val.value) - storage['0x' + val.key.toString('hex')] = { - key: this.keyHashes[val.key.toString('hex')], - value: '0x' + value.toString('hex') - } - }) - stream.on('end', function () { - cb(storage) - }) }) } - getStateRoot (cb) { - const checkpoint = this._checkpointCount - this._checkpointCount = 0 - super.getStateRoot((err, stateRoot) => { - this._checkpointCount = checkpoint - cb(err, stateRoot) - }) + async getStateRoot (force = false) { + await this._cache.flush() + + const stateRoot = this._trie.root + return stateRoot } - setStateRoot (stateRoot, cb) { - const checkpoint = this._checkpointCount - this._checkpointCount = 0 - super.setStateRoot(stateRoot, (err) => { - this._checkpointCount = checkpoint - cb(err) - }) + async setStateRoot (stateRoot) { + await this._cache.flush() + + if (stateRoot === this._trie.EMPTY_TRIE_ROOT) { + this._trie.root = stateRoot + this._cache.clear() + this._storageTries = {} + return + } + + const hasRoot = await this._trie.checkRoot(stateRoot) + if (!hasRoot) { + throw new Error('State trie does not contain state root') + } + + this._trie.root = stateRoot + this._cache.clear() + this._storageTries = {} } } @@ -79,7 +100,7 @@ export class VMContext { constructor () { this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault - this.currentFork = 'muirGlacier' + this.currentFork = 'berlin' this.vms = { /* byzantium: createVm('byzantium'), @@ -87,7 +108,7 @@ export class VMContext { petersburg: createVm('petersburg'), istanbul: createVm('istanbul'), */ - muirGlacier: this.createVm('muirGlacier') + berlin: this.createVm('berlin') } this.blocks = {} this.latestBlockNumber = 0 @@ -97,22 +118,21 @@ export class VMContext { } createVm (hardfork) { - const stateManager = new StateManagerCommonStorageDump({}) - stateManager.checkpoint(() => {}) - const ethvm = new EthJSVM({ + const stateManager = new StateManagerCommonStorageDump() + const common = new Common({ chain: 'mainnet', hardfork }) + const vm = new VM({ + common, activatePrecompiles: true, - blockchain: stateManager.blockchain, - stateManager: stateManager, - hardfork: hardfork + stateManager: stateManager }) - ethvm.blockchain.validate = false - this.web3vm = new vm.Web3VMProvider() - this.web3vm.setVM(ethvm) - return { vm: ethvm, web3vm: this.web3vm, stateManager } + + const web3vm = new remixLibVm.Web3VMProvider() + web3vm.setVM(vm) + return { vm, web3vm, stateManager, common } } web3 () { - return this.web3vm + return this.vms[this.currentFork].web3vm } blankWeb3 () { @@ -123,6 +143,10 @@ export class VMContext { return this.vms[this.currentFork].vm } + vmObject () { + return this.vms[this.currentFork] + } + addBlock (block) { let blockNumber = '0x' + block.header.number.toString('hex') if (blockNumber === '0x') { @@ -133,7 +157,7 @@ export class VMContext { this.blocks[blockNumber] = block this.latestBlockNumber = blockNumber - this.logsManager.checkBlock(blockNumber, block, this.web3vm) + this.logsManager.checkBlock(blockNumber, block, this.web3()) } trackTx (tx, block) { From e08291a7ac59fe2278855363aa1ecf873b56aa6d Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 3 May 2021 15:50:36 +0200 Subject: [PATCH 116/199] linting --- libs/remix-lib/src/execution/txRunner.ts | 2 +- libs/remix-simulator/src/vm-context.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/remix-lib/src/execution/txRunner.ts b/libs/remix-lib/src/execution/txRunner.ts index 254b4b0474..e58ac62d5e 100644 --- a/libs/remix-lib/src/execution/txRunner.ts +++ b/libs/remix-lib/src/execution/txRunner.ts @@ -45,4 +45,4 @@ function run (self, tx, stamp, confirmationCb, gasEstimationForceSend = null, pr run(self, next.tx, next.stamp, next.callback) } }) -} \ No newline at end of file +} diff --git a/libs/remix-simulator/src/vm-context.ts b/libs/remix-simulator/src/vm-context.ts index 43f5f6f8c9..a72be89d1e 100644 --- a/libs/remix-simulator/src/vm-context.ts +++ b/libs/remix-simulator/src/vm-context.ts @@ -13,7 +13,6 @@ import { StorageDump } from '@ethereumjs/vm/dist/state/interface' */ class StateManagerCommonStorageDump extends StateManager { - keyHashes: { [key: string]: string } constructor () { super() From 70b1f6d5ceb28b771005927878a420ab4b9b3eea Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 3 May 2021 15:57:04 +0200 Subject: [PATCH 117/199] linting --- .vscode/settings.json | 4 ---- apps/remix-ide/src/blockchain/providers/vm.js | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 2fb99dc19e..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "ethcode.keystore.keyStorePath": "/home/yann/.vscode/extensions/ethential.ethcode-0.2.2", - "ethcode.userConfig.defaultAccount": null -} \ No newline at end of file diff --git a/apps/remix-ide/src/blockchain/providers/vm.js b/apps/remix-ide/src/blockchain/providers/vm.js index c251743e2b..e01b7b08d2 100644 --- a/apps/remix-ide/src/blockchain/providers/vm.js +++ b/apps/remix-ide/src/blockchain/providers/vm.js @@ -1,5 +1,5 @@ const Web3 = require('web3') -const { BN, privateToAddress, stripHexPrefix, hashPersonalMessage } = require('ethereumjs-util') +const { BN, privateToAddress, hashPersonalMessage } = require('ethereumjs-util') const { Provider, extend } = require('@remix-project/remix-simulator') class VMProvider { From 23c8cd0c5bc7e752f14357ceb104c2d981ec2b9d Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 4 May 2021 14:37:59 +0200 Subject: [PATCH 118/199] update e2e tests --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 2a17251179..a7d43153fa 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -62,8 +62,7 @@ module.exports = { 'Call web3.eth.getAccounts() using JavaScript VM': function (browser: NightwatchBrowser) { browser .executeScript('web3.eth.getAccounts()') - .pause(2000) - .waitForElementContainsText('*[data-id="terminalJournal"]', '"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148"', 60000) + .waitForElementContainsText('*[data-id="terminalJournal"]', '"0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c", "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB", "0x583031D1113aD414F02576BD6afaBfb302140225", "0xdD870fA1b7C4700F2BD7f44238821C26f7392148"', 80000) }, 'Call web3.eth.getAccounts() using Web3 Provider': function (browser: NightwatchBrowser) { From 273d85b56e343ff2456612c9289460bd2a629f78 Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 6 May 2021 20:13:45 +0200 Subject: [PATCH 119/199] remove url params --- apps/remix-ide/src/app/files/remixd-handle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index b5f9ec9804..3ec635040c 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -135,7 +135,7 @@ function remixdDialog () {
If you have looked at the Remixd docs and just need remixd command,
here it is:
remixd -s absolute-path-to-the-shared-folder --remix-ide your-remix-ide-URL-instance
-
Connection will start a session between ${window.location.href} and your local file system ws://127.0.0.1:65520 +
Connection will start a session between ${window.location.origin} and your local file system ws://127.0.0.1:65520 so please make sure your system is secured enough (port 65520 neither opened nor forwarded).
From e0e8a2b4a838d8cd5ac234d54a23d3a95f30b41d Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 29 Mar 2021 10:33:29 +0200 Subject: [PATCH 120/199] added tracking of network type usage and ipfs publish --- apps/remix-ide/src/app/tabs/runTab/contractDropdown.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index fb8f022399..a7e7a38a3c 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -9,6 +9,7 @@ const confirmDialog = require('../../ui/confirmDialog') const modalDialog = require('../../ui/modaldialog') const MultiParamManager = require('../../ui/multiParamManager') const helper = require('../../../lib/helper') +const _paq = window._paq = window._paq || [] class ContractDropdownUI { constructor (blockchain, dropdownLogic, logCallback, runView) { @@ -300,13 +301,16 @@ class ContractDropdownUI { if (error) { return this.logCallback(error) } - + _paq.push(['trackEvent', 'udapp', 'txTo', this.networkName]) self.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name]) const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file) self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data) if (self.ipfsCheckedState) { + _paq.push(['trackEvent', 'udapp', 'ipfsPublishChecked']) publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract) + } else { + _paq.push(['trackEvent', 'udapp', 'ipfsPublishNotChecked']) } } From 2736579e65157631184f71d6a9f5e1b426f64559 Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 29 Mar 2021 11:31:02 +0200 Subject: [PATCH 121/199] added network to ipfs --- apps/remix-ide/src/app/tabs/runTab/contractDropdown.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index a7e7a38a3c..c0df6e2fc0 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -301,13 +301,12 @@ class ContractDropdownUI { if (error) { return this.logCallback(error) } - _paq.push(['trackEvent', 'udapp', 'txTo', this.networkName]) self.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name]) const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file) self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data) if (self.ipfsCheckedState) { - _paq.push(['trackEvent', 'udapp', 'ipfsPublishChecked']) + _paq.push(['trackEvent', 'udapp', `ipfsPublishTo_${this.networkName}`]) publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract) } else { _paq.push(['trackEvent', 'udapp', 'ipfsPublishNotChecked']) @@ -344,6 +343,7 @@ class ContractDropdownUI { } deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) { + _paq.push(['trackEvent', 'udapp', 'DeployContractTo', this.networkName]) const { statusCb } = callbacks if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) { return this.blockchain.deployContractAndLibraries(selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) From 4969deda6f5699dc44bdcb328c29b798c988f3c5 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 31 Mar 2021 11:09:04 +0200 Subject: [PATCH 122/199] added tracking for Deploy, LL calls, At Address, Transact, Publish Metada --- .../remix-ide/src/app/tabs/runTab/contractDropdown.js | 5 +++-- .../src/app/tabs/runTab/model/dropdownlogic.js | 11 +++++++---- apps/remix-ide/src/app/udapp/run-tab.js | 2 ++ apps/remix-ide/src/app/ui/universal-dapp-ui.js | 2 ++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index c0df6e2fc0..89d92724a8 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -306,10 +306,10 @@ class ContractDropdownUI { const data = self.runView.compilersArtefacts.getCompilerAbstract(contractObject.contract.file) self.runView.compilersArtefacts.addResolvedContract(helper.addressToString(address), data) if (self.ipfsCheckedState) { - _paq.push(['trackEvent', 'udapp', `ipfsPublishTo_${this.networkName}`]) + _paq.push(['trackEvent', 'udapp', `DeployAndPublish_${this.networkName}`]) publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract) } else { - _paq.push(['trackEvent', 'udapp', 'ipfsPublishNotChecked']) + _paq.push(['trackEvent', 'udapp', 'DeployOnly']) } } @@ -399,6 +399,7 @@ class ContractDropdownUI { return modalDialogCustom.alert(error) } if (loadType === 'abi') { + _paq.push(['trackEvent', 'udapp', 'AtAddressFromABI']) return this.event.trigger('newContractABIAdded', [abi, address]) } var selectedContract = this.getSelectedContract() diff --git a/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js b/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js index a2d01d02f4..15764a6dbe 100644 --- a/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js +++ b/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js @@ -1,7 +1,8 @@ -var remixLib = require('@remix-project/remix-lib') -var txHelper = remixLib.execution.txHelper -var CompilerAbstract = require('../../../compiler/compiler-abstract') -var EventManager = remixLib.EventManager +const remixLib = require('@remix-project/remix-lib') +const txHelper = remixLib.execution.txHelper +const CompilerAbstract = require('../../../compiler/compiler-abstract') +const EventManager = remixLib.EventManager +const _paq = window._paq = window._paq || [] class DropdownLogic { constructor (compilersArtefacts, config, editor, runView) { @@ -50,9 +51,11 @@ class DropdownLogic { } catch (e) { return cb('Failed to parse the current file as JSON ABI.') } + _paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithABI']) cb(null, 'abi', abi) }) } else { + _paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithInstance']) cb(null, 'instance') } } diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index b3ba8013be..cc0d2f6ab6 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -15,6 +15,7 @@ const RecorderUI = require('../tabs/runTab/recorder.js') const DropdownLogic = require('../tabs/runTab/model/dropdownlogic.js') const ContractDropdownUI = require('../tabs/runTab/contractDropdown.js') const toaster = require('../ui/tooltip') +const _paq = window._paq = window._paq || [] const UniversalDAppUI = require('../ui/universal-dapp-ui') @@ -91,6 +92,7 @@ export class RunTab extends ViewPlugin { } sendTransaction (tx) { + _paq.push(['trackEvent', 'udapp', 'sendTx']) return this.blockchain.sendTransaction(tx) } diff --git a/apps/remix-ide/src/app/ui/universal-dapp-ui.js b/apps/remix-ide/src/app/ui/universal-dapp-ui.js index 3573403b78..e29a8126b9 100644 --- a/apps/remix-ide/src/app/ui/universal-dapp-ui.js +++ b/apps/remix-ide/src/app/ui/universal-dapp-ui.js @@ -14,6 +14,7 @@ var txFormat = remixLib.execution.txFormat const txHelper = remixLib.execution.txHelper var TreeView = require('./TreeView') var txCallBacks = require('./sendTxCallbacks') +const _paq = window._paq = window._paq || [] function UniversalDAppUI (blockchain, logCallback) { this.blockchain = blockchain @@ -243,6 +244,7 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i outputOverride.appendChild(decoded) } } + _paq.push(['trackEvent', 'udapp', lookupOnly ? 'call' : args.funABI.type !== 'fallback' ? 'lowLevelInteracions' : 'transact']) const params = args.funABI.type !== 'fallback' ? inputsValues : '' this.blockchain.runOrCallContractMethod( args.contractName, From 4ddb0bb2efca20c892ff22a2cc53e7b40d39da3d Mon Sep 17 00:00:00 2001 From: lianahus Date: Tue, 6 Apr 2021 11:29:23 +0200 Subject: [PATCH 123/199] added network name for deploy without publishing --- apps/remix-ide/src/app/tabs/runTab/contractDropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index 89d92724a8..67635df52f 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -309,7 +309,7 @@ class ContractDropdownUI { _paq.push(['trackEvent', 'udapp', `DeployAndPublish_${this.networkName}`]) publishToStorage('ipfs', self.runView.fileProvider, self.runView.fileManager, selectedContract) } else { - _paq.push(['trackEvent', 'udapp', 'DeployOnly']) + _paq.push(['trackEvent', 'udapp', `DeployOnly_${this.networkName}`]) } } From edf0f501ac25afa427afa9a3c61c0033fabd8f26 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 7 Apr 2021 10:25:25 +0200 Subject: [PATCH 124/199] iremoved doublicate data collecting --- apps/remix-ide/src/app/tabs/runTab/contractDropdown.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index 67635df52f..2a8336125d 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -399,7 +399,6 @@ class ContractDropdownUI { return modalDialogCustom.alert(error) } if (loadType === 'abi') { - _paq.push(['trackEvent', 'udapp', 'AtAddressFromABI']) return this.event.trigger('newContractABIAdded', [abi, address]) } var selectedContract = this.getSelectedContract() From aecbc8463dcd19ad26943e5bed17ed907021d78f Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 12 Apr 2021 12:23:07 +0200 Subject: [PATCH 125/199] added more info for call` --- apps/remix-ide/src/app/ui/universal-dapp-ui.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/ui/universal-dapp-ui.js b/apps/remix-ide/src/app/ui/universal-dapp-ui.js index e29a8126b9..e3eb358090 100644 --- a/apps/remix-ide/src/app/ui/universal-dapp-ui.js +++ b/apps/remix-ide/src/app/ui/universal-dapp-ui.js @@ -244,7 +244,8 @@ UniversalDAppUI.prototype.runTransaction = function (lookupOnly, args, valArr, i outputOverride.appendChild(decoded) } } - _paq.push(['trackEvent', 'udapp', lookupOnly ? 'call' : args.funABI.type !== 'fallback' ? 'lowLevelInteracions' : 'transact']) + const info = `${lookupOnly ? 'call' : args.funABI.type !== 'fallback' ? 'lowLevelInteracions' : 'transact'}_${this.blockchain.executionContext.executionContext}` + _paq.push(['trackEvent', 'udapp', info]) const params = args.funABI.type !== 'fallback' ? inputsValues : '' this.blockchain.runOrCallContractMethod( args.contractName, From b4a44693a7d06b987d15e3e8ae8e1ddde98e257a Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 12 Apr 2021 12:27:49 +0100 Subject: [PATCH 126/199] Initialise fileSystem reducer --- .../src/lib/reducers/fileSystem.ts | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts new file mode 100644 index 0000000000..b1a81ee35a --- /dev/null +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -0,0 +1,42 @@ +interface Action { + type: string; + payload: Record; +} + +export const initialState = { + files: [], + isRequesting: false, + isSuccessful: false, + hasError: null +} + +export const reducer = (state = initialState, action: Action) => { + switch (action.type) { + case 'FETCH_DIRECTORY_REQUEST': { + return { + ...state, + isRequesting: true, + isSuccessful: false, + hasError: null + } + } + case 'FETCH_DIRECTORY_SUCCESS': { + return { + files: [], + isRequesting: false, + isSuccessful: true, + hasError: null + } + } + case 'FETCH_DIRECTORY_ERROR': { + return { + ...state, + isRequesting: false, + isSuccessful: false, + hasError: action.payload + } + } + default: + throw new Error() + } +} From 3c4606ff9e6610ab405c15e181b1955cda88507a Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 12 Apr 2021 16:55:24 +0100 Subject: [PATCH 127/199] template files --- .../src/lib/actions/fileSystem.ts | 86 +++++++++++++++++++ .../file-explorer/src/lib/file-explorer.tsx | 2 + .../src/lib/reducers/fileSystem.ts | 7 +- .../src/lib/reducers/notification.ts | 0 .../file-explorer/src/lib/utils/index.ts | 13 +++ 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts create mode 100644 libs/remix-ui/file-explorer/src/lib/reducers/notification.ts create mode 100644 libs/remix-ui/file-explorer/src/lib/utils/index.ts diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts new file mode 100644 index 0000000000..ab3b6b45dd --- /dev/null +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -0,0 +1,86 @@ +import React from 'react' +import { File } from '../types' +import { extractNameFromKey, extractParentFromKey } from '../utils' + +const globalRegistry = require('../../../../../../apps/remix-ide/src/global/registry') +const fileProviders = globalRegistry.get('fileproviders').api +const browser = fileProviders.browser // eslint-disable-line +const workspace = fileProviders.workspace +const localhost = fileProviders.localhost // eslint-disable-line + +export const fetchDirectoryError = (error: any) => { + return { + type: 'FETCH_DIRECTORY_ERROR', + payload: error + } +} + +export const fetchDirectoryRequest = (promise: Promise) => { + return { + type: 'FETCH_DIRECTORY_REQUEST', + payload: promise + } +} + +export const fetchDirectorySuccess = (path: string, files: File[]) => { + return { + type: 'FETCH_DIRECTORY_SUCCESS', + payload: { path, files } + } +} + +export const fileSystemReset = () => { + return { + type: 'FILESYSTEM_RESET' + } +} + +const normalize = (filesList): File[] => { + const folders = [] + const files = [] + + Object.keys(filesList || {}).forEach(key => { + key = key.replace(/^\/|\/$/g, '') // remove first and last slash + let path = key + path = path.replace(/^\/|\/$/g, '') // remove first and last slash + + if (filesList[key].isDirectory) { + folders.push({ + path, + name: extractNameFromKey(path), + isDirectory: filesList[key].isDirectory + }) + } else { + files.push({ + path, + name: extractNameFromKey(path), + isDirectory: filesList[key].isDirectory + }) + } + }) + + return [...folders, ...files] +} + +const fetchDirectoryContent = async (folderPath: string): Promise => { + return new Promise((resolve) => { + workspace.resolveDirectory(folderPath, (error, fileTree) => { + if (error) console.error(error) + const files = normalize(fileTree) + + resolve(files) + }) + }) +} + +export const fetchDirectory = (path: string) => (dispatch: React.Dispatch) => { + const promise = fetchDirectoryContent(path) + + dispatch(fetchDirectoryRequest(promise)) + promise.then((files) => { + dispatch(fetchDirectorySuccess(path, files)) + }).catch((error) => { + dispatch(fetchDirectoryError({ error })) + }) + return promise +} diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 17f78d79fc..b5be9b0025 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -260,10 +260,12 @@ export const FileExplorer = (props: FileExplorerProps) => { } const fetchDirectoryContent = async (folderPath: string): Promise => { + console.log('folderPath: ', folderPath) return new Promise((resolve) => { filesProvider.resolveDirectory(folderPath, (_error, fileTree) => { const files = normalize(fileTree) + console.log('files: ', files) resolve(files) }) }) diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index b1a81ee35a..c6086ff59f 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -1,10 +1,12 @@ +import { extractNameFromKey, extractParentFromKey } from '../utils' interface Action { type: string; - payload: Record; + payload: Record; } export const initialState = { files: [], + expandPath: [], isRequesting: false, isSuccessful: false, hasError: null @@ -22,7 +24,8 @@ export const reducer = (state = initialState, action: Action) => { } case 'FETCH_DIRECTORY_SUCCESS': { return { - files: [], + files: action.payload.files, + expandPath: [...action.payload.path], isRequesting: false, isSuccessful: true, hasError: null diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts b/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/remix-ui/file-explorer/src/lib/utils/index.ts b/libs/remix-ui/file-explorer/src/lib/utils/index.ts new file mode 100644 index 0000000000..3db8f00902 --- /dev/null +++ b/libs/remix-ui/file-explorer/src/lib/utils/index.ts @@ -0,0 +1,13 @@ +export const extractNameFromKey = (key: string): string => { + const keyPath = key.split('/') + + return keyPath[keyPath.length - 1] +} + +export const extractParentFromKey = (key: string):string => { + if (!key) return + const keyPath = key.split('/') + keyPath.pop() + + return keyPath.join('/') +} From 48f6b50e36d9734fe8d19347a5f9bc47dffe0b39 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 15 Apr 2021 10:06:56 +0100 Subject: [PATCH 128/199] File provider actions --- apps/remix-ide/src/app/panels/file-panel.js | 2 +- .../src/lib/actions/fileSystem.ts | 53 +- .../file-explorer/src/lib/file-explorer.tsx | 551 +++++++++--------- .../src/lib/reducers/fileSystem.ts | 88 ++- 4 files changed, 393 insertions(+), 301 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 893ec084f9..4629b6d5c5 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -229,7 +229,7 @@ module.exports = class Filepanel extends ViewPlugin { /** these are called by the react component, action is already finished whent it's called */ async setWorkspace (workspace) { - this._deps.fileManager.closeAllFiles() + this._deps.fileManager.removeTabsOf(this._deps.fileProviders.workspace) if (workspace.isLocalhost) { this.call('manager', 'activatePlugin', 'remixd') } else if (await this.call('manager', 'isActive', 'remixd')) { diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index ab3b6b45dd..e815d0bf30 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -3,10 +3,12 @@ import { File } from '../types' import { extractNameFromKey, extractParentFromKey } from '../utils' const globalRegistry = require('../../../../../../apps/remix-ide/src/global/registry') -const fileProviders = globalRegistry.get('fileproviders').api -const browser = fileProviders.browser // eslint-disable-line -const workspace = fileProviders.workspace -const localhost = fileProviders.localhost // eslint-disable-line +const initializeProvider = () => { + const fileProviders = globalRegistry.get('fileproviders').api + const browser = fileProviders.browser // eslint-disable-line + const workspace = fileProviders.workspace + const localhost = fileProviders.localhost // eslint-disable-line +} export const fetchDirectoryError = (error: any) => { return { @@ -62,9 +64,9 @@ const normalize = (filesList): File[] => { return [...folders, ...files] } -const fetchDirectoryContent = async (folderPath: string): Promise => { +const fetchDirectoryContent = async (provider, folderPath: string): Promise => { return new Promise((resolve) => { - workspace.resolveDirectory(folderPath, (error, fileTree) => { + provider.resolveDirectory(folderPath, (error, fileTree) => { if (error) console.error(error) const files = normalize(fileTree) @@ -73,8 +75,43 @@ const fetchDirectoryContent = async (folderPath: string): Promise => { }) } -export const fetchDirectory = (path: string) => (dispatch: React.Dispatch) => { - const promise = fetchDirectoryContent(path) +export const fetchDirectory = (provider, path: string) => (dispatch: React.Dispatch) => { + initializeProvider() + const promise = fetchDirectoryContent(provider, path) + + dispatch(fetchDirectoryRequest(promise)) + promise.then((files) => { + dispatch(fetchDirectorySuccess(path, files)) + }).catch((error) => { + dispatch(fetchDirectoryError({ error })) + }) + return promise +} + +export const fetchProviderError = (error: any) => { + return { + type: 'FETCH_PROVIDER_ERROR', + payload: error + } +} + +export const fetchProviderRequest = (promise: Promise) => { + return { + type: 'FETCH_PROVIDER_REQUEST', + payload: promise + } +} + +export const fetchProviderSuccess = (provider: any) => { + return { + type: 'FETCH_PROVIDER_SUCCESS', + payload: provider + } +} + +export const setProvider = () => (dispatch: React.Dispatch) => { + initializeProvider() + const promise = fetchDirectoryContent(provider, path) dispatch(fetchDirectoryRequest(promise)) promise.then((files) => { diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index b5be9b0025..b14760a782 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useRef } from 'react' // eslint-disable-line +import React, { useEffect, useState, useRef, useReducer } from 'react' // eslint-disable-line // import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' // eslint-disable-line import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line @@ -7,6 +7,8 @@ import Gists from 'gists' import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' +import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' +import { fetchDirectory } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -60,6 +62,7 @@ export const FileExplorer = (props: FileExplorerProps) => { mouseOverElement: null, showContextMenu: false }) + const [fileSystem, dispatch] = useReducer(fileSystemReducer, fileSystemInitialState) const editRef = useRef(null) useEffect(() => { @@ -74,8 +77,8 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { (async () => { + await fetchDirectory(filesProvider, name)(dispatch) const fileManager = registry.get('filemanager').api - const files = await fetchDirectoryContent(name) const actions = [{ id: 'newFile', name: 'New File', @@ -121,7 +124,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }] setState(prevState => { - return { ...prevState, fileManager, files, actions, expandPath: [name] } + return { ...prevState, fileManager, actions, expandPath: [name] } }) })() }, [name]) @@ -134,35 +137,35 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [state.fileManager]) - useEffect(() => { - const { expandPath } = state - const expandFn = async () => { - let files = state.files - - for (let i = 0; i < expandPath.length; i++) { - files = await resolveDirectory(expandPath[i], files) - await setState(prevState => { - return { ...prevState, files } - }) - } - } - - if (expandPath && expandPath.length > 0) { - expandFn() - } - }, [state.expandPath]) - - useEffect(() => { - // unregister event to update state in callback - if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded) - if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded) - if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved) - if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed) - filesProvider.event.register('fileAdded', fileAdded) - filesProvider.event.register('folderAdded', folderAdded) - filesProvider.event.register('fileRemoved', fileRemoved) - filesProvider.event.register('fileRenamed', fileRenamed) - }, [state.files]) + // useEffect(() => { + // const { expandPath } = state + // const expandFn = async () => { + // let files = state.files + + // for (let i = 0; i < expandPath.length; i++) { + // files = await resolveDirectory(expandPath[i], files) + // await setState(prevState => { + // return { ...prevState, files } + // }) + // } + // } + + // if (expandPath && expandPath.length > 0) { + // expandFn() + // } + // }, [state.expandPath]) + + // useEffect(() => { + // // unregister event to update state in callback + // if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded) + // if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded) + // if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved) + // if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed) + // filesProvider.event.register('fileAdded', fileAdded) + // filesProvider.event.register('folderAdded', folderAdded) + // filesProvider.event.register('fileRemoved', fileRemoved) + // filesProvider.event.register('fileRenamed', fileRenamed) + // }, [state.files]) useEffect(() => { if (focusRoot) { @@ -220,44 +223,44 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [state.modals]) - const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise => { - if (!isChild && (state.focusEdit.element === '/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === '/blank') === -1)) { - dir = state.focusEdit.type === 'file' ? [...dir, { - path: state.focusEdit.element, - name: '', - isDirectory: false - }] : [{ - path: state.focusEdit.element, - name: '', - isDirectory: true - }, ...dir] - } - dir = await Promise.all(dir.map(async (file) => { - if (file.path === folderPath) { - if ((extractParentFromKey(state.focusEdit.element) === folderPath) && state.focusEdit.isNew) { - file.child = state.focusEdit.type === 'file' ? [...await fetchDirectoryContent(folderPath), { - path: state.focusEdit.element, - name: '', - isDirectory: false - }] : [{ - path: state.focusEdit.element, - name: '', - isDirectory: true - }, ...await fetchDirectoryContent(folderPath)] - } else { - file.child = await fetchDirectoryContent(folderPath) - } - return file - } else if (file.child) { - file.child = await resolveDirectory(folderPath, file.child, true) - return file - } else { - return file - } - })) - - return dir - } + // const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise => { + // if (!isChild && (state.focusEdit.element === '/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === '/blank') === -1)) { + // dir = state.focusEdit.type === 'file' ? [...dir, { + // path: state.focusEdit.element, + // name: '', + // isDirectory: false + // }] : [{ + // path: state.focusEdit.element, + // name: '', + // isDirectory: true + // }, ...dir] + // } + // dir = await Promise.all(dir.map(async (file) => { + // if (file.path === folderPath) { + // if ((extractParentFromKey(state.focusEdit.element) === folderPath) && state.focusEdit.isNew) { + // file.child = state.focusEdit.type === 'file' ? [...await fetchDirectoryContent(folderPath), { + // path: state.focusEdit.element, + // name: '', + // isDirectory: false + // }] : [{ + // path: state.focusEdit.element, + // name: '', + // isDirectory: true + // }, ...await fetchDirectoryContent(folderPath)] + // } else { + // file.child = await fetchDirectoryContent(folderPath) + // } + // return file + // } else if (file.child) { + // file.child = await resolveDirectory(folderPath, file.child, true) + // return file + // } else { + // return file + // } + // })) + + // return dir + // } const fetchDirectoryContent = async (folderPath: string): Promise => { console.log('folderPath: ', folderPath) @@ -312,61 +315,61 @@ export const FileExplorer = (props: FileExplorerProps) => { return keyPath.join('/') } - const createNewFile = (newFilePath: string) => { - const fileManager = state.fileManager - - try { - helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { - if (error) { - modal('Create File Failed', error, { - label: 'Close', - fn: async () => {} - }, null) - } else { - const createFile = await fileManager.writeFile(newName, '') - - if (!createFile) { - return toast('Failed to create file ' + newName) - } else { - await fileManager.open(newName) - setState(prevState => { - return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } - }) - } - } - }) - } catch (error) { - return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { - label: 'Close', - fn: async () => {} - }, null) - } - } - - const createNewFolder = async (newFolderPath: string) => { - const fileManager = state.fileManager - const dirName = newFolderPath + '/' - - try { - const exists = await fileManager.exists(dirName) - - if (exists) { - return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, { - label: 'Close', - fn: () => {} - }, null) - } - await fileManager.mkdir(dirName) - setState(prevState => { - return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } - }) - } catch (e) { - return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, { - label: 'Close', - fn: async () => {} - }, null) - } - } + // const createNewFile = (newFilePath: string) => { + // const fileManager = state.fileManager + + // try { + // helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { + // if (error) { + // modal('Create File Failed', error, { + // label: 'Close', + // fn: async () => {} + // }, null) + // } else { + // const createFile = await fileManager.writeFile(newName, '') + + // if (!createFile) { + // return toast('Failed to create file ' + newName) + // } else { + // await fileManager.open(newName) + // setState(prevState => { + // return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } + // }) + // } + // } + // }) + // } catch (error) { + // return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { + // label: 'Close', + // fn: async () => {} + // }, null) + // } + // } + + // const createNewFolder = async (newFolderPath: string) => { + // const fileManager = state.fileManager + // const dirName = newFolderPath + '/' + + // try { + // const exists = await fileManager.exists(dirName) + + // if (exists) { + // return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, { + // label: 'Close', + // fn: () => {} + // }, null) + // } + // await fileManager.mkdir(dirName) + // setState(prevState => { + // return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } + // }) + // } catch (e) { + // return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, { + // label: 'Close', + // fn: async () => {} + // }, null) + // } + // } const deletePath = async (path: string) => { if (filesProvider.isReadOnly(path)) { @@ -391,72 +394,72 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } - const renamePath = async (oldPath: string, newPath: string) => { - try { - const fileManager = state.fileManager - const exists = await fileManager.exists(newPath) - - if (exists) { - modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, { - label: 'Close', - fn: () => {} - }, null) - } else { - await fileManager.rename(oldPath, newPath) - } - } catch (error) { - modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, { - label: 'Close', - fn: async () => {} - }, null) - } - } - - const removePath = (path: string, files: File[]): File[] => { - return files.map(file => { - if (file.path === path) { - return null - } else if (file.child) { - const childFiles = removePath(path, file.child) - - file.child = childFiles.filter(file => file) - return file - } else { - return file - } - }) - } - - const fileAdded = async (filePath: string) => { - const pathArr = filePath.split('/') - const expandPath = pathArr.map((path, index) => { - return [...pathArr.slice(0, index)].join('/') - }).filter(path => path && (path !== props.name)) - const files = await fetchDirectoryContent(props.name) - - setState(prevState => { - const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] - - return { ...prevState, files, expandPath: uniquePaths } - }) - if (filePath.includes('_test.sol')) { - plugin.event.trigger('newTestFileCreated', [filePath]) - } - } - - const folderAdded = async (folderPath: string) => { - const pathArr = folderPath.split('/') - const expandPath = pathArr.map((path, index) => { - return [...pathArr.slice(0, index)].join('/') - }).filter(path => path && (path !== props.name)) - const files = await fetchDirectoryContent(props.name) - - setState(prevState => { - const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] - - return { ...prevState, files, expandPath: uniquePaths } - }) - } + // const renamePath = async (oldPath: string, newPath: string) => { + // try { + // const fileManager = state.fileManager + // const exists = await fileManager.exists(newPath) + + // if (exists) { + // modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, { + // label: 'Close', + // fn: () => {} + // }, null) + // } else { + // await fileManager.rename(oldPath, newPath) + // } + // } catch (error) { + // modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, { + // label: 'Close', + // fn: async () => {} + // }, null) + // } + // } + + // const removePath = (path: string, files: File[]): File[] => { + // return files.map(file => { + // if (file.path === path) { + // return null + // } else if (file.child) { + // const childFiles = removePath(path, file.child) + + // file.child = childFiles.filter(file => file) + // return file + // } else { + // return file + // } + // }) + // } + + // const fileAdded = async (filePath: string) => { + // const pathArr = filePath.split('/') + // const expandPath = pathArr.map((path, index) => { + // return [...pathArr.slice(0, index)].join('/') + // }).filter(path => path && (path !== props.name)) + // const files = await fetchDirectoryContent(props.name) + + // setState(prevState => { + // const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] + + // return { ...prevState, files, expandPath: uniquePaths } + // }) + // if (filePath.includes('_test.sol')) { + // plugin.event.trigger('newTestFileCreated', [filePath]) + // } + // } + + // const folderAdded = async (folderPath: string) => { + // const pathArr = folderPath.split('/') + // const expandPath = pathArr.map((path, index) => { + // return [...pathArr.slice(0, index)].join('/') + // }).filter(path => path && (path !== props.name)) + // const files = await fetchDirectoryContent(props.name) + + // setState(prevState => { + // const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] + + // return { ...prevState, files, expandPath: uniquePaths } + // }) + // } const fileExternallyChanged = (path: string, file: { content: string }) => { const config = registry.get('config').api @@ -476,22 +479,22 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const fileRemoved = (filePath) => { - const files = removePath(filePath, state.files) - const updatedFiles = files.filter(file => file) + // const fileRemoved = (filePath) => { + // const files = removePath(filePath, state.files) + // const updatedFiles = files.filter(file => file) - setState(prevState => { - return { ...prevState, files: updatedFiles } - }) - } + // setState(prevState => { + // return { ...prevState, files: updatedFiles } + // }) + // } - const fileRenamed = async () => { - const files = await fetchDirectoryContent(props.name) + // const fileRenamed = async () => { + // const files = await fetchDirectoryContent(props.name) - setState(prevState => { - return { ...prevState, files, expandPath: [...prevState.expandPath] } - }) - } + // setState(prevState => { + // return { ...prevState, files, expandPath: [...prevState.expandPath] } + // }) + // } // register to event of the file provider // files.event.register('fileRenamed', fileRenamed) @@ -798,59 +801,59 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } - const editModeOff = async (content: string) => { - if (typeof content === 'string') content = content.trim() - const parentFolder = extractParentFromKey(state.focusEdit.element) - - if (!content || (content.trim() === '')) { - if (state.focusEdit.isNew) { - const files = removePath(state.focusEdit.element, state.files) - const updatedFiles = files.filter(file => file) - - setState(prevState => { - return { ...prevState, files: updatedFiles, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } else { - editRef.current.textContent = state.focusEdit.lastEdit - setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - } else { - if (state.focusEdit.lastEdit === content) { - editRef.current.textContent = content - return setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - if (helper.checkSpecialChars(content)) { - modal('Validation Error', 'Special characters are not allowed', { - label: 'OK', - fn: () => {} - }, null) - } else { - if (state.focusEdit.isNew) { - state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - const files = removePath(state.focusEdit.element, state.files) - const updatedFiles = files.filter(file => file) - - setState(prevState => { - return { ...prevState, files: updatedFiles } - }) - } else { - const oldPath: string = state.focusEdit.element - const oldName = extractNameFromKey(oldPath) - const newPath = oldPath.replace(oldName, content) - - editRef.current.textContent = extractNameFromKey(oldPath) - renamePath(oldPath, newPath) - } - setState(prevState => { - return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - }) - } - } - } + // const editModeOff = async (content: string) => { + // if (typeof content === 'string') content = content.trim() + // const parentFolder = extractParentFromKey(state.focusEdit.element) + + // if (!content || (content.trim() === '')) { + // if (state.focusEdit.isNew) { + // const files = removePath(state.focusEdit.element, state.files) + // const updatedFiles = files.filter(file => file) + + // setState(prevState => { + // return { ...prevState, files: updatedFiles, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + // }) + // } else { + // editRef.current.textContent = state.focusEdit.lastEdit + // setState(prevState => { + // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + // }) + // } + // } else { + // if (state.focusEdit.lastEdit === content) { + // editRef.current.textContent = content + // return setState(prevState => { + // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + // }) + // } + // if (helper.checkSpecialChars(content)) { + // modal('Validation Error', 'Special characters are not allowed', { + // label: 'OK', + // fn: () => {} + // }, null) + // } else { + // if (state.focusEdit.isNew) { + // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) + // const files = removePath(state.focusEdit.element, state.files) + // const updatedFiles = files.filter(file => file) + + // setState(prevState => { + // return { ...prevState, files: updatedFiles } + // }) + // } else { + // const oldPath: string = state.focusEdit.element + // const oldName = extractNameFromKey(oldPath) + // const newPath = oldPath.replace(oldName, content) + + // editRef.current.textContent = extractNameFromKey(oldPath) + // renamePath(oldPath, newPath) + // } + // setState(prevState => { + // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + // }) + // } + // } + // } const handleNewFileInput = async (parentFolder?: string) => { if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name @@ -873,12 +876,12 @@ export const FileExplorer = (props: FileExplorerProps) => { editModeOn(parentFolder + '/blank', 'folder', true) } - const handleEditInput = (event) => { - if (event.which === 13) { - event.preventDefault() - editModeOff(editRef.current.innerText) - } - } + // const handleEditInput = (event) => { + // if (event.which === 13) { + // event.preventDefault() + // editModeOff(editRef.current.innerText) + // } + // } const handleMouseOver = (path: string) => { setState(prevState => { @@ -899,11 +902,11 @@ export const FileExplorer = (props: FileExplorerProps) => { ref={state.focusEdit.element === file.path ? editRef : null} suppressContentEditableWarning={true} contentEditable={state.focusEdit.element === file.path} - onKeyDown={handleEditInput} - onBlur={(e) => { - e.stopPropagation() - editModeOff(editRef.current.innerText) - }} + // onKeyDown={handleEditInput} + // onBlur={(e) => { + // e.stopPropagation() + // editModeOff(editRef.current.innerText) + // }} > {
{ - state.files.map((file, index) => { + fileSystem.files.files.map((file, index) => { return renderFiles(file, index) }) } @@ -1092,8 +1095,8 @@ async function packageFiles (filesProvider, directory, callback) { } } -function joinPath (...paths) { - paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) - if (paths.length === 1) return paths[0] - return paths.join('/') -} +// function joinPath (...paths) { +// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) +// if (paths.length === 1) return paths[0] +// return paths.join('/') +// } diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index c6086ff59f..7f39c28c2f 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -4,39 +4,91 @@ interface Action { payload: Record; } -export const initialState = { - files: [], - expandPath: [], - isRequesting: false, - isSuccessful: false, - hasError: null +export const fileSystemInitialState = { + files: { + files: [], + expandPath: [], + isRequesting: false, + isSuccessful: false, + error: null + }, + provider: { + provider: null, + isRequesting: false, + isSuccessful: false, + error: null + } } -export const reducer = (state = initialState, action: Action) => { +export const fileSystemReducer = (state = fileSystemInitialState, action: Action) => { switch (action.type) { case 'FETCH_DIRECTORY_REQUEST': { return { ...state, - isRequesting: true, - isSuccessful: false, - hasError: null + files: { + ...state.files, + isRequesting: true, + isSuccessful: false, + error: null + } } } case 'FETCH_DIRECTORY_SUCCESS': { return { - files: action.payload.files, - expandPath: [...action.payload.path], - isRequesting: false, - isSuccessful: true, - hasError: null + ...state, + files: { + ...state.files, + files: action.payload.files, + expandPath: [...state.files.expandPath, action.payload.path], + isRequesting: false, + isSuccessful: true, + error: null + } } } case 'FETCH_DIRECTORY_ERROR': { return { ...state, - isRequesting: false, - isSuccessful: false, - hasError: action.payload + files: { + ...state.files, + isRequesting: false, + isSuccessful: false, + error: action.payload + } + } + } + case 'FETCH_PROVIDER_REQUEST': { + return { + ...state, + provider: { + ...state.provider, + isRequesting: true, + isSuccessful: false, + error: null + } + } + } + case 'FETCH_PROVIDER_SUCCESS': { + return { + ...state, + provider: { + ...state.provider, + provider: action.payload, + isRequesting: false, + isSuccessful: true, + error: null + } + } + } + case 'FETCH_PROVIDER_ERROR': { + return { + ...state, + provider: { + ...state.provider, + isRequesting: false, + isSuccessful: false, + error: action.payload + } } } default: From ee357b65dae0bf53fe249d3ffcab9bf230544e7b Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 19 Apr 2021 09:44:03 +0100 Subject: [PATCH 129/199] Change files structure. --- .../src/lib/actions/fileSystem.ts | 81 +++++--- .../file-explorer/src/lib/file-explorer.tsx | 180 +++++++----------- .../src/lib/reducers/fileSystem.ts | 76 +++++++- 3 files changed, 193 insertions(+), 144 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index e815d0bf30..3586342875 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -1,14 +1,6 @@ import React from 'react' import { File } from '../types' -import { extractNameFromKey, extractParentFromKey } from '../utils' - -const globalRegistry = require('../../../../../../apps/remix-ide/src/global/registry') -const initializeProvider = () => { - const fileProviders = globalRegistry.get('fileproviders').api - const browser = fileProviders.browser // eslint-disable-line - const workspace = fileProviders.workspace - const localhost = fileProviders.localhost // eslint-disable-line -} +import { extractNameFromKey } from '../utils' export const fetchDirectoryError = (error: any) => { return { @@ -37,9 +29,9 @@ export const fileSystemReset = () => { } } -const normalize = (filesList): File[] => { - const folders = [] - const files = [] +const normalize = (filesList): any => { + const folders = {} + const files = {} Object.keys(filesList || {}).forEach(key => { key = key.replace(/^\/|\/$/g, '') // remove first and last slash @@ -47,36 +39,35 @@ const normalize = (filesList): File[] => { path = path.replace(/^\/|\/$/g, '') // remove first and last slash if (filesList[key].isDirectory) { - folders.push({ + folders[key] = { path, name: extractNameFromKey(path), isDirectory: filesList[key].isDirectory - }) + } } else { - files.push({ + files[key] = { path, name: extractNameFromKey(path), isDirectory: filesList[key].isDirectory - }) + } } }) - return [...folders, ...files] + return Object.assign({}, folders, files) } -const fetchDirectoryContent = async (provider, folderPath: string): Promise => { +const fetchDirectoryContent = async (provider, folderPath: string): Promise => { return new Promise((resolve) => { provider.resolveDirectory(folderPath, (error, fileTree) => { if (error) console.error(error) const files = normalize(fileTree) - resolve(files) + resolve({ [extractNameFromKey(folderPath)]: files }) }) }) } export const fetchDirectory = (provider, path: string) => (dispatch: React.Dispatch) => { - initializeProvider() const promise = fetchDirectoryContent(provider, path) dispatch(fetchDirectoryRequest(promise)) @@ -88,6 +79,39 @@ export const fetchDirectory = (provider, path: string) => (dispatch: React.Dispa return promise } +export const resolveDirectoryError = (error: any) => { + return { + type: 'RESOLVE_DIRECTORY_ERROR', + payload: error + } +} + +export const resolveDirectoryRequest = (promise: Promise) => { + return { + type: 'RESOLVE_DIRECTORY_REQUEST', + payload: promise + } +} + +export const resolveDirectorySuccess = (path: string, files: File[]) => { + return { + type: 'RESOLVE_DIRECTORY_SUCCESS', + payload: { path, files } + } +} + +export const resolveDirectory = (provider, path: string) => (dispatch: React.Dispatch) => { + const promise = fetchDirectoryContent(provider, path) + + dispatch(resolveDirectoryRequest(promise)) + promise.then((files) => { + dispatch(resolveDirectorySuccess(path, files)) + }).catch((error) => { + dispatch(resolveDirectoryError({ error })) + }) + return promise +} + export const fetchProviderError = (error: any) => { return { type: 'FETCH_PROVIDER_ERROR', @@ -109,15 +133,10 @@ export const fetchProviderSuccess = (provider: any) => { } } -export const setProvider = () => (dispatch: React.Dispatch) => { - initializeProvider() - const promise = fetchDirectoryContent(provider, path) - - dispatch(fetchDirectoryRequest(promise)) - promise.then((files) => { - dispatch(fetchDirectorySuccess(path, files)) - }).catch((error) => { - dispatch(fetchDirectoryError({ error })) - }) - return promise +export const setProvider = (provider) => (dispatch: React.Dispatch) => { + if (provider) { + dispatch(fetchProviderSuccess(provider)) + } else { + dispatch(fetchProviderError('No provider available')) + } } diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index b14760a782..e53648d28d 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory } from './actions/fileSystem' +import { fetchDirectory, setProvider, resolveDirectory } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -17,7 +17,7 @@ import './css/file-explorer.css' const queryParams = new QueryParams() export const FileExplorer = (props: FileExplorerProps) => { - const { filesProvider, name, registry, plugin, focusRoot, contextMenuItems, displayInput, externalUploads } = props + const { name, registry, plugin, focusRoot, contextMenuItems, displayInput, externalUploads } = props const [state, setState] = useState({ focusElement: [{ key: '', @@ -26,10 +26,51 @@ export const FileExplorer = (props: FileExplorerProps) => { focusPath: null, files: [], fileManager: null, - filesProvider, ctrlKey: false, newFileName: '', - actions: [], + actions: [{ + id: 'newFile', + name: 'New File', + type: ['folder'], + path: [], + extension: [], + pattern: [] + }, { + id: 'newFolder', + name: 'New Folder', + type: ['folder'], + path: [], + extension: [], + pattern: [] + }, { + id: 'rename', + name: 'Rename', + type: ['file', 'folder'], + path: [], + extension: [], + pattern: [] + }, { + id: 'delete', + name: 'Delete', + type: ['file', 'folder'], + path: [], + extension: [], + pattern: [] + }, { + id: 'pushChangesToGist', + name: 'Push changes to gist', + type: [], + path: [], + extension: [], + pattern: ['^browser/gists/([0-9]|[a-z])*$'] + }, { + id: 'run', + name: 'Run', + type: [], + path: [], + extension: ['.js'], + pattern: [] + }], focusContext: { element: null, x: null, @@ -65,6 +106,20 @@ export const FileExplorer = (props: FileExplorerProps) => { const [fileSystem, dispatch] = useReducer(fileSystemReducer, fileSystemInitialState) const editRef = useRef(null) + useEffect(() => { + if (props.filesProvider) { + setProvider(props.filesProvider)(dispatch) + } + }, [props.filesProvider]) + + useEffect(() => { + const provider = fileSystem.provider.provider + + if (provider) { + fetchDirectory(provider, props.name)(dispatch) + } + }, [fileSystem.provider.provider]) + useEffect(() => { if (state.focusEdit.element) { setTimeout(() => { @@ -77,83 +132,21 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { (async () => { - await fetchDirectory(filesProvider, name)(dispatch) const fileManager = registry.get('filemanager').api - const actions = [{ - id: 'newFile', - name: 'New File', - type: ['folder'], - path: [], - extension: [], - pattern: [] - }, { - id: 'newFolder', - name: 'New Folder', - type: ['folder'], - path: [], - extension: [], - pattern: [] - }, { - id: 'rename', - name: 'Rename', - type: ['file', 'folder'], - path: [], - extension: [], - pattern: [] - }, { - id: 'delete', - name: 'Delete', - type: ['file', 'folder'], - path: [], - extension: [], - pattern: [] - }, { - id: 'pushChangesToGist', - name: 'Push changes to gist', - type: [], - path: [], - extension: [], - pattern: ['^browser/gists/([0-9]|[a-z])*$'] - }, { - id: 'run', - name: 'Run', - type: [], - path: [], - extension: ['.js'], - pattern: [] - }] setState(prevState => { - return { ...prevState, fileManager, actions, expandPath: [name] } + return { ...prevState, fileManager, expandPath: [name] } }) })() }, [name]) - useEffect(() => { - if (state.fileManager) { - filesProvider.event.register('fileExternallyChanged', fileExternallyChanged) - filesProvider.event.register('fileRenamedError', fileRenamedError) - filesProvider.event.register('rootFolderChanged', rootFolderChanged) - } - }, [state.fileManager]) - // useEffect(() => { - // const { expandPath } = state - // const expandFn = async () => { - // let files = state.files - - // for (let i = 0; i < expandPath.length; i++) { - // files = await resolveDirectory(expandPath[i], files) - // await setState(prevState => { - // return { ...prevState, files } - // }) - // } - // } - - // if (expandPath && expandPath.length > 0) { - // expandFn() + // if (state.fileManager) { + // filesProvider.event.register('fileExternallyChanged', fileExternallyChanged) + // filesProvider.event.register('fileRenamedError', fileRenamedError) + // filesProvider.event.register('rootFolderChanged', rootFolderChanged) // } - // }, [state.expandPath]) + // }, [state.fileManager]) // useEffect(() => { // // unregister event to update state in callback @@ -262,44 +255,6 @@ export const FileExplorer = (props: FileExplorerProps) => { // return dir // } - const fetchDirectoryContent = async (folderPath: string): Promise => { - console.log('folderPath: ', folderPath) - return new Promise((resolve) => { - filesProvider.resolveDirectory(folderPath, (_error, fileTree) => { - const files = normalize(fileTree) - - console.log('files: ', files) - resolve(files) - }) - }) - } - - const normalize = (filesList): File[] => { - const folders = [] - const files = [] - - Object.keys(filesList || {}).forEach(key => { - key = key.replace(/^\/|\/$/g, '') // remove first and last slash - let path = key - path = path.replace(/^\/|\/$/g, '') // remove first and last slash - - if (filesList[key].isDirectory) { - folders.push({ - path, - name: extractNameFromKey(path), - isDirectory: filesList[key].isDirectory - }) - } else { - files.push({ - path, - name: extractNameFromKey(path), - isDirectory: filesList[key].isDirectory - }) - } - }) - - return [...folders, ...files] - } const extractNameFromKey = (key: string):string => { const keyPath = key.split('/') @@ -771,6 +726,7 @@ export const FileExplorer = (props: FileExplorerProps) => { setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'folder' }], expandPath } }) + resolveDirectory(path)(dispatch) } } @@ -1033,8 +989,8 @@ export const FileExplorer = (props: FileExplorerProps) => {
{ - fileSystem.files.files.map((file, index) => { - return renderFiles(file, index) + fileSystem.files.files[props.name] && Object.keys(fileSystem.files.files[props.name]).map((key, index) => { + return renderFiles(fileSystem.files.files[props.name][key], index) }) } diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 7f39c28c2f..2f4a88331a 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -1,4 +1,4 @@ -import { extractNameFromKey, extractParentFromKey } from '../utils' +import { File } from '../types' interface Action { type: string; payload: Record; @@ -7,6 +7,7 @@ interface Action { export const fileSystemInitialState = { files: { files: [], + activeDirectory: {}, expandPath: [], isRequesting: false, isSuccessful: false, @@ -57,6 +58,41 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'RESOLVE_DIRECTORY_REQUEST': { + return { + ...state, + files: { + ...state.files, + isRequesting: true, + isSuccessful: false, + error: null + } + } + } + case 'RESOLVE_DIRECTORY_SUCCESS': { + return { + ...state, + files: { + ...state.files, + files: action.payload.files, + expandPath: [...state.files.expandPath, action.payload.path], + isRequesting: false, + isSuccessful: true, + error: null + } + } + } + case 'RESOLVE_DIRECTORY_ERROR': { + return { + ...state, + files: { + ...state.files, + isRequesting: false, + isSuccessful: false, + error: action.payload + } + } + } case 'FETCH_PROVIDER_REQUEST': { return { ...state, @@ -91,7 +127,45 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'ADD_EMPTY_FILE': { + return { + ...state, + files: { + ...state.files, + files: [] + } + } + } default: throw new Error() } } + +const addEmptyFile = (path: string, files: File[]): File[] => { + if (path === name) { + files.push({ + path: 'browser/blank', + name: '', + isDirectory: false + }) + return files + } + return files.map(file => { + if (file.child) { + if (file.path === path) { + file.child = [...file.child, { + path: file.path + '/blank', + name: '', + isDirectory: false + }] + return file + } else { + file.child = addEmptyFile(path, file.child) + + return file + } + } else { + return file + } + }) +} From 99395f7eadc9450492ad42b5f60410625053c4ef Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 19 Apr 2021 17:13:00 +0100 Subject: [PATCH 130/199] Resolve directory --- .../src/lib/actions/fileSystem.ts | 17 ++++++- .../file-explorer/src/lib/file-explorer.tsx | 48 ++---------------- .../src/lib/reducers/fileSystem.ts | 49 ++++++------------- package-lock.json | 6 +-- package.json | 1 + 5 files changed, 40 insertions(+), 81 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 3586342875..faba186ed9 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -39,13 +39,13 @@ const normalize = (filesList): any => { path = path.replace(/^\/|\/$/g, '') // remove first and last slash if (filesList[key].isDirectory) { - folders[key] = { + folders[extractNameFromKey(key)] = { path, name: extractNameFromKey(path), isDirectory: filesList[key].isDirectory } } else { - files[key] = { + files[extractNameFromKey(key)] = { path, name: extractNameFromKey(path), isDirectory: filesList[key].isDirectory @@ -140,3 +140,16 @@ export const setProvider = (provider) => (dispatch: React.Dispatch) => { dispatch(fetchProviderError('No provider available')) } } + +export const setCurrentWorkspace = (name: string) => { + return { + type: 'SET_CURRENT_WORKSPACE', + payload: name + } +} + +export const setWorkspace = (name: string) => (dispatch: React.Dispatch) => { + if (name) { + dispatch(setCurrentWorkspace(name)) + } +} diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index e53648d28d..9ba8a1dc3f 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory, setProvider, resolveDirectory } from './actions/fileSystem' +import { fetchDirectory, setProvider, resolveDirectory, setWorkspace } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -109,6 +109,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { setProvider(props.filesProvider)(dispatch) + setWorkspace(props.name)(dispatch) } }, [props.filesProvider]) @@ -216,45 +217,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [state.modals]) - // const resolveDirectory = async (folderPath, dir: File[], isChild = false): Promise => { - // if (!isChild && (state.focusEdit.element === '/blank') && state.focusEdit.isNew && (dir.findIndex(({ path }) => path === '/blank') === -1)) { - // dir = state.focusEdit.type === 'file' ? [...dir, { - // path: state.focusEdit.element, - // name: '', - // isDirectory: false - // }] : [{ - // path: state.focusEdit.element, - // name: '', - // isDirectory: true - // }, ...dir] - // } - // dir = await Promise.all(dir.map(async (file) => { - // if (file.path === folderPath) { - // if ((extractParentFromKey(state.focusEdit.element) === folderPath) && state.focusEdit.isNew) { - // file.child = state.focusEdit.type === 'file' ? [...await fetchDirectoryContent(folderPath), { - // path: state.focusEdit.element, - // name: '', - // isDirectory: false - // }] : [{ - // path: state.focusEdit.element, - // name: '', - // isDirectory: true - // }, ...await fetchDirectoryContent(folderPath)] - // } else { - // file.child = await fetchDirectoryContent(folderPath) - // } - // return file - // } else if (file.child) { - // file.child = await resolveDirectory(folderPath, file.child, true) - // return file - // } else { - // return file - // } - // })) - - // return dir - // } - const extractNameFromKey = (key: string):string => { const keyPath = key.split('/') @@ -726,7 +688,7 @@ export const FileExplorer = (props: FileExplorerProps) => { setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'folder' }], expandPath } }) - resolveDirectory(path)(dispatch) + resolveDirectory(fileSystem.provider.provider, path)(dispatch) } } @@ -914,8 +876,8 @@ export const FileExplorer = (props: FileExplorerProps) => { > { file.child ? { - file.child.map((file, index) => { - return renderFiles(file, index) + Object.keys(file.child).map((key, index) => { + return renderFiles(file.child[key], index) }) } : diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 2f4a88331a..0d0ecd7c85 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -1,4 +1,5 @@ -import { File } from '../types' +import * as _ from 'lodash' +import { extractNameFromKey } from '../utils' interface Action { type: string; payload: Record; @@ -7,8 +8,7 @@ interface Action { export const fileSystemInitialState = { files: { files: [], - activeDirectory: {}, - expandPath: [], + workspaceName: null, isRequesting: false, isSuccessful: false, error: null @@ -40,7 +40,6 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action files: { ...state.files, files: action.payload.files, - expandPath: [...state.files.expandPath, action.payload.path], isRequesting: false, isSuccessful: true, error: null @@ -74,8 +73,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action ...state, files: { ...state.files, - files: action.payload.files, - expandPath: [...state.files.expandPath, action.payload.path], + files: resolveDirectory(state.files.workspaceName, action.payload.path, state.files.files, action.payload.files), isRequesting: false, isSuccessful: true, error: null @@ -127,12 +125,12 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } - case 'ADD_EMPTY_FILE': { + case 'SET_CURRENT_WORKSPACE': { return { ...state, files: { ...state.files, - files: [] + workspaceName: action.payload } } } @@ -141,31 +139,16 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } -const addEmptyFile = (path: string, files: File[]): File[] => { - if (path === name) { - files.push({ - path: 'browser/blank', - name: '', - isDirectory: false - }) - return files - } - return files.map(file => { - if (file.child) { - if (file.path === path) { - file.child = [...file.child, { - path: file.path + '/blank', - name: '', - isDirectory: false - }] - return file - } else { - file.child = addEmptyFile(path, file.child) +const resolveDirectory = (root, path: string, files, content) => { + const pathArr = path.split('/') + if (pathArr[0] !== root) pathArr.unshift(root) - return file - } - } else { - return file - } + files = _.set(files, pathArr, { + isDirectory: true, + path, + name: extractNameFromKey(path), + child: { ...content[pathArr[pathArr.length - 1]] } }) + + return files } diff --git a/package-lock.json b/package-lock.json index 4f92e09fa8..d74204bd8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25139,9 +25139,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash-es": { "version": "4.17.15", diff --git a/package.json b/package.json index 2587e3bfbf..a7ae4d3288 100644 --- a/package.json +++ b/package.json @@ -160,6 +160,7 @@ "jquery": "^3.3.1", "jszip": "^3.6.0", "latest-version": "^5.1.0", + "lodash": "^4.17.21", "merge": "^1.2.0", "npm-install-version": "^6.0.2", "react": "16.13.1", From be2341a0c4774bc43440a246f83ad0a171325fd8 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 21 Apr 2021 19:25:08 +0100 Subject: [PATCH 131/199] Complete input fields functionality --- .../src/lib/actions/fileSystem.ts | 62 ++++++++- .../file-explorer/src/lib/file-explorer.tsx | 127 +++++++++--------- .../src/lib/reducers/fileSystem.ts | 42 +++++- 3 files changed, 160 insertions(+), 71 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index faba186ed9..49a95ec4f9 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -1,6 +1,6 @@ import React from 'react' import { File } from '../types' -import { extractNameFromKey } from '../utils' +import { extractNameFromKey, extractParentFromKey } from '../utils' export const fetchDirectoryError = (error: any) => { return { @@ -29,7 +29,7 @@ export const fileSystemReset = () => { } } -const normalize = (filesList): any => { +const normalize = (parent, filesList, newInputType?: string): any => { const folders = {} const files = {} @@ -53,14 +53,32 @@ const normalize = (filesList): any => { } }) + if (newInputType === 'folder') { + const path = parent + '/blank' + + folders[path] = { + path: path, + name: '', + isDirectory: true + } + } else if (newInputType === 'file') { + const path = parent + '/blank' + + files[path] = { + path: path, + name: '', + isDirectory: false + } + } + return Object.assign({}, folders, files) } -const fetchDirectoryContent = async (provider, folderPath: string): Promise => { +const fetchDirectoryContent = async (provider, folderPath: string, newInputType?: string): Promise => { return new Promise((resolve) => { provider.resolveDirectory(folderPath, (error, fileTree) => { if (error) console.error(error) - const files = normalize(fileTree) + const files = normalize(folderPath, fileTree, newInputType) resolve({ [extractNameFromKey(folderPath)]: files }) }) @@ -153,3 +171,39 @@ export const setWorkspace = (name: string) => (dispatch: React.Dispatch) => dispatch(setCurrentWorkspace(name)) } } + +export const addInputFieldSuccess = (path: string, files: File[]) => { + return { + type: 'ADD_INPUT_FIELD', + payload: { path, files } + } +} + +export const addInputField = (provider, type: string, path: string) => (dispatch: React.Dispatch) => { + const promise = fetchDirectoryContent(provider, path, type) + + promise.then((files) => { + dispatch(addInputFieldSuccess(path, files)) + }).catch((error) => { + console.error(error) + }) + return promise +} + +export const removeInputFieldSuccess = (path: string, files: File[]) => { + return { + type: 'REMOVE_INPUT_FIELD', + payload: { path, files } + } +} + +export const removeInputField = (provider, path: string) => (dispatch: React.Dispatch) => { + const promise = fetchDirectoryContent(provider, path) + + promise.then((files) => { + dispatch(removeInputFieldSuccess(path, files)) + }).catch((error) => { + console.error(error) + }) + return promise +} diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 9ba8a1dc3f..a65cffb003 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory, setProvider, resolveDirectory, setWorkspace } from './actions/fileSystem' +import { fetchDirectory, setProvider, resolveDirectory, setWorkspace, addInputField, removeInputField } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -713,70 +713,64 @@ export const FileExplorer = (props: FileExplorerProps) => { } const editModeOn = (path: string, type: string, isNew: boolean = false) => { - if (filesProvider.isReadOnly(path)) return + if (fileSystem.provider.provider.isReadOnly(path)) return setState(prevState => { return { ...prevState, focusEdit: { ...prevState.focusEdit, element: path, isNew, type } } }) } - // const editModeOff = async (content: string) => { - // if (typeof content === 'string') content = content.trim() - // const parentFolder = extractParentFromKey(state.focusEdit.element) + const editModeOff = async (content: string) => { + if (typeof content === 'string') content = content.trim() + const parentFolder = extractParentFromKey(state.focusEdit.element) - // if (!content || (content.trim() === '')) { - // if (state.focusEdit.isNew) { - // const files = removePath(state.focusEdit.element, state.files) - // const updatedFiles = files.filter(file => file) - - // setState(prevState => { - // return { ...prevState, files: updatedFiles, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - // }) - // } else { - // editRef.current.textContent = state.focusEdit.lastEdit - // setState(prevState => { - // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - // }) - // } - // } else { - // if (state.focusEdit.lastEdit === content) { - // editRef.current.textContent = content - // return setState(prevState => { - // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - // }) - // } - // if (helper.checkSpecialChars(content)) { - // modal('Validation Error', 'Special characters are not allowed', { - // label: 'OK', - // fn: () => {} - // }, null) - // } else { - // if (state.focusEdit.isNew) { - // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - // const files = removePath(state.focusEdit.element, state.files) - // const updatedFiles = files.filter(file => file) - - // setState(prevState => { - // return { ...prevState, files: updatedFiles } - // }) - // } else { - // const oldPath: string = state.focusEdit.element - // const oldName = extractNameFromKey(oldPath) - // const newPath = oldPath.replace(oldName, content) + if (!content || (content.trim() === '')) { + if (state.focusEdit.isNew) { + removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) + setState(prevState => { + return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + }) + } else { + editRef.current.textContent = state.focusEdit.lastEdit + setState(prevState => { + return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + }) + } + } else { + if (state.focusEdit.lastEdit === content) { + editRef.current.textContent = content + return setState(prevState => { + return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + }) + } + if (helper.checkSpecialChars(content)) { + modal('Validation Error', 'Special characters are not allowed', { + label: 'OK', + fn: () => {} + }, null) + } else { + if (state.focusEdit.isNew) { + // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) + removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) + } else { + const oldPath: string = state.focusEdit.element + // const oldName = extractNameFromKey(oldPath) + // const newPath = oldPath.replace(oldName, content) - // editRef.current.textContent = extractNameFromKey(oldPath) - // renamePath(oldPath, newPath) - // } - // setState(prevState => { - // return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } - // }) - // } - // } - // } + editRef.current.textContent = extractNameFromKey(oldPath) + // renamePath(oldPath, newPath) + } + setState(prevState => { + return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } + }) + } + } + } const handleNewFileInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name const expandPath = [...new Set([...state.expandPath, parentFolder])] + await addInputField(fileSystem.provider.provider, 'file', parentFolder)(dispatch) setState(prevState => { return { ...prevState, expandPath } }) @@ -784,22 +778,23 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleNewFolderInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name else if ((parentFolder.indexOf('.sol') !== -1) || (parentFolder.indexOf('.js') !== -1)) parentFolder = extractParentFromKey(parentFolder) const expandPath = [...new Set([...state.expandPath, parentFolder])] + await addInputField(fileSystem.provider.provider, 'folder', parentFolder)(dispatch) setState(prevState => { return { ...prevState, expandPath } }) editModeOn(parentFolder + '/blank', 'folder', true) } - // const handleEditInput = (event) => { - // if (event.which === 13) { - // event.preventDefault() - // editModeOff(editRef.current.innerText) - // } - // } + const handleEditInput = (event) => { + if (event.which === 13) { + event.preventDefault() + editModeOff(editRef.current.innerText) + } + } const handleMouseOver = (path: string) => { setState(prevState => { @@ -820,11 +815,11 @@ export const FileExplorer = (props: FileExplorerProps) => { ref={state.focusEdit.element === file.path ? editRef : null} suppressContentEditableWarning={true} contentEditable={state.focusEdit.element === file.path} - // onKeyDown={handleEditInput} - // onBlur={(e) => { - // e.stopPropagation() - // editModeOff(editRef.current.innerText) - // }} + onKeyDown={handleEditInput} + onBlur={(e) => { + e.stopPropagation() + editModeOff(editRef.current.innerText) + }} > { const pathArr = path.split('/') - if (pathArr[0] !== root) pathArr.unshift(root) + if (pathArr[0] !== root) pathArr.unshift(root) files = _.set(files, pathArr, { isDirectory: true, path, @@ -152,3 +179,16 @@ const resolveDirectory = (root, path: string, files, content) => { return files } + +const addInputField = (root, path: string, files, content) => { + if (Object.keys(content)[0] === root) return { [Object.keys(content)[0]]: { ...content[Object.keys(content)[0]], ...files[Object.keys(content)[0]] } } + return resolveDirectory(root, path, files, content) +} + +const removeInputField = (root, path: string, files, content) => { + if (Object.keys(content)[0] === root) { + delete files[root][path + '/' + 'blank'] + return files + } + return resolveDirectory(root, path, files, content) +} From 837490e9a4475758a6dfbd8e62f8596c0bb9df05 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 22 Apr 2021 20:53:32 +0100 Subject: [PATCH 132/199] Fix file added bug --- apps/remix-ide/src/app/files/fileProvider.js | 2 +- .../src/app/files/workspaceFileProvider.js | 2 +- apps/remix-ide/src/lib/helper.js | 21 +++++ .../src/lib/actions/fileSystem.ts | 12 ++- .../file-explorer/src/lib/file-explorer.tsx | 89 +++++++------------ .../src/lib/reducers/fileSystem.ts | 1 + 6 files changed, 61 insertions(+), 66 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 544a1b0bab..999587c7e0 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -67,7 +67,7 @@ class FileProvider { // todo check the type (directory/file) as well #2386 // currently it is not possible to have a file and folder with same path const ret = this._exists(path) - if (cb) cb(null, ret) + return ret } diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index 742d85a775..156723b622 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -33,7 +33,7 @@ class WorkspaceFileProvider extends FileProvider { if (!this.workspace) this.createWorkspace() path = path.replace(/^\/|\/$/g, '') // remove first and last slash if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path - if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace + if (path.startsWith(this.workspace)) return path.replace(this.workspace, this.workspacesPath + '/' + this.workspace) path = super.removePrefix(path) let ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path) diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index ac3f71a0e5..2757fc84da 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -52,6 +52,27 @@ module.exports = { createNonClashingName (name, fileProvider, cb) { this.createNonClashingNameWithPrefix(name, fileProvider, '', cb) }, + async checkNonClashingNameAsync (name, fileManager, prefix = '') { + if (!name) name = 'Undefined' + let counter = '' + let ext = 'sol' + const reg = /(.*)\.([^.]+)/g + const split = reg.exec(name) + if (split) { + name = split[1] + ext = split[2] + } + let exist = true + + do { + const isDuplicate = await fileManager.exists(name + counter + prefix + '.' + ext) + + if (isDuplicate) counter = (counter | 0) + 1 + else exist = false + } while (exist) + + return name + counter + prefix + '.' + ext + }, checkSpecialChars (name) { return name.match(/[:*?"<>\\'|]/) != null }, diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 49a95ec4f9..7e552115e7 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -151,9 +151,13 @@ export const fetchProviderSuccess = (provider: any) => { } } -export const setProvider = (provider) => (dispatch: React.Dispatch) => { +export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatch) => { if (provider) { + provider.event.register('fileAdded', async (filePath) => { + resolveDirectory(provider, extractParentFromKey(filePath) || workspaceName)(dispatch) + }) dispatch(fetchProviderSuccess(provider)) + dispatch(setCurrentWorkspace(workspaceName)) } else { dispatch(fetchProviderError('No provider available')) } @@ -166,12 +170,6 @@ export const setCurrentWorkspace = (name: string) => { } } -export const setWorkspace = (name: string) => (dispatch: React.Dispatch) => { - if (name) { - dispatch(setCurrentWorkspace(name)) - } -} - export const addInputFieldSuccess = (path: string, files: File[]) => { return { type: 'ADD_INPUT_FIELD', diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index a65cffb003..9d1bc176a3 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory, setProvider, resolveDirectory, setWorkspace, addInputField, removeInputField } from './actions/fileSystem' +import { fetchDirectory, setProvider, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -108,8 +108,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { - setProvider(props.filesProvider)(dispatch) - setWorkspace(props.name)(dispatch) + setProvider(props.filesProvider, props.name)(dispatch) } }, [props.filesProvider]) @@ -217,7 +216,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [state.modals]) - const extractNameFromKey = (key: string):string => { const keyPath = key.split('/') @@ -232,36 +230,28 @@ export const FileExplorer = (props: FileExplorerProps) => { return keyPath.join('/') } - // const createNewFile = (newFilePath: string) => { - // const fileManager = state.fileManager + const createNewFile = async (newFilePath: string) => { + const fileManager = state.fileManager - // try { - // helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => { - // if (error) { - // modal('Create File Failed', error, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } else { - // const createFile = await fileManager.writeFile(newName, '') - - // if (!createFile) { - // return toast('Failed to create file ' + newName) - // } else { - // await fileManager.open(newName) - // setState(prevState => { - // return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } - // }) - // } - // } - // }) - // } catch (error) { - // return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } - // } + try { + const newName = await helper.checkNonClashingNameAsync(newFilePath, fileManager) + const createFile = await fileManager.writeFile(newName, '') + + if (!createFile) { + return toast('Failed to create file ' + newName) + } else { + await fileManager.open(newName) + setState(prevState => { + return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } + }) + } + } catch (error) { + return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { + label: 'Close', + fn: async () => {} + }, null) + } + } // const createNewFolder = async (newFolderPath: string) => { // const fileManager = state.fileManager @@ -347,23 +337,6 @@ export const FileExplorer = (props: FileExplorerProps) => { // }) // } - // const fileAdded = async (filePath: string) => { - // const pathArr = filePath.split('/') - // const expandPath = pathArr.map((path, index) => { - // return [...pathArr.slice(0, index)].join('/') - // }).filter(path => path && (path !== props.name)) - // const files = await fetchDirectoryContent(props.name) - - // setState(prevState => { - // const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] - - // return { ...prevState, files, expandPath: uniquePaths } - // }) - // if (filePath.includes('_test.sol')) { - // plugin.event.trigger('newTestFileCreated', [filePath]) - // } - // } - // const folderAdded = async (folderPath: string) => { // const pathArr = folderPath.split('/') // const expandPath = pathArr.map((path, index) => { @@ -659,6 +632,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleClickFile = (path: string) => { + console.log('path: ', path) state.fileManager.open(path) setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'file' }] } @@ -750,6 +724,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } else { if (state.focusEdit.isNew) { // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) + createNewFile(joinPath(parentFolder, content)) removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) } else { const oldPath: string = state.focusEdit.element @@ -767,7 +742,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleNewFileInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name const expandPath = [...new Set([...state.expandPath, parentFolder])] await addInputField(fileSystem.provider.provider, 'file', parentFolder)(dispatch) @@ -778,7 +753,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleNewFolderInput = async (parentFolder?: string) => { - if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) : name + if (!parentFolder) parentFolder = state.focusElement[0] ? state.focusElement[0].type === 'folder' ? state.focusElement[0].key ? state.focusElement[0].key : name : extractParentFromKey(state.focusElement[0].key) ? extractParentFromKey(state.focusElement[0].key) : name : name else if ((parentFolder.indexOf('.sol') !== -1) || (parentFolder.indexOf('.js') !== -1)) parentFolder = extractParentFromKey(parentFolder) const expandPath = [...new Set([...state.expandPath, parentFolder])] @@ -1008,8 +983,8 @@ async function packageFiles (filesProvider, directory, callback) { } } -// function joinPath (...paths) { -// paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) -// if (paths.length === 1) return paths[0] -// return paths.join('/') -// } +function joinPath (...paths) { + paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash) + if (paths.length === 1) return paths[0] + return paths.join('/') +} diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index bc2b96e409..e673efba75 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -167,6 +167,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } const resolveDirectory = (root, path: string, files, content) => { + if (path === root) return { [root]: { ...content[root], ...files[root] } } const pathArr = path.split('/') if (pathArr[0] !== root) pathArr.unshift(root) From 49e0da7c50f5aeed82ac8775dbfe6d224347726e Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Fri, 23 Apr 2021 13:34:47 +0100 Subject: [PATCH 133/199] Fix event bugs --- .../src/lib/actions/fileSystem.ts | 8 +- .../file-explorer/src/lib/file-explorer.tsx | 104 +++++------------- .../src/lib/reducers/fileSystem.ts | 12 +- 3 files changed, 45 insertions(+), 79 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 7e552115e7..52c28fd11c 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -153,9 +153,15 @@ export const fetchProviderSuccess = (provider: any) => { export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatch) => { if (provider) { - provider.event.register('fileAdded', async (filePath) => { + provider.event.register('fileAdded', (filePath) => { resolveDirectory(provider, extractParentFromKey(filePath) || workspaceName)(dispatch) }) + provider.event.register('folderAdded', (folderPath) => { + resolveDirectory(provider, extractParentFromKey(folderPath) || workspaceName)(dispatch) + }) + provider.event.register('fileRemoved', (path) => { + resolveDirectory(provider, extractParentFromKey(path) || workspaceName)(dispatch) + }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) } else { diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 9d1bc176a3..5102cacb8f 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -253,32 +253,34 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - // const createNewFolder = async (newFolderPath: string) => { - // const fileManager = state.fileManager - // const dirName = newFolderPath + '/' + const createNewFolder = async (newFolderPath: string) => { + const fileManager = state.fileManager + const dirName = newFolderPath + '/' - // try { - // const exists = await fileManager.exists(dirName) + try { + const exists = await fileManager.exists(dirName) - // if (exists) { - // return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, { - // label: 'Close', - // fn: () => {} - // }, null) - // } - // await fileManager.mkdir(dirName) - // setState(prevState => { - // return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } - // }) - // } catch (e) { - // return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } - // } + if (exists) { + return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, { + label: 'Close', + fn: () => {} + }, null) + } + await fileManager.mkdir(dirName) + setState(prevState => { + return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } + }) + } catch (e) { + return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, { + label: 'Close', + fn: async () => {} + }, null) + } + } const deletePath = async (path: string) => { + const filesProvider = fileSystem.provider.provider + if (filesProvider.isReadOnly(path)) { return toast('cannot delete file. ' + name + ' is a read only explorer') } @@ -322,35 +324,6 @@ export const FileExplorer = (props: FileExplorerProps) => { // } // } - // const removePath = (path: string, files: File[]): File[] => { - // return files.map(file => { - // if (file.path === path) { - // return null - // } else if (file.child) { - // const childFiles = removePath(path, file.child) - - // file.child = childFiles.filter(file => file) - // return file - // } else { - // return file - // } - // }) - // } - - // const folderAdded = async (folderPath: string) => { - // const pathArr = folderPath.split('/') - // const expandPath = pathArr.map((path, index) => { - // return [...pathArr.slice(0, index)].join('/') - // }).filter(path => path && (path !== props.name)) - // const files = await fetchDirectoryContent(props.name) - - // setState(prevState => { - // const uniquePaths = [...new Set([...prevState.expandPath, ...expandPath])] - - // return { ...prevState, files, expandPath: uniquePaths } - // }) - // } - const fileExternallyChanged = (path: string, file: { content: string }) => { const config = registry.get('config').api const editor = registry.get('editor').api @@ -369,23 +342,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - // const fileRemoved = (filePath) => { - // const files = removePath(filePath, state.files) - // const updatedFiles = files.filter(file => file) - - // setState(prevState => { - // return { ...prevState, files: updatedFiles } - // }) - // } - - // const fileRenamed = async () => { - // const files = await fetchDirectoryContent(props.name) - - // setState(prevState => { - // return { ...prevState, files, expandPath: [...prevState.expandPath] } - // }) - // } - // register to event of the file provider // files.event.register('fileRenamed', fileRenamed) const fileRenamedError = (error: string) => { @@ -632,7 +588,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleClickFile = (path: string) => { - console.log('path: ', path) state.fileManager.open(path) setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'file' }] } @@ -655,6 +610,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (!state.expandPath.includes(path)) { expandPath = [...new Set([...state.expandPath, path])] + resolveDirectory(fileSystem.provider.provider, path)(dispatch) } else { expandPath = [...new Set(state.expandPath.filter(key => key && (typeof key === 'string') && !key.startsWith(path)))] } @@ -662,7 +618,6 @@ export const FileExplorer = (props: FileExplorerProps) => { setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'folder' }], expandPath } }) - resolveDirectory(fileSystem.provider.provider, path)(dispatch) } } @@ -723,8 +678,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }, null) } else { if (state.focusEdit.isNew) { - // state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - createNewFile(joinPath(parentFolder, content)) + state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) } else { const oldPath: string = state.focusEdit.element @@ -845,12 +799,12 @@ export const FileExplorer = (props: FileExplorerProps) => { }} > { - file.child ? { + file.child ? { Object.keys(file.child).map((key, index) => { return renderFiles(file.child[key], index) }) } - : + : } ) @@ -858,7 +812,7 @@ export const FileExplorer = (props: FileExplorerProps) => { return ( { e.stopPropagation() diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index e673efba75..cd6ad31b4d 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -168,10 +168,14 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action const resolveDirectory = (root, path: string, files, content) => { if (path === root) return { [root]: { ...content[root], ...files[root] } } - const pathArr = path.split('/') + const pathArr: string[] = path.split('/') if (pathArr[0] !== root) pathArr.unshift(root) - files = _.set(files, pathArr, { + const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { + return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur] + }, []) + + files = _.set(files, _path, { isDirectory: true, path, name: extractNameFromKey(path), @@ -183,7 +187,9 @@ const resolveDirectory = (root, path: string, files, content) => { const addInputField = (root, path: string, files, content) => { if (Object.keys(content)[0] === root) return { [Object.keys(content)[0]]: { ...content[Object.keys(content)[0]], ...files[Object.keys(content)[0]] } } - return resolveDirectory(root, path, files, content) + const result = resolveDirectory(root, path, files, content) + + return result } const removeInputField = (root, path: string, files, content) => { From 7deedbad2ba367600beafdfd6d905957087f8b51 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sat, 24 Apr 2021 14:27:06 +0100 Subject: [PATCH 134/199] replace directory bug --- .../src/lib/actions/fileSystem.ts | 47 ++++++++++++++-- .../src/lib/reducers/fileSystem.ts | 56 ++++++++++++++++++- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 52c28fd11c..029711c5aa 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -151,16 +151,51 @@ export const fetchProviderSuccess = (provider: any) => { } } +export const fileAddedSuccess = (path: string, files) => { + return { + type: 'FILE_ADDED', + payload: { path, files } + } +} + +export const folderAddedSuccess = (path: string, files) => { + return { + type: 'FOLDER_ADDED', + payload: { path, files } + } +} + +export const fileRemovedSuccess = (path: string, removePath: string, files) => { + return { + type: 'FILE_REMOVED', + payload: { path, removePath, files } + } +} + export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatch) => { if (provider) { - provider.event.register('fileAdded', (filePath) => { - resolveDirectory(provider, extractParentFromKey(filePath) || workspaceName)(dispatch) + provider.event.register('fileAdded', async (filePath) => { + const path = extractParentFromKey(filePath) || workspaceName + const data = await fetchDirectoryContent(provider, path) + + dispatch(fileAddedSuccess(path, data)) }) - provider.event.register('folderAdded', (folderPath) => { - resolveDirectory(provider, extractParentFromKey(folderPath) || workspaceName)(dispatch) + provider.event.register('folderAdded', async (folderPath) => { + const path = extractParentFromKey(folderPath) || workspaceName + const data = await fetchDirectoryContent(provider, path) + + console.log('data: ', data) + + dispatch(folderAddedSuccess(path, data)) }) - provider.event.register('fileRemoved', (path) => { - resolveDirectory(provider, extractParentFromKey(path) || workspaceName)(dispatch) + provider.event.register('fileRemoved', async (removePath) => { + const path = extractParentFromKey(removePath) || workspaceName + const data = await fetchDirectoryContent(provider, path) + + dispatch(fileRemovedSuccess(path, removePath, data)) + }) + provider.event.register('fileRenamed', async () => { + }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index cd6ad31b4d..d647e32d69 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -161,6 +161,42 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'FILE_ADDED': { + return { + ...state, + files: { + ...state.files, + files: fileAdded(state.files.workspaceName, action.payload.path, state.files.files, action.payload.files), + isRequesting: false, + isSuccessful: true, + error: null + } + } + } + case 'FOLDER_ADDED': { + return { + ...state, + files: { + ...state.files, + files: folderAdded(state.files.workspaceName, action.payload.path, state.files.files, action.payload.files), + isRequesting: false, + isSuccessful: true, + error: null + } + } + } + case 'FILE_REMOVED': { + return { + ...state, + files: { + ...state.files, + files: fileRemoved(state.files.workspaceName, action.payload.path, action.payload.removePath, state.files.files, action.payload.files), + isRequesting: false, + isSuccessful: true, + error: null + } + } + } default: throw new Error() } @@ -168,7 +204,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action const resolveDirectory = (root, path: string, files, content) => { if (path === root) return { [root]: { ...content[root], ...files[root] } } - const pathArr: string[] = path.split('/') + const pathArr: string[] = path.split('/').filter(value => value) if (pathArr[0] !== root) pathArr.unshift(root) const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { @@ -199,3 +235,21 @@ const removeInputField = (root, path: string, files, content) => { } return resolveDirectory(root, path, files, content) } + +const fileAdded = (root, path: string, files, content) => { + return resolveDirectory(root, path, files, content) +} + +const folderAdded = (root, path: string, files, content) => { + return resolveDirectory(root, path, files, content) +} + +const fileRemoved = (root, path: string, removedPath: string, files, content) => { + if (path === root) { + const allFiles = { [root]: { ...content[root], ...files[root] } } + + delete allFiles[root][removedPath] + return allFiles + } + return resolveDirectory(root, path, files, content) +} From 7033c20013c41d6943693d1355368a58650f1477 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sat, 24 Apr 2021 15:41:11 +0100 Subject: [PATCH 135/199] Fixed file/folder removed bug --- .../src/lib/actions/fileSystem.ts | 24 +++------- .../file-explorer/src/lib/file-explorer.tsx | 11 +++-- .../src/lib/reducers/fileSystem.ts | 45 ++++++++++++++----- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 029711c5aa..92beacb84a 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -165,10 +165,10 @@ export const folderAddedSuccess = (path: string, files) => { } } -export const fileRemovedSuccess = (path: string, removePath: string, files) => { +export const fileRemovedSuccess = (path: string, removePath: string) => { return { type: 'FILE_REMOVED', - payload: { path, removePath, files } + payload: { path, removePath } } } @@ -184,15 +184,12 @@ export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatc const path = extractParentFromKey(folderPath) || workspaceName const data = await fetchDirectoryContent(provider, path) - console.log('data: ', data) - dispatch(folderAddedSuccess(path, data)) }) provider.event.register('fileRemoved', async (removePath) => { const path = extractParentFromKey(removePath) || workspaceName - const data = await fetchDirectoryContent(provider, path) - dispatch(fileRemovedSuccess(path, removePath, data)) + dispatch(fileRemovedSuccess(path, removePath)) }) provider.event.register('fileRenamed', async () => { @@ -229,20 +226,13 @@ export const addInputField = (provider, type: string, path: string) => (dispatch return promise } -export const removeInputFieldSuccess = (path: string, files: File[]) => { +export const removeInputFieldSuccess = (path: string) => { return { type: 'REMOVE_INPUT_FIELD', - payload: { path, files } + payload: { path } } } -export const removeInputField = (provider, path: string) => (dispatch: React.Dispatch) => { - const promise = fetchDirectoryContent(provider, path) - - promise.then((files) => { - dispatch(removeInputFieldSuccess(path, files)) - }).catch((error) => { - console.error(error) - }) - return promise +export const removeInputField = (path: string) => (dispatch: React.Dispatch) => { + return dispatch(removeInputFieldSuccess(path)) } diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 5102cacb8f..35cf6149cc 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -654,7 +654,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (!content || (content.trim() === '')) { if (state.focusEdit.isNew) { - removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) + removeInputField(parentFolder)(dispatch) setState(prevState => { return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } }) @@ -679,7 +679,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } else { if (state.focusEdit.isNew) { state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - removeInputField(fileSystem.provider.provider, parentFolder)(dispatch) + removeInputField(parentFolder)(dispatch) } else { const oldPath: string = state.focusEdit.element // const oldName = extractNameFromKey(oldPath) @@ -768,6 +768,9 @@ export const FileExplorer = (props: FileExplorerProps) => { ? 'bg-light border' : (state.focusContext.element === file.path) && (state.focusEdit.element !== file.path) ? 'bg-light border' : '' const icon = helper.getPathIcon(file.path) + const spreadProps = { + onClick: (e) => e.stopPropagation() + } if (file.isDirectory) { return ( @@ -799,12 +802,12 @@ export const FileExplorer = (props: FileExplorerProps) => { }} > { - file.child ? { + file.child ? { Object.keys(file.child).map((key, index) => { return renderFiles(file.child[key], index) }) } - : + : } ) diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index d647e32d69..ba05a57d9b 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -153,7 +153,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action ...state, files: { ...state.files, - files: removeInputField(state.files.workspaceName, state.files.blankPath, state.files.files, action.payload.files), + files: removeInputField(state.files.workspaceName, state.files.blankPath, state.files.files), blankPath: null, isRequesting: false, isSuccessful: true, @@ -190,7 +190,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action ...state, files: { ...state.files, - files: fileRemoved(state.files.workspaceName, action.payload.path, action.payload.removePath, state.files.files, action.payload.files), + files: fileRemoved(state.files.workspaceName, action.payload.path, action.payload.removePath, state.files.files), isRequesting: false, isSuccessful: true, error: null @@ -211,29 +211,51 @@ const resolveDirectory = (root, path: string, files, content) => { return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur] }, []) + const prevFiles = _.get(files, _path) + + files = _.set(files, _path, { + isDirectory: true, + path, + name: extractNameFromKey(path), + child: { ...content[pathArr[pathArr.length - 1]], ...prevFiles.child } + }) + + return files +} + +const removePath = (root, path: string, pathName, files) => { + const pathArr: string[] = path.split('/').filter(value => value) + + if (pathArr[0] !== root) pathArr.unshift(root) + const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { + return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur] + }, []) + const prevFiles = _.get(files, _path) + + pathName && delete prevFiles.child[pathName] files = _.set(files, _path, { isDirectory: true, path, name: extractNameFromKey(path), - child: { ...content[pathArr[pathArr.length - 1]] } + child: prevFiles.child }) return files } const addInputField = (root, path: string, files, content) => { - if (Object.keys(content)[0] === root) return { [Object.keys(content)[0]]: { ...content[Object.keys(content)[0]], ...files[Object.keys(content)[0]] } } + if (path === root) return { [root]: { ...content[root], ...files[root] } } const result = resolveDirectory(root, path, files, content) return result } -const removeInputField = (root, path: string, files, content) => { - if (Object.keys(content)[0] === root) { +const removeInputField = (root, path: string, files) => { + if (path === root) { delete files[root][path + '/' + 'blank'] return files } - return resolveDirectory(root, path, files, content) + return removePath(root, path, path + '/' + 'blank', files) } const fileAdded = (root, path: string, files, content) => { @@ -244,12 +266,11 @@ const folderAdded = (root, path: string, files, content) => { return resolveDirectory(root, path, files, content) } -const fileRemoved = (root, path: string, removedPath: string, files, content) => { +const fileRemoved = (root, path: string, removedPath: string, files) => { if (path === root) { - const allFiles = { [root]: { ...content[root], ...files[root] } } + delete files[root][removedPath] - delete allFiles[root][removedPath] - return allFiles + return files } - return resolveDirectory(root, path, files, content) + return removePath(root, path, extractNameFromKey(removedPath), files) } From ed03204f25e8e426d2da23899a9a29a151be57cf Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sat, 24 Apr 2021 17:50:26 +0100 Subject: [PATCH 136/199] Init plugin --- .../src/lib/actions/fileSystem.ts | 10 +++++++++- .../file-explorer/src/lib/file-explorer.tsx | 8 ++++++-- .../src/lib/reducers/fileSystem.ts | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 92beacb84a..e3dc559a4b 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -172,7 +172,7 @@ export const fileRemovedSuccess = (path: string, removePath: string) => { } } -export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatch) => { +export const init = (provider, workspaceName: string, plugin) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { const path = extractParentFromKey(filePath) || workspaceName @@ -196,6 +196,7 @@ export const setProvider = (provider, workspaceName) => (dispatch: React.Dispatc }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) + dispatch(setPlugin(plugin)) } else { dispatch(fetchProviderError('No provider available')) } @@ -208,6 +209,13 @@ export const setCurrentWorkspace = (name: string) => { } } +export const setPlugin = (plugin) => { + return { + type: 'SET_PLUGIN', + payload: plugin + } +} + export const addInputFieldSuccess = (path: string, files: File[]) => { return { type: 'ADD_INPUT_FIELD', diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 35cf6149cc..2430b8e0f6 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -8,7 +8,7 @@ import { FileExplorerMenu } from './file-explorer-menu' // eslint-disable-line import { FileExplorerContextMenu } from './file-explorer-context-menu' // eslint-disable-line import { FileExplorerProps, File } from './types' import { fileSystemReducer, fileSystemInitialState } from './reducers/fileSystem' -import { fetchDirectory, setProvider, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem' +import { fetchDirectory, init, resolveDirectory, addInputField, removeInputField } from './actions/fileSystem' import * as helper from '../../../../../apps/remix-ide/src/lib/helper' import QueryParams from '../../../../../apps/remix-ide/src/lib/query-params' @@ -108,7 +108,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { - setProvider(props.filesProvider, props.name)(dispatch) + init(props.filesProvider, props.name, props.plugin)(dispatch) } }, [props.filesProvider]) @@ -361,6 +361,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const uploadFile = (target) => { + const filesProvider = fileSystem.provider.provider // 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 // a file and then just use `files.add`. The file explorer will @@ -433,6 +434,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const toGist = (id?: string) => { + const filesProvider = fileSystem.provider.provider const proccedResult = function (error, data) { if (error) { modal('Publish to gist Failed', 'Failed to manage gist: ' + error, { @@ -549,6 +551,8 @@ export const FileExplorer = (props: FileExplorerProps) => { } const runScript = async (path: string) => { + const filesProvider = fileSystem.provider.provider + filesProvider.get(path, (error, content: string) => { if (error) return console.log(error) plugin.call('scriptRunner', 'execute', content) diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index ba05a57d9b..4f25db4eb7 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -19,6 +19,12 @@ export const fileSystemInitialState = { isRequesting: false, isSuccessful: false, error: null + }, + plugin: { + plugin: null, + isRequesting: false, + isSuccessful: false, + error: null } } @@ -135,6 +141,18 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'SET_PLUGIN': { + return { + ...state, + plugin: { + ...state.plugin, + plugin: action.payload, + isRequesting: false, + isSuccessful: true, + error: null + } + } + } case 'ADD_INPUT_FIELD': { return { ...state, From 59afc28810b105d78cc8d41aab1533a2b5b62ba9 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sat, 24 Apr 2021 19:11:27 +0100 Subject: [PATCH 137/199] Renames but appends to bottom --- .../src/lib/actions/fileSystem.ts | 16 ++++- .../file-explorer/src/lib/file-explorer.tsx | 58 ++++++++----------- .../src/lib/reducers/fileSystem.ts | 49 +++++++++++++++- 3 files changed, 86 insertions(+), 37 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index e3dc559a4b..f1db07e81c 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -172,6 +172,13 @@ export const fileRemovedSuccess = (path: string, removePath: string) => { } } +export const fileRenamedSuccess = (parentPath: string, oldPath: string, newPath: string) => { + return { + type: 'FILE_RENAMED', + payload: { parentPath, oldPath, newPath } + } +} + export const init = (provider, workspaceName: string, plugin) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { @@ -179,6 +186,9 @@ export const init = (provider, workspaceName: string, plugin) => (dispatch: Reac const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) + if (filePath.includes('_test.sol')) { + plugin.event.trigger('newTestFileCreated', [filePath]) + } }) provider.event.register('folderAdded', async (folderPath) => { const path = extractParentFromKey(folderPath) || workspaceName @@ -191,8 +201,12 @@ export const init = (provider, workspaceName: string, plugin) => (dispatch: Reac dispatch(fileRemovedSuccess(path, removePath)) }) - provider.event.register('fileRenamed', async () => { + provider.event.register('fileRenamed', async (oldPath, newPath) => { + console.log('oldPath: ', oldPath) + console.log('newPath: ', newPath) + const parentPath = extractParentFromKey(oldPath) || workspaceName + dispatch(fileRenamedSuccess(parentPath, oldPath, newPath)) }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 2430b8e0f6..820699b95d 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -148,18 +148,6 @@ export const FileExplorer = (props: FileExplorerProps) => { // } // }, [state.fileManager]) - // useEffect(() => { - // // unregister event to update state in callback - // if (filesProvider.event.registered.fileAdded) filesProvider.event.unregister('fileAdded', fileAdded) - // if (filesProvider.event.registered.folderAdded) filesProvider.event.unregister('folderAdded', folderAdded) - // if (filesProvider.event.registered.fileRemoved) filesProvider.event.unregister('fileRemoved', fileRemoved) - // if (filesProvider.event.registered.fileRenamed) filesProvider.event.unregister('fileRenamed', fileRenamed) - // filesProvider.event.register('fileAdded', fileAdded) - // filesProvider.event.register('folderAdded', folderAdded) - // filesProvider.event.register('fileRemoved', fileRemoved) - // filesProvider.event.register('fileRenamed', fileRenamed) - // }, [state.files]) - useEffect(() => { if (focusRoot) { setState(prevState => { @@ -303,26 +291,26 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } - // const renamePath = async (oldPath: string, newPath: string) => { - // try { - // const fileManager = state.fileManager - // const exists = await fileManager.exists(newPath) - - // if (exists) { - // modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, { - // label: 'Close', - // fn: () => {} - // }, null) - // } else { - // await fileManager.rename(oldPath, newPath) - // } - // } catch (error) { - // modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, { - // label: 'Close', - // fn: async () => {} - // }, null) - // } - // } + const renamePath = async (oldPath: string, newPath: string) => { + try { + const fileManager = state.fileManager + const exists = await fileManager.exists(newPath) + + if (exists) { + modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, { + label: 'Close', + fn: () => {} + }, null) + } else { + await fileManager.rename(oldPath, newPath) + } + } catch (error) { + modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, { + label: 'Close', + fn: async () => {} + }, null) + } + } const fileExternallyChanged = (path: string, file: { content: string }) => { const config = registry.get('config').api @@ -686,11 +674,11 @@ export const FileExplorer = (props: FileExplorerProps) => { removeInputField(parentFolder)(dispatch) } else { const oldPath: string = state.focusEdit.element - // const oldName = extractNameFromKey(oldPath) - // const newPath = oldPath.replace(oldName, content) + const oldName = extractNameFromKey(oldPath) + const newPath = oldPath.replace(oldName, content) editRef.current.textContent = extractNameFromKey(oldPath) - // renamePath(oldPath, newPath) + renamePath(oldPath, newPath) } setState(prevState => { return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 4f25db4eb7..c06dc87485 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -215,6 +215,18 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'FILE_RENAMED': { + return { + ...state, + files: { + ...state.files, + files: fileRenamed(state.files.workspaceName, action.payload.parentPath, action.payload.oldPath, action.payload.newPath, state.files.files), + isRequesting: false, + isSuccessful: true, + error: null + } + } + } default: throw new Error() } @@ -250,7 +262,7 @@ const removePath = (root, path: string, pathName, files) => { }, []) const prevFiles = _.get(files, _path) - pathName && delete prevFiles.child[pathName] + prevFiles.child[pathName] && delete prevFiles.child[pathName] files = _.set(files, _path, { isDirectory: true, path, @@ -292,3 +304,38 @@ const fileRemoved = (root, path: string, removedPath: string, files) => { } return removePath(root, path, extractNameFromKey(removedPath), files) } + +const fileRenamed = (root, parentPath: string, oldPath: string, newPath: string, files) => { + if (parentPath === root) { + const newPathName = extractNameFromKey(newPath) || newPath + files[root][newPathName] = { + ...files[root][oldPath], + path: newPath, + name: newPathName + } + delete files[root][extractNameFromKey(oldPath) || oldPath] + return files + } + const pathArr: string[] = parentPath.split('/').filter(value => value) + + if (pathArr[0] !== root) pathArr.unshift(root) + const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { + return Array.isArray(cur) ? [...acc, ...cur] : [...acc, cur] + }, []) + const prevFiles = _.get(files, _path) + + prevFiles.child[extractNameFromKey(newPath)] = { + ...prevFiles.child[oldPath], + path: newPath, + name: extractNameFromKey(newPath) + } + delete prevFiles.child[extractNameFromKey(oldPath)] + files = _.set(files, _path, { + isDirectory: true, + path: parentPath, + name: extractNameFromKey(parentPath), + child: prevFiles.child + }) + + return files +} From b71001ea8f851e2fe2ef41a1ba3977f6df30a02a Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sun, 25 Apr 2021 17:10:24 +0100 Subject: [PATCH 138/199] Fixed renamed position --- .../src/lib/actions/fileSystem.ts | 11 +++---- .../src/lib/reducers/fileSystem.ts | 33 +++++++------------ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index f1db07e81c..73832ac32c 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -172,10 +172,10 @@ export const fileRemovedSuccess = (path: string, removePath: string) => { } } -export const fileRenamedSuccess = (parentPath: string, oldPath: string, newPath: string) => { +export const fileRenamedSuccess = (path: string, removePath: string, files) => { return { type: 'FILE_RENAMED', - payload: { parentPath, oldPath, newPath } + payload: { path, removePath, files } } } @@ -202,11 +202,10 @@ export const init = (provider, workspaceName: string, plugin) => (dispatch: Reac dispatch(fileRemovedSuccess(path, removePath)) }) provider.event.register('fileRenamed', async (oldPath, newPath) => { - console.log('oldPath: ', oldPath) - console.log('newPath: ', newPath) - const parentPath = extractParentFromKey(oldPath) || workspaceName + const path = extractParentFromKey(oldPath) || workspaceName + const data = await fetchDirectoryContent(provider, path) - dispatch(fileRenamedSuccess(parentPath, oldPath, newPath)) + dispatch(fileRenamedSuccess(path, oldPath, data)) }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index c06dc87485..99b4fcb8d0 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -220,7 +220,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action ...state, files: { ...state.files, - files: fileRenamed(state.files.workspaceName, action.payload.parentPath, action.payload.oldPath, action.payload.newPath, state.files.files), + files: fileRenamed(state.files.workspaceName, action.payload.path, action.payload.removePath, state.files.files, action.payload.files), isRequesting: false, isSuccessful: true, error: null @@ -305,18 +305,14 @@ const fileRemoved = (root, path: string, removedPath: string, files) => { return removePath(root, path, extractNameFromKey(removedPath), files) } -const fileRenamed = (root, parentPath: string, oldPath: string, newPath: string, files) => { - if (parentPath === root) { - const newPathName = extractNameFromKey(newPath) || newPath - files[root][newPathName] = { - ...files[root][oldPath], - path: newPath, - name: newPathName - } - delete files[root][extractNameFromKey(oldPath) || oldPath] - return files +const fileRenamed = (root, path: string, removePath: string, files, content) => { + if (path === root) { + const allFiles = { [root]: { ...content[root], ...files[root] } } + + delete allFiles[root][extractNameFromKey(removePath) || removePath] + return allFiles } - const pathArr: string[] = parentPath.split('/').filter(value => value) + const pathArr: string[] = path.split('/').filter(value => value) if (pathArr[0] !== root) pathArr.unshift(root) const _path = pathArr.map((key, index) => index > 1 ? ['child', key] : key).reduce((acc: string[], cur) => { @@ -324,17 +320,12 @@ const fileRenamed = (root, parentPath: string, oldPath: string, newPath: string, }, []) const prevFiles = _.get(files, _path) - prevFiles.child[extractNameFromKey(newPath)] = { - ...prevFiles.child[oldPath], - path: newPath, - name: extractNameFromKey(newPath) - } - delete prevFiles.child[extractNameFromKey(oldPath)] + delete prevFiles.child[extractNameFromKey(removePath)] files = _.set(files, _path, { isDirectory: true, - path: parentPath, - name: extractNameFromKey(parentPath), - child: prevFiles.child + path, + name: extractNameFromKey(path), + child: { ...content[pathArr[pathArr.length - 1]], ...prevFiles.child } }) return files From 1f7d1fa4b70d212e8736e3cdbd2b3dfb267b7e29 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Sun, 25 Apr 2021 18:40:11 +0100 Subject: [PATCH 139/199] Complete notifications setup --- .../src/lib/actions/fileSystem.ts | 51 ++++++++++++---- .../file-explorer/src/lib/file-explorer.tsx | 58 +++++-------------- .../src/lib/reducers/fileSystem.ts | 43 ++++++++------ .../src/lib/reducers/notification.ts | 0 .../file-explorer/src/lib/types/index.ts | 2 +- 5 files changed, 81 insertions(+), 73 deletions(-) delete mode 100644 libs/remix-ui/file-explorer/src/lib/reducers/notification.ts diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 73832ac32c..eb0303e45d 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -179,7 +179,7 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { } } -export const init = (provider, workspaceName: string, plugin) => (dispatch: React.Dispatch) => { +export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { const path = extractParentFromKey(filePath) || workspaceName @@ -201,15 +201,36 @@ export const init = (provider, workspaceName: string, plugin) => (dispatch: Reac dispatch(fileRemovedSuccess(path, removePath)) }) - provider.event.register('fileRenamed', async (oldPath, newPath) => { + provider.event.register('fileRenamed', async (oldPath) => { const path = extractParentFromKey(oldPath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileRenamedSuccess(path, oldPath, data)) }) + provider.event.register('fileExternallyChanged', async (path: string, file: { content: string }) => { + const config = registry.get('config').api + const editor = registry.get('editor').api + + if (config.get('currentFile') === path && editor.currentContent() !== file.content) { + if (provider.isReadOnly(path)) return editor.setText(file.content) + dispatch(displayNotification( + path + ' changed', + 'This file has been changed outside of Remix IDE.', + 'Replace by the new content', 'Keep the content displayed in Remix', + () => { + editor.setText(file.content) + } + )) + } + }) + provider.event.register('fileRenamedError', async () => { + dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel')) + }) + provider.event.register('rootFolderChanged', async () => { + fetchDirectory(provider, workspaceName)(dispatch) + }) dispatch(fetchProviderSuccess(provider)) dispatch(setCurrentWorkspace(workspaceName)) - dispatch(setPlugin(plugin)) } else { dispatch(fetchProviderError('No provider available')) } @@ -222,13 +243,6 @@ export const setCurrentWorkspace = (name: string) => { } } -export const setPlugin = (plugin) => { - return { - type: 'SET_PLUGIN', - payload: plugin - } -} - export const addInputFieldSuccess = (path: string, files: File[]) => { return { type: 'ADD_INPUT_FIELD', @@ -257,3 +271,20 @@ export const removeInputFieldSuccess = (path: string) => { export const removeInputField = (path: string) => (dispatch: React.Dispatch) => { return dispatch(removeInputFieldSuccess(path)) } + +export const displayNotification = (title: string, message: string, labelOk: string, labelCancel: string, actionOk?: (...args) => void, actionCancel?: (...args) => void) => { + return { + type: 'DISPLAY_NOTIFICATION', + payload: { title, message, labelOk, labelCancel, actionOk, actionCancel } + } +} + +export const hideNotification = () => { + return { + type: 'DISPLAY_NOTIFICATION' + } +} + +export const closeNotificationModal = () => (dispatch: React.Dispatch) => { + dispatch(hideNotification()) +} diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 820699b95d..a83b81d044 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -108,7 +108,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (props.filesProvider) { - init(props.filesProvider, props.name, props.plugin)(dispatch) + init(props.filesProvider, props.name, props.plugin, props.registry)(dispatch) } }, [props.filesProvider]) @@ -120,6 +120,18 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [fileSystem.provider.provider]) + useEffect(() => { + if (fileSystem.notification.message) { + modal(fileSystem.notification.title, fileSystem.notification.message, { + label: fileSystem.notification.labelOk, + fn: fileSystem.notification.actionOk + }, { + label: fileSystem.notification.labelCancel, + fn: fileSystem.notification.actionCancel + }) + } + }, [fileSystem.notification.message]) + useEffect(() => { if (state.focusEdit.element) { setTimeout(() => { @@ -140,14 +152,6 @@ export const FileExplorer = (props: FileExplorerProps) => { })() }, [name]) - // useEffect(() => { - // if (state.fileManager) { - // filesProvider.event.register('fileExternallyChanged', fileExternallyChanged) - // filesProvider.event.register('fileRenamedError', fileRenamedError) - // filesProvider.event.register('rootFolderChanged', rootFolderChanged) - // } - // }, [state.fileManager]) - useEffect(() => { if (focusRoot) { setState(prevState => { @@ -312,42 +316,6 @@ export const FileExplorer = (props: FileExplorerProps) => { } } - const fileExternallyChanged = (path: string, file: { content: string }) => { - const config = registry.get('config').api - const editor = registry.get('editor').api - - if (config.get('currentFile') === path && editor.currentContent() !== file.content) { - if (filesProvider.isReadOnly(path)) return editor.setText(file.content) - modal(path + ' changed', 'This file has been changed outside of Remix IDE.', { - label: 'Replace by the new content', - fn: () => { - editor.setText(file.content) - } - }, { - label: 'Keep the content displayed in Remix', - fn: () => {} - }) - } - } - - // register to event of the file provider - // files.event.register('fileRenamed', fileRenamed) - const fileRenamedError = (error: string) => { - modal('File Renamed Failed', error, { - label: 'Close', - fn: () => {} - }, null) - } - - // register to event of the file provider - // files.event.register('rootFolderChanged', rootFolderChanged) - const rootFolderChanged = async () => { - const files = await fetchDirectoryContent(name) - setState(prevState => { - return { ...prevState, files } - }) - } - const uploadFile = (target) => { const filesProvider = fileSystem.provider.provider // TODO The file explorer is merely a view on the current state of diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 99b4fcb8d0..df4475108e 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -20,11 +20,13 @@ export const fileSystemInitialState = { isSuccessful: false, error: null }, - plugin: { - plugin: null, - isRequesting: false, - isSuccessful: false, - error: null + notification: { + title: null, + message: null, + actionOk: () => {}, + actionCancel: () => {}, + labelOk: null, + labelCancel: null } } @@ -141,18 +143,6 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } - case 'SET_PLUGIN': { - return { - ...state, - plugin: { - ...state.plugin, - plugin: action.payload, - isRequesting: false, - isSuccessful: true, - error: null - } - } - } case 'ADD_INPUT_FIELD': { return { ...state, @@ -227,6 +217,25 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action } } } + case 'DISPLAY_NOTIFICATION': { + return { + ...state, + notification: { + title: action.payload.title, + message: action.payload.message, + actionOk: action.payload.actionOk || fileSystemInitialState.notification.actionOk, + actionCancel: action.payload.actionCancel || fileSystemInitialState.notification.actionCancel, + labelOk: action.payload.labelOk, + labelCancel: action.payload.labelCancel + } + } + } + case 'HIDE_NOTIFICATION': { + return { + ...state, + notification: fileSystemInitialState.notification + } + } default: throw new Error() } diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts b/libs/remix-ui/file-explorer/src/lib/reducers/notification.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/remix-ui/file-explorer/src/lib/types/index.ts b/libs/remix-ui/file-explorer/src/lib/types/index.ts index 61c554dc3a..17d6975414 100644 --- a/libs/remix-ui/file-explorer/src/lib/types/index.ts +++ b/libs/remix-ui/file-explorer/src/lib/types/index.ts @@ -6,7 +6,7 @@ export interface FileExplorerProps { menuItems?: string[], plugin: any, focusRoot: boolean, - contextMenuItems: { name: string, type: string[], path: string[], extension: string[], pattern: string[] }[], + contextMenuItems: { id: string, name: string, type: string[], path: string[], extension: string[], pattern: string[] }[], displayInput?: boolean, externalUploads?: EventTarget & HTMLInputElement } From b5841428039f8074fe172577e643953edc1ad723 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 26 Apr 2021 12:12:41 +0100 Subject: [PATCH 140/199] Update selector for blank input field. --- apps/remix-ide-e2e/src/commands/addFile.ts | 6 +++--- apps/remix-ide-e2e/src/tests/fileExplorer.test.ts | 12 ++++++------ apps/remix-ide-e2e/src/tests/gist.spec.ts | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/addFile.ts b/apps/remix-ide-e2e/src/commands/addFile.ts index 80838ff9d7..bc2f40e114 100644 --- a/apps/remix-ide-e2e/src/commands/addFile.ts +++ b/apps/remix-ide-e2e/src/commands/addFile.ts @@ -18,9 +18,9 @@ function addFile (browser: NightwatchBrowser, name: string, content: NightwatchC .clickLaunchIcon('filePanel') .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('.newFile') - .waitForElementContainsText('*[data-id="treeViewLitreeViewItem/blank"]', '', 60000) - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', name) - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementContainsText('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]', '', 60000) + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', name) + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) .pause(2000) .waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000) .setEditorValue(content.content) diff --git a/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts b/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts index 0400dc6394..d262f5a665 100644 --- a/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts +++ b/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts @@ -22,9 +22,9 @@ module.exports = { .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('*[data-id="fileExplorerNewFilecreateNewFile"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItem/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', '5_New_contract.sol') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', '5_New_contract.sol') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItem5_New_contract.sol"]', 7000) }, @@ -49,9 +49,9 @@ module.exports = { .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('[data-id="fileExplorerNewFilecreateNewFolder"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItem/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', 'Browser_Tests') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', 'Browser_Tests') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItemBrowser_Tests"]') }, diff --git a/apps/remix-ide-e2e/src/tests/gist.spec.ts b/apps/remix-ide-e2e/src/tests/gist.spec.ts index dbc2f3a096..1be57c8350 100644 --- a/apps/remix-ide-e2e/src/tests/gist.spec.ts +++ b/apps/remix-ide-e2e/src/tests/gist.spec.ts @@ -29,9 +29,9 @@ module.exports = { .waitForElementVisible('*[data-id="fileExplorerNewFilecreateNewFolder"]') .click('[data-id="fileExplorerNewFilecreateNewFolder"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItem/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', 'Browser_Tests') - .sendKeys('*[data-id="treeViewLitreeViewItem/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', 'Browser_Tests') + .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItemBrowser_Tests"]') .addFile('File.sol', { content: '' }) .click('*[data-id="fileExplorerNewFilepublishToGist"]') From 383ac9311f0fedcb93191f9ba77208dddf7a350d Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 26 Apr 2021 13:58:20 +0100 Subject: [PATCH 141/199] Expand externally loaded files --- libs/remix-ui/file-explorer/src/lib/file-explorer.tsx | 8 ++++++++ .../remix-ui/file-explorer/src/lib/reducers/fileSystem.ts | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index a83b81d044..83c8f422cc 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -132,6 +132,14 @@ export const FileExplorer = (props: FileExplorerProps) => { } }, [fileSystem.notification.message]) + useEffect(() => { + if (fileSystem.files.expandPath.length > 0) { + setState(prevState => { + return { ...prevState, expandPath: [...new Set([...prevState.expandPath, ...fileSystem.files.expandPath])] } + }) + } + }, [fileSystem.files.expandPath]) + useEffect(() => { if (state.focusEdit.element) { setTimeout(() => { diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index df4475108e..2e033a17bd 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -8,6 +8,7 @@ interface Action { export const fileSystemInitialState = { files: { files: [], + expandPath: [], workspaceName: null, blankPath: null, isRequesting: false, @@ -175,6 +176,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action files: { ...state.files, files: fileAdded(state.files.workspaceName, action.payload.path, state.files.files, action.payload.files), + expandPath: [...new Set([...state.files.expandPath, action.payload.path])], isRequesting: false, isSuccessful: true, error: null @@ -187,6 +189,7 @@ export const fileSystemReducer = (state = fileSystemInitialState, action: Action files: { ...state.files, files: folderAdded(state.files.workspaceName, action.payload.path, state.files.files, action.payload.files), + expandPath: [...new Set([...state.files.expandPath, action.payload.path])], isRequesting: false, isSuccessful: true, error: null @@ -271,12 +274,12 @@ const removePath = (root, path: string, pathName, files) => { }, []) const prevFiles = _.get(files, _path) - prevFiles.child[pathName] && delete prevFiles.child[pathName] + prevFiles && prevFiles.child && prevFiles.child[pathName] && delete prevFiles.child[pathName] files = _.set(files, _path, { isDirectory: true, path, name: extractNameFromKey(path), - child: prevFiles.child + child: prevFiles ? prevFiles.child : {} }) return files From 8dfeb658a95ad916050db4b9f039317069d7d2dd Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 27 Apr 2021 11:30:29 +0100 Subject: [PATCH 142/199] Fix failing tests --- apps/remix-ide-e2e/src/commands/addFile.ts | 6 +++--- apps/remix-ide-e2e/src/tests/fileExplorer.test.ts | 12 ++++++------ apps/remix-ide-e2e/src/tests/gist.spec.ts | 6 +++--- .../remix-ui/file-explorer/src/lib/file-explorer.tsx | 4 ++-- .../file-explorer/src/lib/reducers/fileSystem.ts | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/addFile.ts b/apps/remix-ide-e2e/src/commands/addFile.ts index bc2f40e114..aa1f8d7f6e 100644 --- a/apps/remix-ide-e2e/src/commands/addFile.ts +++ b/apps/remix-ide-e2e/src/commands/addFile.ts @@ -18,9 +18,9 @@ function addFile (browser: NightwatchBrowser, name: string, content: NightwatchC .clickLaunchIcon('filePanel') .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('.newFile') - .waitForElementContainsText('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]', '', 60000) - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', name) - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementContainsText('*[data-id$="/blank"]', '', 60000) + .sendKeys('*[data-id$="/blank"] .remixui_items', name) + .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) .pause(2000) .waitForElementVisible(`li[data-id="treeViewLitreeViewItem${name}"]`, 60000) .setEditorValue(content.content) diff --git a/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts b/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts index d262f5a665..4eb8d156b6 100644 --- a/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts +++ b/apps/remix-ide-e2e/src/tests/fileExplorer.test.ts @@ -22,9 +22,9 @@ module.exports = { .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('*[data-id="fileExplorerNewFilecreateNewFile"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', '5_New_contract.sol') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id$="/blank"]') + .sendKeys('*[data-id$="/blank"] .remixui_items', '5_New_contract.sol') + .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItem5_New_contract.sol"]', 7000) }, @@ -49,9 +49,9 @@ module.exports = { .click('li[data-id="treeViewLitreeViewItemREADME.txt"]') // focus on root directory .click('[data-id="fileExplorerNewFilecreateNewFolder"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', 'Browser_Tests') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id$="/blank"]') + .sendKeys('*[data-id$="/blank"] .remixui_items', 'Browser_Tests') + .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItemBrowser_Tests"]') }, diff --git a/apps/remix-ide-e2e/src/tests/gist.spec.ts b/apps/remix-ide-e2e/src/tests/gist.spec.ts index 1be57c8350..ad98cb6f19 100644 --- a/apps/remix-ide-e2e/src/tests/gist.spec.ts +++ b/apps/remix-ide-e2e/src/tests/gist.spec.ts @@ -29,9 +29,9 @@ module.exports = { .waitForElementVisible('*[data-id="fileExplorerNewFilecreateNewFolder"]') .click('[data-id="fileExplorerNewFilecreateNewFolder"]') .pause(1000) - .waitForElementVisible('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"]') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', 'Browser_Tests') - .sendKeys('*[data-id="treeViewLitreeViewItemdefault_workspace/blank"] .remixui_items', browser.Keys.ENTER) + .waitForElementVisible('*[data-id$="/blank"]') + .sendKeys('*[data-id$="/blank"] .remixui_items', 'Browser_Tests') + .sendKeys('*[data-id$="/blank"] .remixui_items', browser.Keys.ENTER) .waitForElementVisible('*[data-id="treeViewLitreeViewItemBrowser_Tests"]') .addFile('File.sol', { content: '' }) .click('*[data-id="fileExplorerNewFilepublishToGist"]') diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 83c8f422cc..3cfda6c0af 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -110,7 +110,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (props.filesProvider) { init(props.filesProvider, props.name, props.plugin, props.registry)(dispatch) } - }, [props.filesProvider]) + }, [props.filesProvider, props.name]) useEffect(() => { const provider = fileSystem.provider.provider @@ -118,7 +118,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (provider) { fetchDirectory(provider, props.name)(dispatch) } - }, [fileSystem.provider.provider]) + }, [fileSystem.provider.provider, props.name]) useEffect(() => { if (fileSystem.notification.message) { diff --git a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts index 2e033a17bd..dc1628ebf9 100644 --- a/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/reducers/fileSystem.ts @@ -259,7 +259,7 @@ const resolveDirectory = (root, path: string, files, content) => { isDirectory: true, path, name: extractNameFromKey(path), - child: { ...content[pathArr[pathArr.length - 1]], ...prevFiles.child } + child: { ...content[pathArr[pathArr.length - 1]], ...(prevFiles ? prevFiles.child : {}) } }) return files From 3a1a03a85cfe441314487f84e2c867bb79e4ab00 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 27 Apr 2021 16:06:50 +0100 Subject: [PATCH 143/199] Fixed exists callback bug --- apps/remix-ide/src/app/files/fileManager.js | 5 +---- apps/remix-ide/src/app/files/fileProvider.js | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index cc73ba0942..d7473e1bc0 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -121,10 +121,7 @@ class FileManager extends Plugin { try { path = this.limitPluginScope(path) const provider = this.fileProviderOf(path) - const result = provider.exists(path, (err, result) => { - if (err) return false - return result - }) + const result = provider.exists(path, () => {}) return result } catch (e) { diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 999587c7e0..d0dc69862b 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -67,6 +67,7 @@ class FileProvider { // todo check the type (directory/file) as well #2386 // currently it is not possible to have a file and folder with same path const ret = this._exists(path) + if (cb) cb(null, ret) return ret } From bf80ca988a97cbcdcbdd47220a0d55a03dc9014b Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 11:39:41 +0100 Subject: [PATCH 144/199] Changed remixd set and createDir implementation, changed fileProvider's exist implementation --- .../src/app/compiler/compiler-imports.js | 6 +- apps/remix-ide/src/app/editor/contextView.js | 5 +- apps/remix-ide/src/app/files/fileManager.js | 2 +- apps/remix-ide/src/app/files/fileProvider.js | 3 +- .../remix-ide/src/app/files/remixDProvider.js | 9 +-- apps/remix-ide/src/app/panels/file-panel.js | 2 +- .../remix-ide/src/app/tabs/testTab/testTab.js | 4 +- apps/remix-ide/src/app/ui/renderer.js | 5 +- apps/remix-ide/src/lib/helper.js | 14 ++-- .../file-explorer/src/lib/file-explorer.tsx | 6 +- libs/remixd/src/services/remixdClient.ts | 73 ++++++++----------- 11 files changed, 61 insertions(+), 68 deletions(-) diff --git a/apps/remix-ide/src/app/compiler/compiler-imports.js b/apps/remix-ide/src/app/compiler/compiler-imports.js index 89fa1aa988..0e72bb425d 100644 --- a/apps/remix-ide/src/app/compiler/compiler-imports.js +++ b/apps/remix-ide/src/app/compiler/compiler-imports.js @@ -121,9 +121,7 @@ module.exports = class CompilerImports extends Plugin { if (provider.type === 'localhost' && !provider.isConnected()) { return reject(new Error(`file provider ${provider.type} not available while trying to resolve ${url}`)) } - provider.exists(url, (error, exist) => { - if (error) return reject(error) - + provider.exists(url).then(exist => { /* if the path is absolute and the file does not exist, we can stop here Doesn't make sense to try to resolve "localhost/node_modules/localhost/node_modules/" and we'll end in an infinite loop. @@ -162,6 +160,8 @@ module.exports = class CompilerImports extends Plugin { if (error) return reject(error) resolve(content) }) + }).catch(error => { + return reject(error) }) } }) diff --git a/apps/remix-ide/src/app/editor/contextView.js b/apps/remix-ide/src/app/editor/contextView.js index dbf1bbf933..da01321762 100644 --- a/apps/remix-ide/src/app/editor/contextView.js +++ b/apps/remix-ide/src/app/editor/contextView.js @@ -109,10 +109,11 @@ class ContextView { if (filename !== this._deps.config.get('currentFile')) { const provider = this._deps.fileManager.fileProviderOf(filename) if (provider) { - provider.exists(filename, (error, exist) => { - if (error) return console.log(error) + provider.exists(filename).then(exist => { this._deps.fileManager.open(filename) jumpToLine(lineColumn) + }).catch(error => { + if (error) return console.log(error) }) } } else { diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index d7473e1bc0..fd74b1722d 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -121,7 +121,7 @@ class FileManager extends Plugin { try { path = this.limitPluginScope(path) const provider = this.fileProviderOf(path) - const result = provider.exists(path, () => {}) + const result = provider.exists(path) return result } catch (e) { diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index d0dc69862b..521dcec453 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -63,11 +63,10 @@ class FileProvider { }) } - exists (path, cb) { + async exists (path) { // todo check the type (directory/file) as well #2386 // currently it is not possible to have a file and folder with same path const ret = this._exists(path) - if (cb) cb(null, ret) return ret } diff --git a/apps/remix-ide/src/app/files/remixDProvider.js b/apps/remix-ide/src/app/files/remixDProvider.js index b20a097ccd..60337c11e4 100644 --- a/apps/remix-ide/src/app/files/remixDProvider.js +++ b/apps/remix-ide/src/app/files/remixDProvider.js @@ -74,16 +74,15 @@ module.exports = class RemixDProvider extends FileProvider { }) } - exists (path, cb) { - if (!this._isReady) return cb && cb('provider not ready') + exists (path) { + if (!this._isReady) throw new Error('provider not ready') const unprefixedpath = this.removePrefix(path) return this._appManager.call('remixd', 'exists', { path: unprefixedpath }) .then((result) => { - if (cb) return cb(null, result) return result - }).catch((error) => { - if (cb) return cb(error) + }) + .catch((error) => { throw new Error(error) }) } diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 4629b6d5c5..893ec084f9 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -229,7 +229,7 @@ module.exports = class Filepanel extends ViewPlugin { /** these are called by the react component, action is already finished whent it's called */ async setWorkspace (workspace) { - this._deps.fileManager.removeTabsOf(this._deps.fileProviders.workspace) + this._deps.fileManager.closeAllFiles() if (workspace.isLocalhost) { this.call('manager', 'activatePlugin', 'remixd') } else if (await this.call('manager', 'isActive', 'remixd')) { diff --git a/apps/remix-ide/src/app/tabs/testTab/testTab.js b/apps/remix-ide/src/app/tabs/testTab/testTab.js index 1cfdff91be..1f915d9ee4 100644 --- a/apps/remix-ide/src/app/tabs/testTab/testTab.js +++ b/apps/remix-ide/src/app/tabs/testTab/testTab.js @@ -18,7 +18,9 @@ class TestTabLogic { // Checking to ignore the value which contains only whitespaces if (!path || !(/\S/.test(path))) return const fileProvider = this.fileManager.fileProviderOf(path.split('/')[0]) - fileProvider.exists(path, (e, res) => { if (!res) fileProvider.createDir(path) }) + fileProvider.exists(path).then(res => { + if (!res) fileProvider.createDir(path) + }) } pathExists (path) { diff --git a/apps/remix-ide/src/app/ui/renderer.js b/apps/remix-ide/src/app/ui/renderer.js index 35cf8395ec..97107c19d2 100644 --- a/apps/remix-ide/src/app/ui/renderer.js +++ b/apps/remix-ide/src/app/ui/renderer.js @@ -39,10 +39,11 @@ Renderer.prototype._errorClick = function (errFile, errLine, errCol) { // TODO: refactor with this._components.contextView.jumpTo var provider = self._deps.fileManager.fileProviderOf(errFile) if (provider) { - provider.exists(errFile, (error, exist) => { - if (error) return console.log(error) + provider.exists(errFile).then(exist => { self._deps.fileManager.open(errFile) editor.gotoLine(errLine, errCol) + }).catch(error => { + if (error) return console.log(error) }) } } else { diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index 2757fc84da..cb78e55356 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -36,14 +36,12 @@ module.exports = { async.whilst( () => { return exist }, (callback) => { - fileProvider.exists(name + counter + prefix + '.' + ext, (error, currentExist) => { - if (error) { - callback(error) - } else { - exist = currentExist - if (exist) counter = (counter | 0) + 1 - callback() - } + fileProvider.exists(name + counter + prefix + '.' + ext).then(currentExist => { + exist = currentExist + if (exist) counter = (counter | 0) + 1 + callback() + }).catch(error => { + if (error) console.log(error) }) }, (error) => { cb(error, name + counter + prefix + '.' + ext) } diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 3cfda6c0af..f4b0020ca5 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -368,8 +368,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const name = `${parentFolder}/${file.name}` - filesProvider.exists(name, (error, exist) => { - if (error) console.log(error) + filesProvider.exists(name).then(exist => { if (!exist) { loadFile(name) } else { @@ -383,6 +382,8 @@ export const FileExplorer = (props: FileExplorerProps) => { fn: () => {} }) } + }).catch(error => { + if (error) console.log(error) }) }) } @@ -730,6 +731,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const renderFiles = (file: File, index: number) => { + if (!file || !file.path || typeof file === 'string' || typeof file === 'number' || typeof file === 'boolean') return const labelClass = state.focusEdit.element === file.path ? 'bg-light' : state.focusElement.findIndex(item => item.key === file.path) !== -1 ? 'bg-secondary' : state.mouseOverElement === file.path diff --git a/libs/remixd/src/services/remixdClient.ts b/libs/remixd/src/services/remixdClient.ts index 09f78b7dec..31588628ea 100644 --- a/libs/remixd/src/services/remixdClient.ts +++ b/libs/remixd/src/services/remixdClient.ts @@ -85,11 +85,10 @@ export class RemixdClient extends PluginClient { } } - set (args: SharedFolderArgs): Promise { + set (args: SharedFolderArgs) { try { return new Promise((resolve, reject) => { if (this.readOnly) return reject(new Error('Cannot write file: read-only mode selected')) - const isFolder = args.path.endsWith('/') const path = utils.absolutePath(args.path, this.currentSharedFolder) const exists = fs.existsSync(path) @@ -99,31 +98,25 @@ export class RemixdClient extends PluginClient { return reject(new Error('trying to write "undefined" ! stopping.')) } this.trackDownStreamUpdate[path] = path - if (isFolder) { - fs.mkdirp(path).then(() => { - let splitPath = args.path.split('/') - - splitPath = splitPath.filter(dir => dir) - const dir = '/' + splitPath.join('/') - - this.emit('folderAdded', dir) - resolve() - }).catch((e: Error) => reject(e)) + if (!exists && args.path.indexOf('/') !== -1) { + // the last element is the filename and we should remove it + this.createDir({ path: args.path.substr(0, args.path.lastIndexOf('/')) }) + } + try { + fs.writeFile(path, args.content, 'utf8', (error: Error) => { + if (error) { + console.log(error) + return reject(error) + } + resolve(true) + }) + } catch (e) { + return reject(e) + } + if (!exists) { + this.emit('fileAdded', args.path) } else { - fs.ensureFile(path).then(() => { - fs.writeFile(path, args.content, 'utf8', (error: Error) => { - if (error) { - console.log(error) - return reject(error) - } - resolve() - }) - }).catch((e: Error) => reject(e)) - if (!exists) { - this.emit('fileAdded', args.path) - } else { - this.emit('fileChanged', args.path) - } + this.emit('fileChanged', args.path) } }) } catch (error) { @@ -131,24 +124,22 @@ export class RemixdClient extends PluginClient { } } - createDir (args: SharedFolderArgs): Promise { + createDir (args: SharedFolderArgs) { try { return new Promise((resolve, reject) => { if (this.readOnly) return reject(new Error('Cannot create folder: read-only mode selected')) - const path = utils.absolutePath(args.path, this.currentSharedFolder) - const exists = fs.existsSync(path) - - if (exists && !isRealPath(path)) return reject(new Error('')) - this.trackDownStreamUpdate[path] = path - fs.mkdirp(path).then(() => { - let splitPath = args.path.split('/') - - splitPath = splitPath.filter(dir => dir) - const dir = '/' + splitPath.join('/') - - this.emit('folderAdded', dir) - resolve() - }).catch((e: Error) => reject(e)) + const paths = args.path.split('/').filter(value => value) + if (paths.length && paths[0] === '') paths.shift() + let currentCheck = '' + paths.forEach((value) => { + currentCheck = currentCheck ? currentCheck + '/' + value : value + const path = utils.absolutePath(currentCheck, this.currentSharedFolder) + if (!fs.existsSync(path)) { + fs.mkdirp(path) + this.emit('folderAdded', currentCheck) + } + }) + resolve(true) }) } catch (error) { throw new Error(error) From 9b9fa8c4208a4dc8718d7f94d136588fef4d998e Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 12:31:39 +0100 Subject: [PATCH 145/199] Add tests for workspace alert modal --- apps/remix-ide-e2e/src/helpers/init.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/remix-ide-e2e/src/helpers/init.ts b/apps/remix-ide-e2e/src/helpers/init.ts index 484645b391..28d7c5e1fe 100644 --- a/apps/remix-ide-e2e/src/helpers/init.ts +++ b/apps/remix-ide-e2e/src/helpers/init.ts @@ -7,6 +7,8 @@ export default function (browser: NightwatchBrowser, callback: VoidFunction, url .url(url || 'http://127.0.0.1:8080') .pause(5000) .switchBrowserTab(0) + .waitForElementVisible('*[data-id="modalDialogModalBody"]', 60000) + .modalFooterOKClick() .fullscreenWindow(() => { if (preloadPlugins) { initModules(browser, () => { From cbd023306f9647cdbcaee8c3d667d21d9c9f5970 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 14:16:52 +0100 Subject: [PATCH 146/199] Fixed library deployment test --- .../remix-ide-e2e/src/commands/getAddressAtPosition.ts | 2 +- .../remix-ide-e2e/src/commands/testConstantFunction.ts | 2 +- apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts b/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts index a1ea787335..4db10565fa 100644 --- a/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts +++ b/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts @@ -15,7 +15,7 @@ class GetAddressAtPosition extends EventEmitter { } function getAddressAtPosition (browser: NightwatchBrowser, index: number, callback: (pos: string) => void) { - browser.waitForElementPresent('*[data-shared="universalDappUiInstance"]') + browser.waitForElementPresent('*[data-shared="universalDappUiInstance"]', 60000) .execute(function (index) { const deployedContracts = document.querySelectorAll('*[data-shared="universalDappUiInstance"]') const id = deployedContracts[index].getAttribute('id') diff --git a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts index db0d3b0946..064391220a 100644 --- a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts +++ b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts @@ -27,7 +27,7 @@ function testConstantFunction (browser: NightwatchBrowser, address: string, fnFu }) .click('.instance button[title="' + fnFullName + '"]') .pause(1000) - .waitForElementPresent('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') + .waitForElementPresent('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]', 60000) .scrollInto('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') .assert.containsText('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]', expectedOutput).perform(() => { cb() diff --git a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts index 0a759aa332..555fdcc372 100644 --- a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts +++ b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts @@ -80,7 +80,7 @@ function checkDeployShouldFail (browser: NightwatchBrowser, callback: VoidFuncti .getText('div[class^="terminal"]', (value) => { console.log('value: ', value) }) - .assert.containsText('div[class^="terminal"]', '
is not a valid address') + .waitForElementContainsText('div[class^="terminal"]', '
is not a valid address', 60000) .perform(() => { callback() }) } @@ -100,14 +100,14 @@ function checkDeployShouldSucceed (browser: NightwatchBrowser, address: string, .clickLaunchIcon('udapp') .selectContract('test') // deploy lib .createContract('') - .getAddressAtPosition(1, (address) => { + .getAddressAtPosition(0, (address) => { addressRef = address }) - .waitForElementPresent('.instance:nth-of-type(3)') - .click('.instance:nth-of-type(3) > div > button') + .waitForElementPresent('.instance') + .click('.instance > div > button') .perform(() => { browser - .testConstantFunction(addressRef, 'get - call', null, '0:\nuint256: 45') + .testConstantFunction(addressRef, 'getInt - call', null, '0:\nuint256: 45') .perform(() => { callback() }) }) } From d96f11cdbd139847a407d3537256be58760ad30c Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 14:30:08 +0100 Subject: [PATCH 147/199] Fixed failing tests --- apps/remix-ide-e2e/src/tests/solidityImport.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts b/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts index 8be5c1899c..7c8e66f309 100644 --- a/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts @@ -26,7 +26,7 @@ module.exports = { 'Test Failed Import': function (browser: NightwatchBrowser) { browser.addFile('Untitled3.sol', sources[2]['Untitled3.sol']) .clickLaunchIcon('solidity') - .assert.containsText('#compileTabView .error pre', 'not found Untitled11.sol') + .assert.containsText('#compileTabView .error pre', 'not found default_workspace/Untitled11.sol') }, 'Test Github Import - from master branch': function (browser: NightwatchBrowser) { From 7ef4483a3c126fc18eb9c1e1f4c6aa81a284e4e8 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 14:48:21 +0100 Subject: [PATCH 148/199] Conditionally close alert --- apps/remix-ide-e2e/src/helpers/init.ts | 11 ++++++++--- apps/remix-ide-e2e/src/tests/url.spec.ts | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/helpers/init.ts b/apps/remix-ide-e2e/src/helpers/init.ts index 28d7c5e1fe..8782c7a44b 100644 --- a/apps/remix-ide-e2e/src/helpers/init.ts +++ b/apps/remix-ide-e2e/src/helpers/init.ts @@ -2,13 +2,18 @@ import { NightwatchBrowser } from 'nightwatch' require('dotenv').config() -export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true): void { +export default function (browser: NightwatchBrowser, callback: VoidFunction, url?: string, preloadPlugins = true, closeWorkspaceAlert = true): void { browser .url(url || 'http://127.0.0.1:8080') .pause(5000) .switchBrowserTab(0) - .waitForElementVisible('*[data-id="modalDialogModalBody"]', 60000) - .modalFooterOKClick() + .perform((done) => { + if (closeWorkspaceAlert) { + browser.waitForElementVisible('*[data-id="modalDialogModalBody"]', 60000) + .modalFooterOKClick() + } + done() + }) .fullscreenWindow(() => { if (preloadPlugins) { initModules(browser, () => { diff --git a/apps/remix-ide-e2e/src/tests/url.spec.ts b/apps/remix-ide-e2e/src/tests/url.spec.ts index ec273cab4c..40a52bd073 100644 --- a/apps/remix-ide-e2e/src/tests/url.spec.ts +++ b/apps/remix-ide-e2e/src/tests/url.spec.ts @@ -10,7 +10,7 @@ const sources = [ module.exports = { before: function (browser: NightwatchBrowser, done: VoidFunction) { - init(browser, done, 'http://127.0.0.1:8080/#optimize=true&runs=300&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0') + init(browser, done, 'http://127.0.0.1:8080/#optimize=true&runs=300&evmVersion=istanbul&version=soljson-v0.7.4+commit.3f05b770.js&code=cHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuNy4wOwoKaW1wb3J0ICJodHRwczovL2dpdGh1Yi5jb20vT3BlblplcHBlbGluL29wZW56ZXBwZWxpbi1jb250cmFjdHMvYmxvYi9tYXN0ZXIvY29udHJhY3RzL2FjY2Vzcy9Pd25hYmxlLnNvbCI7Cgpjb250cmFjdCBHZXRQYWlkIGlzIE93bmFibGUgewogIGZ1bmN0aW9uIHdpdGhkcmF3KCkgZXh0ZXJuYWwgb25seU93bmVyIHsKICB9Cn0', true, false) }, '@sources': function () { From 3dfd5ef5f921a480d5b6b1ddceb140cdd7d29ca1 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 16:35:08 +0100 Subject: [PATCH 149/199] Rename helper function to createNonClashingNameAsync --- apps/remix-ide/src/lib/helper.js | 2 +- libs/remix-ui/file-explorer/src/lib/file-explorer.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/lib/helper.js b/apps/remix-ide/src/lib/helper.js index cb78e55356..2d8bb19cfb 100644 --- a/apps/remix-ide/src/lib/helper.js +++ b/apps/remix-ide/src/lib/helper.js @@ -50,7 +50,7 @@ module.exports = { createNonClashingName (name, fileProvider, cb) { this.createNonClashingNameWithPrefix(name, fileProvider, '', cb) }, - async checkNonClashingNameAsync (name, fileManager, prefix = '') { + async createNonClashingNameAsync (name, fileManager, prefix = '') { if (!name) name = 'Undefined' let counter = '' let ext = 'sol' diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index f4b0020ca5..a2566c5848 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -234,7 +234,7 @@ export const FileExplorer = (props: FileExplorerProps) => { const fileManager = state.fileManager try { - const newName = await helper.checkNonClashingNameAsync(newFilePath, fileManager) + const newName = await helper.createNonClashingNameAsync(newFilePath, fileManager) const createFile = await fileManager.writeFile(newName, '') if (!createFile) { From 9272951f67d80df132d31225551d9cd0eee8e588 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Thu, 29 Apr 2021 19:58:28 +0100 Subject: [PATCH 150/199] Revert "Fixed library deployment test" This reverts commit b2beb9467ec43a74da945c793230b61228709019. --- .../remix-ide-e2e/src/commands/getAddressAtPosition.ts | 2 +- .../remix-ide-e2e/src/commands/testConstantFunction.ts | 2 +- apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts b/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts index 4db10565fa..a1ea787335 100644 --- a/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts +++ b/apps/remix-ide-e2e/src/commands/getAddressAtPosition.ts @@ -15,7 +15,7 @@ class GetAddressAtPosition extends EventEmitter { } function getAddressAtPosition (browser: NightwatchBrowser, index: number, callback: (pos: string) => void) { - browser.waitForElementPresent('*[data-shared="universalDappUiInstance"]', 60000) + browser.waitForElementPresent('*[data-shared="universalDappUiInstance"]') .execute(function (index) { const deployedContracts = document.querySelectorAll('*[data-shared="universalDappUiInstance"]') const id = deployedContracts[index].getAttribute('id') diff --git a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts index 064391220a..db0d3b0946 100644 --- a/apps/remix-ide-e2e/src/commands/testConstantFunction.ts +++ b/apps/remix-ide-e2e/src/commands/testConstantFunction.ts @@ -27,7 +27,7 @@ function testConstantFunction (browser: NightwatchBrowser, address: string, fnFu }) .click('.instance button[title="' + fnFullName + '"]') .pause(1000) - .waitForElementPresent('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]', 60000) + .waitForElementPresent('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') .scrollInto('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]') .assert.containsText('#instance' + address + ' div[class^="contractActionsContainer"] div[class^="value"]', expectedOutput).perform(() => { cb() diff --git a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts index 555fdcc372..0a759aa332 100644 --- a/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts +++ b/apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts @@ -80,7 +80,7 @@ function checkDeployShouldFail (browser: NightwatchBrowser, callback: VoidFuncti .getText('div[class^="terminal"]', (value) => { console.log('value: ', value) }) - .waitForElementContainsText('div[class^="terminal"]', '
is not a valid address', 60000) + .assert.containsText('div[class^="terminal"]', '
is not a valid address') .perform(() => { callback() }) } @@ -100,14 +100,14 @@ function checkDeployShouldSucceed (browser: NightwatchBrowser, address: string, .clickLaunchIcon('udapp') .selectContract('test') // deploy lib .createContract('') - .getAddressAtPosition(0, (address) => { + .getAddressAtPosition(1, (address) => { addressRef = address }) - .waitForElementPresent('.instance') - .click('.instance > div > button') + .waitForElementPresent('.instance:nth-of-type(3)') + .click('.instance:nth-of-type(3) > div > button') .perform(() => { browser - .testConstantFunction(addressRef, 'getInt - call', null, '0:\nuint256: 45') + .testConstantFunction(addressRef, 'get - call', null, '0:\nuint256: 45') .perform(() => { callback() }) }) } From 0cfab431e5dc240df317aa6c592df4ed9bb0b844 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Fri, 30 Apr 2021 18:26:39 +0100 Subject: [PATCH 151/199] Fixed file linking for libraries --- libs/remix-ui/file-explorer/src/lib/file-explorer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index a2566c5848..fc8c89450a 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -240,7 +240,9 @@ export const FileExplorer = (props: FileExplorerProps) => { if (!createFile) { return toast('Failed to create file ' + newName) } else { - await fileManager.open(newName) + const path = newName.indexOf(props.name + '/') === 0 ? newName.replace(props.name + '/', '') : newName + + await fileManager.open(path) setState(prevState => { return { ...prevState, focusElement: [{ key: newName, type: 'file' }] } }) @@ -557,6 +559,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } const handleClickFile = (path: string) => { + path = path.indexOf(props.name + '/') === 0 ? path.replace(props.name + '/', '') : path state.fileManager.open(path) setState(prevState => { return { ...prevState, focusElement: [{ key: path, type: 'file' }] } From c991d4ab958fb5ef9264daf0775930a4940774a1 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Fri, 30 Apr 2021 20:12:07 +0100 Subject: [PATCH 152/199] Fixed failing tests --- apps/remix-ide/src/app/panels/file-panel.js | 12 +++++++----- .../file-explorer/src/lib/actions/fileSystem.ts | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 893ec084f9..5628425b34 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -209,11 +209,13 @@ module.exports = class Filepanel extends ViewPlugin { workspaceProvider.setWorkspace(workspaceName) await this.request.setWorkspace(workspaceName) // tells the react component to switch to that workspace for (const file in examples) { - try { - await workspaceProvider.set(examples[file].name, examples[file].content) - } catch (error) { - console.error(error) - } + setTimeout(async () => { // space creation of files to give react ui time to update. + try { + await workspaceProvider.set(examples[file].name, examples[file].content) + } catch (error) { + console.error(error) + } + }, 200) } } } diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index eb0303e45d..c9b00bb099 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -182,7 +182,7 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { - const path = extractParentFromKey(filePath) || workspaceName + const path = extractParentFromKey(filePath) ? extractParentFromKey(filePath) === '/.workspaces' ? workspaceName : extractParentFromKey(filePath) : workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) @@ -191,7 +191,7 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp } }) provider.event.register('folderAdded', async (folderPath) => { - const path = extractParentFromKey(folderPath) || workspaceName + const path = extractParentFromKey(folderPath) ? extractParentFromKey(folderPath) === '/.workspaces' ? workspaceName : extractParentFromKey(folderPath) : workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) From e6a36a3fe1c51513569a8b4a0e1e4dfd6bcd9fad Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 11 May 2021 13:11:44 +0100 Subject: [PATCH 153/199] Wait for workspace creation before fetching --- apps/remix-ide/src/app/files/file-explorer.js | 702 ------------------ apps/remix-ide/src/app/panels/file-panel.js | 20 +- .../src/lib/actions/fileSystem.ts | 6 +- package-lock.json | 600 +++++++-------- 4 files changed, 316 insertions(+), 1012 deletions(-) delete mode 100644 apps/remix-ide/src/app/files/file-explorer.js diff --git a/apps/remix-ide/src/app/files/file-explorer.js b/apps/remix-ide/src/app/files/file-explorer.js deleted file mode 100644 index 9f5f3e3f69..0000000000 --- a/apps/remix-ide/src/app/files/file-explorer.js +++ /dev/null @@ -1,702 +0,0 @@ -/* global FileReader */ -/* global fetch */ -const async = require('async') -const Gists = require('gists') -const modalDialogCustom = require('../ui/modal-dialog-custom') -const tooltip = require('../ui/tooltip') -const QueryParams = require('../../lib/query-params') -const helper = require('../../lib/helper') -const yo = require('yo-yo') -const Treeview = require('../ui/TreeView') -const modalDialog = require('../ui/modaldialog') -const EventManager = require('../../lib/events') -const contextMenu = require('../ui/contextMenu') -const css = require('./styles/file-explorer-styles') -const globalRegistry = require('../../global/registry') -const queryParams = new QueryParams() -let MENU_HANDLE - -function fileExplorer (localRegistry, files, menuItems, plugin) { - var self = this - this.events = new EventManager() - // file provider backend - this.files = files - // element currently focused on - this.focusElement = null - // path currently focused on - this.focusPath = null - const allItems = - [ - { - action: 'createNewFile', - title: 'Create New File', - icon: 'fas fa-plus-circle' - }, - { - action: 'publishToGist', - title: 'Publish all [browser] explorer files to a github gist', - icon: 'fab fa-github' - }, - { - action: 'uploadFile', - title: 'Add Local file to the Browser Storage Explorer', - icon: 'far fa-folder-open' - }, - { - action: 'updateGist', - title: 'Update the current [gist] explorer', - icon: 'fab fa-github' - } - ] - // menu items - this.menuItems = allItems.filter( - (item) => { - if (menuItems) return menuItems.find((name) => { return name === item.action }) - } - ) - - self._components = {} - self._components.registry = localRegistry || globalRegistry - self._deps = { - config: self._components.registry.get('config').api, - editor: self._components.registry.get('editor').api, - fileManager: self._components.registry.get('filemanager').api - } - - self.events.register('focus', function (path) { - self._deps.fileManager.open(path) - }) - - self._components.registry.put({ api: self, name: `fileexplorer/${self.files.type}` }) - - // warn if file changed outside of Remix - function remixdDialog () { - return yo`
This file has been changed outside of Remix IDE.
` - } - - this.files.event.register('fileExternallyChanged', (path, file) => { - if (self._deps.config.get('currentFile') === path && self._deps.editor.currentContent() && self._deps.editor.currentContent() !== file.content) { - if (this.files.isReadOnly(path)) return self._deps.editor.setText(file.content) - - modalDialog(path + ' changed', remixdDialog(), - { - label: 'Replace by the new content', - fn: () => { - self._deps.editor.setText(file.content) - } - }, - { - label: 'Keep the content displayed in Remix', - fn: () => {} - } - ) - } - }) - - // register to event of the file provider - files.event.register('fileRemoved', fileRemoved) - files.event.register('fileRenamed', fileRenamed) - files.event.register('fileRenamedError', fileRenamedError) - files.event.register('fileAdded', fileAdded) - files.event.register('folderAdded', folderAdded) - - function fileRenamedError (error) { - modalDialogCustom.alert(error) - } - - function fileAdded (filepath) { - self.ensureRoot(() => { - const folderpath = filepath.split('/').slice(0, -1).join('/') - const currentTree = self.treeView.nodeAt(folderpath) - if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) - if (currentTree) { - self.files.resolveDirectory(folderpath, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - fileTree = normalize(folderpath, fileTree) - self.treeView.updateNodeFromJSON(folderpath, fileTree, true) - self.focusElement = self.treeView.labelAt(self.focusPath) - // TODO: here we update the selected file (it applicable) - // cause we are refreshing the interface of the whole directory when there's a new file. - if (self.focusElement && !self.focusElement.classList.contains('bg-secondary')) { - self.focusElement.classList.add('bg-secondary') - } - }) - } - }) - } - - function extractNameFromKey (key) { - const keyPath = key.split('/') - - return keyPath[keyPath.length - 1] - } - - function folderAdded (folderpath) { - self.ensureRoot(() => { - folderpath = folderpath.split('/').slice(0, -1).join('/') - self.files.resolveDirectory(folderpath, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - fileTree = normalize(folderpath, fileTree) - self.treeView.updateNodeFromJSON(folderpath, fileTree, true) - if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) - }) - }) - } - - function fileRemoved (filepath) { - const label = self.treeView.labelAt(filepath) - filepath = filepath.split('/').slice(0, -1).join('/') - - if (label && label.parentElement) { - label.parentElement.removeChild(label) - } - - self.updatePath(filepath) - } - - function fileRenamed (oldName, newName, isFolder) { - fileRemoved(oldName) - fileAdded(newName) - } - - // make interface and register to nodeClick, leafClick - self.treeView = new Treeview({ - extractData: function extractData (value, tree, key) { - var newValue = {} - // var isReadOnly = false - var isFile = false - Object.keys(value).filter(function keep (x) { - if (x === '/content') isFile = true - if (x[0] !== '/') return true - }).forEach(function (x) { newValue[x] = value[x] }) - return { - path: (tree || {}).path ? tree.path + '/' + key : key, - children: isFile ? undefined - : value instanceof Array ? value.map((item, index) => ({ - key: index, value: item - })) : value instanceof Object ? Object.keys(value).map(subkey => ({ - key: subkey, value: value[subkey] - })) : undefined - } - }, - formatSelf: function formatSelf (key, data, li) { - const isRoot = data.path === self.files.type - const isFolder = !!data.children - return yo` -
- - ${key.split('/').pop()} - - ${isRoot ? self.renderMenuItems() : ''} -
- ` - } - }) - - /** - * Extracts first two folders as a subpath from the path. - **/ - function extractExternalFolder (path) { - const firstSlIndex = path.indexOf('/', 1) - if (firstSlIndex === -1) return '' - const secondSlIndex = path.indexOf('/', firstSlIndex + 1) - if (secondSlIndex === -1) return '' - return path.substring(0, secondSlIndex) - } - - self.treeView.event.register('nodeRightClick', function (key, data, label, event) { - if (self.files.readonly) return - if (key === self.files.type) return - MENU_HANDLE && MENU_HANDLE.hide(null, true) - const actions = {} - const provider = self._deps.fileManager.fileProviderOf(key) - actions['Create File'] = () => self.createNewFile(key) - actions['Create Folder'] = () => self.createNewFolder(key) - // @todo(#2386) not fully implemented. Readd later when fixed - if (provider.isExternalFolder(key)) { - /* actions['Discard changes'] = () => { - modalDialogCustom.confirm( - 'Discard changes', - 'Are you sure you want to discard all your changes?', - () => { self.files.discardChanges(key) }, - () => {} - ) - } */ - } else { - const folderPath = extractExternalFolder(key) - actions.Rename = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') } - var name = label.querySelector('span[data-path="' + key + '"]') - if (name) editModeOn(name) - } - actions.Delete = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } - const currentFoldername = extractNameFromKey(key) - - modalDialogCustom.confirm('Confirm to delete folder', `Are you sure you want to delete ${currentFoldername} folder?`, - async () => { - const fileManager = self._deps.fileManager - const removeFolder = await fileManager.remove(key) - - if (!removeFolder) { - tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) - } - }, () => {}) - } - if (folderPath === 'browser/gists') { - actions['Push changes to gist'] = () => { - const id = key.substr(key.lastIndexOf('/') + 1, key.length - 1) - modalDialogCustom.confirm( - 'Push back to Gist', - 'Are you sure you want to push all your changes back to Gist?', - () => { self.toGist(id) }, - () => {} - ) - } - } - } - MENU_HANDLE = contextMenu(event, actions) - }) - - self.treeView.event.register('leafRightClick', function (key, data, label, event) { - if (key === self.files.type) return - MENU_HANDLE && MENU_HANDLE.hide(null, true) - const actions = {} - const provider = self._deps.fileManager.fileProviderOf(key) - if (!provider.isExternalFolder(key)) { - actions['Create Folder'] = () => self.createNewFolder(self._deps.fileManager.extractPathOf(key)) - actions.Rename = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot rename file. ' + self.files.type + ' is a read only explorer') } - var name = label.querySelector('span[data-path="' + key + '"]') - if (name) editModeOn(name) - } - actions.Delete = () => { - if (self.files.isReadOnly(key)) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') } - const currentFilename = extractNameFromKey(key) - - modalDialogCustom.confirm( - 'Delete file', `Are you sure you want to delete ${currentFilename} file?`, - async () => { - const fileManager = self._deps.fileManager - const removeFile = await fileManager.remove(key) - - if (!removeFile) { - tooltip(`Failed to remove file ${key}.`) - } - }, - () => {} - ) - } - if (key.endsWith('.js')) { - actions.Run = async () => { - provider.get(key, (error, content) => { - if (error) return console.log(error) - plugin.call('scriptRunner', 'execute', content) - }) - } - } - } - MENU_HANDLE = contextMenu(event, actions) - }) - - self.treeView.event.register('leafClick', function (key, data, label) { - self.events.trigger('focus', [key]) - }) - - self.treeView.event.register('nodeClick', function (path, childrenContainer) { - if (!childrenContainer) return - if (childrenContainer.style.display === 'none') return - self.updatePath(path) - }) - - // register to main app, trigger when the current file in the editor changed - self._deps.fileManager.events.on('currentFileChanged', (newFile) => { - const provider = self._deps.fileManager.fileProviderOf(newFile) - if (self.focusElement && self.focusPath !== newFile) { - self.focusElement.classList.remove('bg-secondary') - self.focusElement = null - self.focusPath = null - } - if (provider && (provider.type === files.type)) { - self.focusElement = self.treeView.labelAt(newFile) - if (self.focusElement) { - self.focusElement.classList.add('bg-secondary') - self.focusPath = newFile - } - } - }) - - self._deps.fileManager.events.on('noFileSelected', () => { - if (self.focusElement) { - self.focusElement.classList.remove('bg-secondary') - self.focusElement = null - self.focusPath = null - } - }) - - var textUnderEdit = null - - function selectElementContents (el) { - var range = document.createRange() - range.selectNodeContents(el) - var sel = window.getSelection() - sel.removeAllRanges() - sel.addRange(range) - } - - function editModeOn (label) { - textUnderEdit = label.innerText - label.setAttribute('contenteditable', true) - label.classList.add('bg-light') - label.focus() - selectElementContents(label) - } - - function editModeOff (event) { - const label = this - - const isFolder = label.className.indexOf('folder') !== -1 - function rename () { - var newPath = label.dataset.path - newPath = newPath.split('/') - newPath[newPath.length - 1] = label.innerText - newPath = newPath.join('/') - if (label.innerText === '') { - modalDialogCustom.alert('File name cannot be empty') - label.innerText = textUnderEdit - } else if (helper.checkSpecialChars(label.innerText)) { - modalDialogCustom.alert('Special characters are not allowed') - label.innerText = textUnderEdit - } else { - files.exists(newPath, (error, exist) => { - if (error) return modalDialogCustom.alert('Unexpected error while renaming: ' + error) - if (!exist) { - files.rename(label.dataset.path, newPath, isFolder) - } else { - modalDialogCustom.alert('File already exists.') - label.innerText = textUnderEdit - } - }) - } - } - - if (event.which === 13) event.preventDefault() - if ((event.type === 'blur' || event.which === 13) && label.getAttribute('contenteditable')) { - var save = textUnderEdit !== label.innerText - if (save) { - modalDialogCustom.confirm( - 'Confirm to rename a ' + (isFolder ? 'folder' : 'file'), - 'Are you sure you want to rename ' + textUnderEdit + '?', - () => { rename() }, - () => { label.innerText = textUnderEdit } - ) - } - label.removeAttribute('contenteditable') - label.classList.remove('bg-light') - } - } -} - -fileExplorer.prototype.updatePath = function (path) { - this.files.resolveDirectory(path, (error, fileTree) => { - if (error) console.error(error) - if (!fileTree) return - var newTree = normalize(path, fileTree) - this.treeView.updateNodeFromJSON(path, newTree, true) - }) -} - -fileExplorer.prototype.hide = function () { - if (this.container) this.container.style.display = 'none' -} - -fileExplorer.prototype.show = function () { - if (this.container) this.container.style.display = 'block' -} - -fileExplorer.prototype.init = function () { - this.container = yo`
` - return this.container -} - -fileExplorer.prototype.publishToGist = function () { - modalDialogCustom.confirm( - 'Create a public gist', - 'Are you sure you want to publish all your files in browser directory anonymously as a public gist on github.com? Note: this will not include directories.', - () => { this.toGist() } - ) -} - -fileExplorer.prototype.uploadFile = function (event) { - // 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 - // a file and then just use `files.add`. The file explorer will - // pick that up via the 'fileAdded' event from the files module. - - const self = this - - ;[...event.target.files].forEach((file) => { - const files = this.files - function loadFile () { - var fileReader = new FileReader() - fileReader.onload = async function (event) { - if (helper.checkSpecialChars(file.name)) { - modalDialogCustom.alert('Special characters are not allowed') - return - } - var success = await files.set(name, event.target.result) - if (!success) { - modalDialogCustom.alert('Failed to create file ' + name) - } else { - self.events.trigger('focus', [name]) - } - } - fileReader.readAsText(file) - } - var name = files.type + '/' + file.name - files.exists(name, (error, exist) => { - if (error) console.log(error) - if (!exist) { - loadFile() - } else { - modalDialogCustom.confirm('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() }) - } - }) - }) -} - -fileExplorer.prototype.toGist = function (id) { - const proccedResult = function (error, data) { - if (error) { - modalDialogCustom.alert('Failed to manage gist: ' + error) - console.log('Failed to manage gist: ' + error) - } else { - if (data.html_url) { - modalDialogCustom.confirm('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => { - window.open(data.html_url, '_blank') - }) - } else { - modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) - } - } - } - - /** - * This function is to get the original content of given gist - * @params id is the gist id to fetch - */ - async function getOriginalFiles (id) { - if (!id) { - return [] - } - - const url = `https://api.github.com/gists/${id}` - const res = await fetch(url) - const data = await res.json() - return data.files || [] - } - - // If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer. - const folder = id ? '/gists/' + id : '/' - this.packageFiles(this.files, folder, (error, packaged) => { - if (error) { - console.log(error) - modalDialogCustom.alert('Failed to create gist: ' + error.message) - } else { - // check for token - var tokenAccess = this._deps.config.get('settings/gist-access-token') - if (!tokenAccess) { - modalDialogCustom.alert( - 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.' - ) - } else { - const description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + - queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&runs=' + queryParams.get().runs + '&gist=' - const gists = new Gists({ token: tokenAccess }) - - if (id) { - const originalFileList = getOriginalFiles(id) - // Telling the GIST API to remove files - const updatedFileList = Object.keys(packaged) - const allItems = Object.keys(originalFileList) - .filter(fileName => updatedFileList.indexOf(fileName) === -1) - .reduce((acc, deleteFileName) => ({ - ...acc, - [deleteFileName]: null - }), originalFileList) - // adding new files - updatedFileList.forEach((file) => { - const _items = file.split('/') - const _fileName = _items[_items.length - 1] - allItems[_fileName] = packaged[file] - }) - - tooltip('Saving gist (' + id + ') ...') - gists.edit({ - description: description, - public: true, - files: allItems, - id: id - }, (error, result) => { - proccedResult(error, result) - if (!error) { - for (const key in allItems) { - if (allItems[key] === null) delete allItems[key] - } - } - }) - } else { - // id is not existing, need to create a new gist - tooltip('Creating a new gist ...') - gists.create({ - description: description, - public: true, - files: packaged - }, (error, result) => { - proccedResult(error, result) - }) - } - } - } - }) -} - -// return all the files, except the temporary/readonly ones.. -fileExplorer.prototype.packageFiles = function (filesProvider, directory, callback) { - const ret = {} - filesProvider.resolveDirectory(directory, (error, files) => { - if (error) callback(error) - else { - async.eachSeries(Object.keys(files), (path, cb) => { - if (filesProvider.isDirectory(path)) { - cb() - } else { - filesProvider.get(path, (error, content) => { - if (error) return cb(error) - if (/^\s+$/.test(content) || !content.length) { - content = '// this line is added to create a gist. Empty file is not allowed.' - } - ret[path] = { content } - cb() - }) - } - }, (error) => { - callback(error, ret) - }) - } - }) -} - -fileExplorer.prototype.createNewFile = function (parentFolder = '/') { - const self = this - modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { - if (!input) input = 'New file' - helper.createNonClashingName(parentFolder + '/' + input, self.files, async (error, newName) => { - if (error) return tooltip('Failed to create file ' + newName + ' ' + error) - const fileManager = self._deps.fileManager - const createFile = await fileManager.writeFile(newName, '') - - if (!createFile) { - tooltip('Failed to create file ' + newName) - } else { - await fileManager.open(newName) - if (newName.includes('_test.sol')) { - self.events.trigger('newTestFileCreated', [newName]) - } - } - }) - }, null, true) -} - -fileExplorer.prototype.createNewFolder = function (parentFolder) { - const self = this - modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { - if (!input) { - return tooltip('Failed to create folder. The name can not be empty') - } - - const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder - let newName = currentPath ? currentPath + '/' + input : self.files.type + '/' + input - - newName = newName + '/' - self.files.exists(newName, (error, exist) => { - if (error) return tooltip('Unexpected error while creating folder: ' + error) - if (!exist) { - self.files.set(newName, '') - } else { - tooltip('Folder already exists.', () => {}) - } - }) - }, null, true) -} - -fileExplorer.prototype.renderMenuItems = function () { - let items = '' - if (this.menuItems) { - items = this.menuItems.map(({ action, title, icon }) => { - if (action === 'uploadFile') { - return yo` - - ` - } else { - return yo` - { event.stopPropagation(); this[action]() }} - class="newFile ${icon} ${css.newFile}" - title=${title} - > - - ` - } - }) - } - return yo`${items}` -} - -fileExplorer.prototype.ensureRoot = function (cb) { - cb = cb || (() => {}) - var self = this - if (self.element) return cb() - const root = {} - root[this.files.type] = {} - var element = self.treeView.render(root, false) - element.classList.add(css.fileexplorer) - element.events = self.events - element.api = self.api - self.container.appendChild(element) - self.element = element - if (cb) cb() - self.treeView.expand(self.files.type) -} - -function normalize (path, filesList) { - var prefix = path.split('/')[0] - var newList = {} - Object.keys(filesList).forEach(key => { - newList[prefix + '/' + key] = filesList[key].isDirectory ? {} : { '/content': true } - }) - return newList -} - -module.exports = fileExplorer diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 5628425b34..ccc6ad7967 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -4,7 +4,7 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' import { Workspace } from '@remix-ui/workspace' // eslint-disable-line -import { bufferToHex, keccakFromString } from 'ethereumjs-util' +import * as ethutil from 'ethereumjs-util' import { checkSpecialChars, checkSlash } from '../../lib/helper' var EventManager = require('../../lib/events') var { RemixdHandle } = require('../files/remixd-handle.js') @@ -154,7 +154,7 @@ module.exports = class Filepanel extends ViewPlugin { try { await this.processCreateWorkspace('code-sample') this._deps.fileProviders.workspace.setWorkspace('code-sample') - var hash = bufferToHex(keccakFromString(params.code)) + var hash = ethutil.bufferToHex(ethutil.keccak(params.code)) const fileName = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol' const path = fileName await this._deps.fileProviders.workspace.set(path, atob(params.code)) @@ -166,12 +166,16 @@ module.exports = class Filepanel extends ViewPlugin { return } // insert example contracts if there are no files to show - this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { - if (error) console.error(error) - if (Object.keys(filesList).length === 0) { - await this.createWorkspace('default_workspace') - } - this.getWorkspaces() + return new Promise((resolve, reject) => { + this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { + if (error) console.error(error) + if (Object.keys(filesList).length === 0) { + await this.createWorkspace('default_workspace') + } + const workspaces = await this.getWorkspaces() + + resolve(workspaces) + }) }) } diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index c9b00bb099..09443366b5 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -182,7 +182,8 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { - const path = extractParentFromKey(filePath) ? extractParentFromKey(filePath) === '/.workspaces' ? workspaceName : extractParentFromKey(filePath) : workspaceName + if (extractParentFromKey(filePath) === '/.workspaces') return + const path = extractParentFromKey(filePath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) @@ -191,7 +192,8 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp } }) provider.event.register('folderAdded', async (folderPath) => { - const path = extractParentFromKey(folderPath) ? extractParentFromKey(folderPath) === '/.workspaces' ? workspaceName : extractParentFromKey(folderPath) : workspaceName + if (extractParentFromKey(folderPath) === '/.workspaces') return + const path = extractParentFromKey(folderPath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) diff --git a/package-lock.json b/package-lock.json index d74204bd8f..13ca34a1d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3634,7 +3634,7 @@ "@evocateur/libnpmaccess": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz", - "integrity": "sha512-KSCAHwNWro0CF2ukxufCitT9K5LjL/KuMmNzSu8wuwN2rjyKHD8+cmOsiybK+W5hdnwc5M1SmRlVCaMHQo+3rg==", + "integrity": "sha1-7Pf2zmsATp+UKwmNkiAL5KSxyEU=", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3647,13 +3647,13 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "integrity": "sha1-UlILiuW1aSFbNU78DKo/4eRaitw=", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3665,7 +3665,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -3673,7 +3673,7 @@ "@evocateur/libnpmpublish": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz", - "integrity": "sha512-MJrrk9ct1FeY9zRlyeoyMieBjGDG9ihyyD9/Ft6MMrTxql9NyoEx2hw9casTIP4CdqEVu+3nQ2nXxoJ8RCXyFg==", + "integrity": "sha1-Vd8J0tyhNq+6nIjHWconIZjbnxo=", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3690,13 +3690,13 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "integrity": "sha1-UlILiuW1aSFbNU78DKo/4eRaitw=", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3708,7 +3708,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -3716,7 +3716,7 @@ "@evocateur/npm-registry-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@evocateur/npm-registry-fetch/-/npm-registry-fetch-4.0.0.tgz", - "integrity": "sha512-k1WGfKRQyhJpIr+P17O5vLIo2ko1PFLKwoetatdduUSt/aQ4J2sJrJwwatdI5Z3SiYk/mRH9S3JpdmMFd/IK4g==", + "integrity": "sha1-jEw4dm2NMtMgD8sKg/BktXNl7WY=", "dev": true, "requires": { "JSONStream": "^1.3.4", @@ -3731,7 +3731,7 @@ "agentkeepalive": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "integrity": "sha1-oROSTdP6JKC8O3gQjEUMKr7gD2c=", "dev": true, "requires": { "humanize-ms": "^1.2.1" @@ -3740,13 +3740,13 @@ "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "integrity": "sha1-ObDhat2bYFvwqe89nar0hDtMrNI=", "dev": true }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "integrity": "sha1-TuenN6vZJniik9mzShr00NCMeHs=", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -3756,7 +3756,7 @@ "make-fetch-happen": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "integrity": "sha1-qoOHEE8mh+3KAchofuRQE9AtGb0=", "dev": true, "requires": { "agentkeepalive": "^3.4.1", @@ -3775,7 +3775,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3787,7 +3787,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -3795,7 +3795,7 @@ "@evocateur/pacote": { "version": "9.6.5", "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.5.tgz", - "integrity": "sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==", + "integrity": "sha1-M94yuiELbxfCDrq01JfvxnVfSuU=", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3832,7 +3832,7 @@ "agentkeepalive": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "integrity": "sha1-oROSTdP6JKC8O3gQjEUMKr7gD2c=", "dev": true, "requires": { "humanize-ms": "^1.2.1" @@ -3841,13 +3841,13 @@ "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "integrity": "sha1-ObDhat2bYFvwqe89nar0hDtMrNI=", "dev": true }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "integrity": "sha1-TuenN6vZJniik9mzShr00NCMeHs=", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -3857,7 +3857,7 @@ "make-fetch-happen": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", + "integrity": "sha1-qoOHEE8mh+3KAchofuRQE9AtGb0=", "dev": true, "requires": { "agentkeepalive": "^3.4.1", @@ -3876,7 +3876,7 @@ "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "integrity": "sha1-5xN2Ln0+Mv7YAxFc+T4EvKn8yaY=", "dev": true, "requires": { "safe-buffer": "^5.1.2", @@ -3886,7 +3886,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3898,7 +3898,7 @@ "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -3909,7 +3909,7 @@ "npm-pick-manifest": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", - "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", + "integrity": "sha1-9Nnl/UviFT5fTl+be+jcQZqZq7c=", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -3920,7 +3920,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -4604,7 +4604,7 @@ "@lerna/add": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.21.0.tgz", - "integrity": "sha512-vhUXXF6SpufBE1EkNEXwz1VLW03f177G9uMOFMQkp6OJ30/PWg4Ekifuz9/3YfgB2/GH8Tu4Lk3O51P2Hskg/A==", + "integrity": "sha1-JwB73nHMewopaas8LwrkFXi0V3s=", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", @@ -4622,7 +4622,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4634,7 +4634,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -4644,7 +4644,7 @@ "@lerna/bootstrap": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.21.0.tgz", - "integrity": "sha512-mtNHlXpmvJn6JTu0KcuTTPl2jLsDNud0QacV/h++qsaKbhAaJr/FElNZ5s7MwZFUM3XaDmvWzHKaszeBMHIbBw==", + "integrity": "sha1-vNG2Ub5bCXCyDY+uBMhkVIEjrtY=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -4675,7 +4675,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4687,7 +4687,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -4697,7 +4697,7 @@ "@lerna/changed": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.21.0.tgz", - "integrity": "sha512-hzqoyf8MSHVjZp0gfJ7G8jaz+++mgXYiNs9iViQGA8JlN/dnWLI5sWDptEH3/B30Izo+fdVz0S0s7ydVE3pWIw==", + "integrity": "sha1-EI4V9nm/4HevUA9YJIxjTxBE6gs=", "dev": true, "requires": { "@lerna/collect-updates": "3.20.0", @@ -4709,7 +4709,7 @@ "@lerna/check-working-tree": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz", - "integrity": "sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==", + "integrity": "sha1-tPiuYbtFI1Yd+5+PjYdN1Gu0S6o=", "dev": true, "requires": { "@lerna/collect-uncommitted": "3.16.5", @@ -4720,7 +4720,7 @@ "@lerna/child-process": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.16.5.tgz", - "integrity": "sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==", + "integrity": "sha1-OPo8GAZKpKwHVK2AEUd2p7NqabI=", "dev": true, "requires": { "chalk": "^2.3.1", @@ -4731,7 +4731,7 @@ "@lerna/clean": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.21.0.tgz", - "integrity": "sha512-b/L9l+MDgE/7oGbrav6rG8RTQvRiZLO1zTcG17zgJAAuhlsPxJExMlh2DFwJEVi2les70vMhHfST3Ue1IMMjpg==", + "integrity": "sha1-wLRrUwDMPa4s2jvsFLgDCC2jhW0=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -4747,7 +4747,7 @@ "@lerna/cli": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.18.5.tgz", - "integrity": "sha512-erkbxkj9jfc89vVs/jBLY/fM0I80oLmJkFUV3Q3wk9J3miYhP14zgVEBsPZY68IZlEjT6T3Xlq2xO1AVaatHsA==", + "integrity": "sha1-yQxGFUL801ttWwFaKQ+w2/tB0kI=", "dev": true, "requires": { "@lerna/global-options": "3.13.0", @@ -4759,13 +4759,13 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", "dev": true }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", "dev": true, "requires": { "string-width": "^3.1.0", @@ -4776,7 +4776,7 @@ "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", "dev": true, "requires": { "locate-path": "^3.0.0" @@ -4785,13 +4785,13 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", "dev": true }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", "dev": true, "requires": { "p-locate": "^3.0.0", @@ -4801,7 +4801,7 @@ "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4810,7 +4810,7 @@ "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", "dev": true, "requires": { "p-limit": "^2.0.0" @@ -4819,19 +4819,19 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", "dev": true, "requires": { "emoji-regex": "^7.0.1", @@ -4842,7 +4842,7 @@ "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", "dev": true, "requires": { "ansi-regex": "^4.1.0" @@ -4851,7 +4851,7 @@ "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", "dev": true, "requires": { "ansi-styles": "^3.2.0", @@ -4862,7 +4862,7 @@ "yargs": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "integrity": "sha1-Ghw+3O0a+yov6jNgS8bR2NaIpBQ=", "dev": true, "requires": { "cliui": "^5.0.0", @@ -4881,7 +4881,7 @@ "yargs-parser": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "integrity": "sha1-VHhq9AuCDcsvuAJbEbTWWddjI7M=", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -4893,7 +4893,7 @@ "@lerna/collect-uncommitted": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz", - "integrity": "sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==", + "integrity": "sha1-pJTWGqwxzceuxLvlLJZVAnQTLmM=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4905,7 +4905,7 @@ "@lerna/collect-updates": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.20.0.tgz", - "integrity": "sha512-qBTVT5g4fupVhBFuY4nI/3FSJtQVcDh7/gEPOpRxoXB/yCSnT38MFHXWl+y4einLciCjt/+0x6/4AG80fjay2Q==", + "integrity": "sha1-YvnXa6IaJbfZ+/McAt6IdEpWS9E=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4918,7 +4918,7 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", "dev": true } } @@ -4926,7 +4926,7 @@ "@lerna/command": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.21.0.tgz", - "integrity": "sha512-T2bu6R8R3KkH5YoCKdutKv123iUgUbW8efVjdGCDnCMthAQzoentOJfDeodBwn0P2OqCl3ohsiNVtSn9h78fyQ==", + "integrity": "sha1-miODdZ3HtwDaz6iiKy86bhkBIfc=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4944,7 +4944,7 @@ "@lerna/conventional-commits": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.22.0.tgz", - "integrity": "sha512-z4ZZk1e8Mhz7+IS8NxHr64wyklHctCJyWpJKEZZPJiLFJ8yKto/x38O80R10pIzC0rr8Sy/OsjSH4bl0TbbgqA==", + "integrity": "sha1-J5j0iB7i70V72uAnq30L8K9vHgk=", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -4974,7 +4974,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4986,7 +4986,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -4994,7 +4994,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true } } @@ -5002,7 +5002,7 @@ "@lerna/create": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.22.0.tgz", - "integrity": "sha512-MdiQQzCcB4E9fBF1TyMOaAEz9lUjIHp1Ju9H7f3lXze5JK6Fl5NYkouAvsLgY6YSIhXMY8AHW2zzXeBDY4yWkw==", + "integrity": "sha1-1rvQN8PcW0Jf5fbRuBcFfCePdhk=", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", @@ -5028,13 +5028,13 @@ "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", "dev": true }, "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -5080,7 +5080,7 @@ "globby": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=", "dev": true, "requires": { "@types/glob": "^7.1.1", @@ -5096,13 +5096,13 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5114,7 +5114,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -5122,13 +5122,13 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", "dev": true } } @@ -5136,7 +5136,7 @@ "@lerna/create-symlink": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-3.16.2.tgz", - "integrity": "sha512-pzXIJp6av15P325sgiIRpsPXLFmkisLhMBCy4764d+7yjf2bzrJ4gkWVMhsv4AdF0NN3OyZ5jjzzTtLNqfR+Jw==", + "integrity": "sha1-QSy45Zpy9afZRj5ORyGtIHAUmWc=", "dev": true, "requires": { "@zkochan/cmd-shim": "^3.1.0", @@ -5160,7 +5160,7 @@ "@lerna/describe-ref": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.16.5.tgz", - "integrity": "sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==", + "integrity": "sha1-ozjCWq7YN9PccLinLER8XGY0asA=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5170,7 +5170,7 @@ "@lerna/diff": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.21.0.tgz", - "integrity": "sha512-5viTR33QV3S7O+bjruo1SaR40m7F2aUHJaDAC7fL9Ca6xji+aw1KFkpCtVlISS0G8vikUREGMJh+c/VMSc8Usw==", + "integrity": "sha1-5t8Ni5kWFn/1pJ/LAqwGQkKApo0=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5182,7 +5182,7 @@ "@lerna/exec": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.21.0.tgz", - "integrity": "sha512-iLvDBrIE6rpdd4GIKTY9mkXyhwsJ2RvQdB9ZU+/NhR3okXfqKc6py/24tV111jqpXTtZUW6HNydT4dMao2hi1Q==", + "integrity": "sha1-F/B1M4k8uRihe0G8xWbcQ3AW2yY=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5197,7 +5197,7 @@ "@lerna/filter-options": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.20.0.tgz", - "integrity": "sha512-bmcHtvxn7SIl/R9gpiNMVG7yjx7WyT0HSGw34YVZ9B+3xF/83N3r5Rgtjh4hheLZ+Q91Or0Jyu5O3Nr+AwZe2g==", + "integrity": "sha1-Dw9dWkeDhW7s5CBHCMyQLLyK9Zs=", "dev": true, "requires": { "@lerna/collect-updates": "3.20.0", @@ -5210,7 +5210,7 @@ "@lerna/filter-packages": { "version": "3.18.0", "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.18.0.tgz", - "integrity": "sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==", + "integrity": "sha1-ano3bShSCNsDqClYz7gXLhebTnA=", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -5221,7 +5221,7 @@ "@lerna/get-npm-exec-opts": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.13.0.tgz", - "integrity": "sha512-Y0xWL0rg3boVyJk6An/vurKzubyJKtrxYv2sj4bB8Mc5zZ3tqtv0ccbOkmkXKqbzvNNF7VeUt1OJ3DRgtC/QZw==", + "integrity": "sha1-0bVSywCIGZ/D5+Em+RTjmgjfnqU=", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -5230,7 +5230,7 @@ "@lerna/get-packed": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-3.16.0.tgz", - "integrity": "sha512-AjsFiaJzo1GCPnJUJZiTW6J1EihrPkc2y3nMu6m3uWFxoleklsSCyImumzVZJssxMi3CPpztj8LmADLedl9kXw==", + "integrity": "sha1-GzFrcG3O6Gx7qlXlCwh5WUR4Uv8=", "dev": true, "requires": { "fs-extra": "^8.1.0", @@ -5254,7 +5254,7 @@ "@lerna/github-client": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.22.0.tgz", - "integrity": "sha512-O/GwPW+Gzr3Eb5bk+nTzTJ3uv+jh5jGho9BOqKlajXaOkMYGBELEAqV5+uARNGWZFvYAiF4PgqHb6aCUu7XdXg==", + "integrity": "sha1-XYFqpPdnR+1zauZP+WK48Vw1TZU=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5267,7 +5267,7 @@ "@lerna/gitlab-client": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-3.15.0.tgz", - "integrity": "sha512-OsBvRSejHXUBMgwWQqNoioB8sgzL/Pf1pOUhHKtkiMl6aAWjklaaq5HPMvTIsZPfS6DJ9L5OK2GGZuooP/5c8Q==", + "integrity": "sha1-kfTsjGl7WsV/fyW9UP5lnSSqlqY=", "dev": true, "requires": { "node-fetch": "^2.5.0", @@ -5278,13 +5278,13 @@ "@lerna/global-options": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.13.0.tgz", - "integrity": "sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ==", + "integrity": "sha1-IXZiKQ2watnPLEnY4xAO4o6uuuE=", "dev": true }, "@lerna/has-npm-version": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz", - "integrity": "sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==", + "integrity": "sha1-q4OVbyEdiSPqav6bl5s4zHOxUyY=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5294,7 +5294,7 @@ "@lerna/import": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.22.0.tgz", - "integrity": "sha512-uWOlexasM5XR6tXi4YehODtH9Y3OZrFht3mGUFFT3OIl2s+V85xIGFfqFGMTipMPAGb2oF1UBLL48kR43hRsOg==", + "integrity": "sha1-Gl8DlPOOI8T2QqEj5eFRfnDQaNI=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5323,7 +5323,7 @@ "@lerna/info": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/info/-/info-3.21.0.tgz", - "integrity": "sha512-0XDqGYVBgWxUquFaIptW2bYSIu6jOs1BtkvRTWDDhw4zyEdp6q4eaMvqdSap1CG+7wM5jeLCi6z94wS0AuiuwA==", + "integrity": "sha1-dmlrZ2/bDzXUjIPGPB4yu143gU8=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5334,7 +5334,7 @@ "@lerna/init": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.21.0.tgz", - "integrity": "sha512-6CM0z+EFUkFfurwdJCR+LQQF6MqHbYDCBPyhu/d086LRf58GtYZYj49J8mKG9ktayp/TOIxL/pKKjgLD8QBPOg==", + "integrity": "sha1-HoEJNNyL9OU4bAMQQYgdO0CWqlw=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5360,7 +5360,7 @@ "@lerna/link": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.21.0.tgz", - "integrity": "sha512-tGu9GxrX7Ivs+Wl3w1+jrLi1nQ36kNI32dcOssij6bg0oZ2M2MDEFI9UF2gmoypTaN9uO5TSsjCFS7aR79HbdQ==", + "integrity": "sha1-i+aP8MzuEEsXS1u9YGMCwvBunZs=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5373,7 +5373,7 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", "dev": true } } @@ -5381,7 +5381,7 @@ "@lerna/list": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.21.0.tgz", - "integrity": "sha512-KehRjE83B1VaAbRRkRy6jLX1Cin8ltsrQ7FHf2bhwhRHK0S54YuA6LOoBnY/NtA8bHDX/Z+G5sMY78X30NS9tg==", + "integrity": "sha1-Qvdvr6Vt6hO2keyMqxODJpHWHaI=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5393,7 +5393,7 @@ "@lerna/listable": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.18.5.tgz", - "integrity": "sha512-Sdr3pVyaEv5A7ZkGGYR7zN+tTl2iDcinryBPvtuv20VJrXBE8wYcOks1edBTcOWsPjCE/rMP4bo1pseyk3UTsg==", + "integrity": "sha1-6CeYQFte2PxRhDyO8eeg5Jc4iho=", "dev": true, "requires": { "@lerna/query-graph": "3.18.5", @@ -5404,7 +5404,7 @@ "@lerna/log-packed": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-3.16.0.tgz", - "integrity": "sha512-Fp+McSNBV/P2mnLUYTaSlG8GSmpXM7krKWcllqElGxvAqv6chk2K3c2k80MeVB4WvJ9tRjUUf+i7HUTiQ9/ckQ==", + "integrity": "sha1-+DmRBB7neySVY04URwtCJZ/SvBY=", "dev": true, "requires": { "byte-size": "^5.0.1", @@ -5416,7 +5416,7 @@ "@lerna/npm-conf": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.16.0.tgz", - "integrity": "sha512-HbO3DUrTkCAn2iQ9+FF/eisDpWY5POQAOF1m7q//CZjdC2HSW3UYbKEGsSisFxSfaF9Z4jtrV+F/wX6qWs3CuA==", + "integrity": "sha1-HBComuL2wu6WliVXc4aFMA03aCc=", "dev": true, "requires": { "config-chain": "^1.1.11", @@ -5426,7 +5426,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true } } @@ -5434,7 +5434,7 @@ "@lerna/npm-dist-tag": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.5.tgz", - "integrity": "sha512-xw0HDoIG6HreVsJND9/dGls1c+lf6vhu7yJoo56Sz5bvncTloYGLUppIfDHQr4ZvmPCK8rsh0euCVh2giPxzKQ==", + "integrity": "sha1-nvmrt8EEB3sx9vqyLMc7MU1UrFU=", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -5447,7 +5447,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5459,7 +5459,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -5467,7 +5467,7 @@ "@lerna/npm-install": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.5.tgz", - "integrity": "sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==", + "integrity": "sha1-1r/cFvgShdpmUVrkeSTW4njWN9M=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5493,7 +5493,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5505,7 +5505,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -5513,7 +5513,7 @@ "@lerna/npm-publish": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.18.5.tgz", - "integrity": "sha512-3etLT9+2L8JAx5F8uf7qp6iAtOLSMj+ZYWY6oUgozPi/uLqU0/gsMsEXh3F0+YVW33q0M61RpduBoAlOOZnaTg==", + "integrity": "sha1-JA5AOZWf2YFrScWwdCHhG1ywAK8=", "dev": true, "requires": { "@evocateur/libnpmpublish": "^1.2.2", @@ -5541,7 +5541,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5553,13 +5553,13 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -5567,7 +5567,7 @@ "@lerna/npm-run-script": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz", - "integrity": "sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==", + "integrity": "sha1-nC7IJFOibAtG7cC7fBWBbIIfXBU=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5578,7 +5578,7 @@ "@lerna/otplease": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/otplease/-/otplease-3.18.5.tgz", - "integrity": "sha512-S+SldXAbcXTEDhzdxYLU0ZBKuYyURP/ND2/dK6IpKgLxQYh/z4ScljPDMyKymmEvgiEJmBsPZAAPfmNPEzxjog==", + "integrity": "sha1-t3uOdgtAq62fdljZiPPqd9T9AjE=", "dev": true, "requires": { "@lerna/prompt": "3.18.5", @@ -5588,7 +5588,7 @@ "@lerna/output": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/output/-/output-3.13.0.tgz", - "integrity": "sha512-7ZnQ9nvUDu/WD+bNsypmPG5MwZBwu86iRoiW6C1WBuXXDxM5cnIAC1m2WxHeFnjyMrYlRXM9PzOQ9VDD+C15Rg==", + "integrity": "sha1-Pe18yQiyephyIopjDZUK7a56SYk=", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -5597,7 +5597,7 @@ "@lerna/pack-directory": { "version": "3.16.4", "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.16.4.tgz", - "integrity": "sha512-uxSF0HZeGyKaaVHz5FroDY9A5NDDiCibrbYR6+khmrhZtY0Bgn6hWq8Gswl9iIlymA+VzCbshWIMX4o2O8C8ng==", + "integrity": "sha1-Pq5fkb31rP4DhFEO1T+t3EwHRpM=", "dev": true, "requires": { "@lerna/get-packed": "3.16.0", @@ -5613,7 +5613,7 @@ "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -5626,7 +5626,7 @@ "@lerna/package": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/package/-/package-3.16.0.tgz", - "integrity": "sha512-2lHBWpaxcBoiNVbtyLtPUuTYEaB/Z+eEqRS9duxpZs6D+mTTZMNy6/5vpEVSCBmzvdYpyqhqaYjjSLvjjr5Riw==", + "integrity": "sha1-fgpG5Gl+2LipwU1Zx/iQ4NOLoTw=", "dev": true, "requires": { "load-json-file": "^5.3.0", @@ -5637,7 +5637,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -5650,7 +5650,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5662,19 +5662,19 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", "dev": true } } @@ -5682,7 +5682,7 @@ "@lerna/package-graph": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.18.5.tgz", - "integrity": "sha512-8QDrR9T+dBegjeLr+n9WZTVxUYUhIUjUgZ0gvNxUBN8S1WB9r6H5Yk56/MVaB64tA3oGAN9IIxX6w0WvTfFudA==", + "integrity": "sha1-x0Di6jV40FnlUWM+lQaQgxuUH2s=", "dev": true, "requires": { "@lerna/prerelease-id-from-version": "3.16.0", @@ -5695,7 +5695,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5707,7 +5707,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -5717,7 +5717,7 @@ "@lerna/prerelease-id-from-version": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-3.16.0.tgz", - "integrity": "sha512-qZyeUyrE59uOK8rKdGn7jQz+9uOpAaF/3hbslJVFL1NqF9ELDTqjCPXivuejMX/lN4OgD6BugTO4cR7UTq/sZA==", + "integrity": "sha1-skv6eJ9eG6q5FNewi6rpt719g6E=", "dev": true, "requires": { "semver": "^6.2.0" @@ -5726,7 +5726,7 @@ "@lerna/profiler": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-3.20.0.tgz", - "integrity": "sha512-bh8hKxAlm6yu8WEOvbLENm42i2v9SsR4WbrCWSbsmOElx3foRnMlYk7NkGECa+U5c3K4C6GeBbwgqs54PP7Ljg==", + "integrity": "sha1-D23CNvTqj56l81jGcDMFpPMq0FE=", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -5751,7 +5751,7 @@ "@lerna/project": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.21.0.tgz", - "integrity": "sha512-xT1mrpET2BF11CY32uypV2GPtPVm6Hgtha7D81GQP9iAitk9EccrdNjYGt5UBYASl4CIDXBRxwmTTVGfrCx82A==", + "integrity": "sha1-XXhNLRDFYaAPIDILzbBAmXwQUC0=", "dev": true, "requires": { "@lerna/package": "3.16.0", @@ -5771,13 +5771,13 @@ "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", "dev": true }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "integrity": "sha1-BA9yaAnFked6F8CjYmykW08Wixo=", "dev": true, "requires": { "import-fresh": "^2.0.0", @@ -5789,7 +5789,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -5798,7 +5798,7 @@ "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -5835,7 +5835,7 @@ "globby": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=", "dev": true, "requires": { "@types/glob": "^7.1.1", @@ -5851,7 +5851,7 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", "dev": true }, "import-fresh": { @@ -5881,7 +5881,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -5894,25 +5894,25 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", "dev": true } } @@ -5920,7 +5920,7 @@ "@lerna/prompt": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-3.18.5.tgz", - "integrity": "sha512-rkKj4nm1twSbBEb69+Em/2jAERK8htUuV8/xSjN0NPC+6UjzAwY52/x9n5cfmpa9lyKf/uItp7chCI7eDmNTKQ==", + "integrity": "sha1-YozVRfIliH0GBJGrld+JnPxSGKE=", "dev": true, "requires": { "inquirer": "^6.2.0", @@ -5930,7 +5930,7 @@ "@lerna/publish": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.22.1.tgz", - "integrity": "sha512-PG9CM9HUYDreb1FbJwFg90TCBQooGjj+n/pb3gw/eH5mEDq0p8wKdLFe0qkiqUkm/Ub5C8DbVFertIo0Vd0zcw==", + "integrity": "sha1-tPfOP7oemvsovkofPYgiImm6lRk=", "dev": true, "requires": { "@evocateur/libnpmaccess": "^3.1.2", @@ -5979,7 +5979,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5991,7 +5991,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -6001,7 +6001,7 @@ "@lerna/pulse-till-done": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-3.13.0.tgz", - "integrity": "sha512-1SOHpy7ZNTPulzIbargrgaJX387csN7cF1cLOGZiJQA6VqnS5eWs2CIrG8i8wmaUavj2QlQ5oEbRMVVXSsGrzA==", + "integrity": "sha1-yOnOW6+vENkwpn1+0My12Vj+ARA=", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -6010,7 +6010,7 @@ "@lerna/query-graph": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.18.5.tgz", - "integrity": "sha512-50Lf4uuMpMWvJ306be3oQDHrWV42nai9gbIVByPBYJuVW8dT8O8pA3EzitNYBUdLL9/qEVbrR0ry1HD7EXwtRA==", + "integrity": "sha1-30gwu1FVJzADvzXo3aHDLQknvYY=", "dev": true, "requires": { "@lerna/package-graph": "3.18.5", @@ -6020,7 +6020,7 @@ "@lerna/resolve-symlink": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-3.16.0.tgz", - "integrity": "sha512-Ibj5e7njVHNJ/NOqT4HlEgPFPtPLWsO7iu59AM5bJDcAJcR96mLZ7KGVIsS2tvaO7akMEJvt2P+ErwCdloG3jQ==", + "integrity": "sha1-N/xwlfq9vPMXwm63Tg0L3o79I4Y=", "dev": true, "requires": { "fs-extra": "^8.1.0", @@ -6044,7 +6044,7 @@ "@lerna/rimraf-dir": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz", - "integrity": "sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==", + "integrity": "sha1-BDFqtf/SkJZXqvOI6lAsuMLyCgk=", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -6056,7 +6056,7 @@ "@lerna/run": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.21.0.tgz", - "integrity": "sha512-fJF68rT3veh+hkToFsBmUJ9MHc9yGXA7LSDvhziAojzOb0AI/jBDp6cEcDQyJ7dbnplba2Lj02IH61QUf9oW0Q==", + "integrity": "sha1-KjXshJeeTW5CR0/hSNMuXeHKyJE=", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -6073,7 +6073,7 @@ "@lerna/run-lifecycle": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.16.2.tgz", - "integrity": "sha512-RqFoznE8rDpyyF0rOJy3+KjZCeTkO8y/OB9orPauR7G2xQ7PTdCpgo7EO6ZNdz3Al+k1BydClZz/j78gNCmL2A==", + "integrity": "sha1-Z7KI+OqWTbnqT7H7x3FdW7sLzgA=", "dev": true, "requires": { "@lerna/npm-conf": "3.16.0", @@ -6085,7 +6085,7 @@ "@lerna/run-topologically": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.18.5.tgz", - "integrity": "sha512-6N1I+6wf4hLOnPW+XDZqwufyIQ6gqoPfHZFkfWlvTQ+Ue7CuF8qIVQ1Eddw5HKQMkxqN10thKOFfq/9NQZ4NUg==", + "integrity": "sha1-PNY52iDpZ9dnLLiNsPdWuS8v38M=", "dev": true, "requires": { "@lerna/query-graph": "3.18.5", @@ -6096,13 +6096,13 @@ "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "integrity": "sha1-LT1I+cNGaY/Og6hdfWZOmFNd9uc=", "dev": true }, "p-queue": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", - "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", + "integrity": "sha1-7Q7uh5iSftbywvX1t3/bIGGl00Y=", "dev": true, "requires": { "eventemitter3": "^3.1.0" @@ -6113,7 +6113,7 @@ "@lerna/symlink-binary": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz", - "integrity": "sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==", + "integrity": "sha1-j4AxswmGOBSIPT8AmHf4Ljiu9Fo=", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -6138,7 +6138,7 @@ "@lerna/symlink-dependencies": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz", - "integrity": "sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==", + "integrity": "sha1-SNY2DphYZaDlbNi1GzCKUmMIeEo=", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -6166,13 +6166,13 @@ "@lerna/timer": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-3.13.0.tgz", - "integrity": "sha512-RHWrDl8U4XNPqY5MQHkToWS9jHPnkLZEt5VD+uunCKTfzlxGnRCr3/zVr8VGy/uENMYpVP3wJa4RKGY6M0vkRw==", + "integrity": "sha1-vNCQRVHbFuCDZNbBjl4hYPyHB4E=", "dev": true }, "@lerna/validation-error": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-3.13.0.tgz", - "integrity": "sha512-SiJP75nwB8GhgwLKQfdkSnDufAaCbkZWJqEDlKOUPUvVOplRGnfL+BPQZH5nvq2BYSRXsksXWZ4UHVnQZI/HYA==", + "integrity": "sha1-yGuPB8WrlTn3db2KVJdukm83WcM=", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -6181,7 +6181,7 @@ "@lerna/version": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.22.1.tgz", - "integrity": "sha512-PSGt/K1hVqreAFoi3zjD0VEDupQ2WZVlVIwesrE5GbrL2BjXowjCsTDPqblahDUPy0hp6h7E2kG855yLTp62+g==", + "integrity": "sha1-mAWpJHpH7mLWuBvZ+l+3KLJLWeI=", "dev": true, "requires": { "@lerna/check-working-tree": "3.16.5", @@ -6215,7 +6215,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -6228,19 +6228,19 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", "dev": true } } @@ -6248,7 +6248,7 @@ "@lerna/write-log-file": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-3.13.0.tgz", - "integrity": "sha512-RibeMnDPvlL8bFYW5C8cs4mbI3AHfQef73tnJCQ/SgrXZHehmHnsyWUiE7qDQCAo+B1RfTapvSyFF69iPj326A==", + "integrity": "sha1-t42eTPwTSai+ZNkTJMTIGZ6CKiY=", "dev": true, "requires": { "npmlog": "^4.1.2", @@ -6258,7 +6258,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -6271,7 +6271,7 @@ "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=", "dev": true, "requires": { "call-me-maybe": "^1.0.1", @@ -7452,7 +7452,7 @@ "@octokit/auth-token": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", - "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", + "integrity": "sha1-ENCul5sQD6a3L6Do5j4n5tDb/4o=", "dev": true, "requires": { "@octokit/types": "^5.0.0" @@ -7461,7 +7461,7 @@ "@octokit/endpoint": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.5.tgz", - "integrity": "sha512-70K5u6zd45ItOny6aHQAsea8HHQjlQq85yqOMe+Aj8dkhN2qSJ9T+Q3YjUjEYfPRBcuUWNgMn62DQnP/4LAIiQ==", + "integrity": "sha1-Q6at7oE8X/0vcZ4gz9FKH+58GTo=", "dev": true, "requires": { "@octokit/types": "^5.0.0", @@ -7472,13 +7472,13 @@ "is-plain-object": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", + "integrity": "sha1-GhTWRSy9UHkO3H/aoK7VpAo167U=", "dev": true }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "integrity": "sha1-M4H4UDslHA2c0hvB3pOeyd9UgO4=", "dev": true } } @@ -7486,13 +7486,13 @@ "@octokit/plugin-enterprise-rest": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", - "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", + "integrity": "sha1-4HiWc5YY2rjafUB3xlgAN3X5VDc=", "dev": true }, "@octokit/plugin-paginate-rest": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", + "integrity": "sha1-AEFwrPjCvlNauiZyeGfWkve0iPw=", "dev": true, "requires": { "@octokit/types": "^2.0.1" @@ -7501,7 +7501,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", "dev": true, "requires": { "@types/node": ">= 8" @@ -7512,13 +7512,13 @@ "@octokit/plugin-request-log": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz", - "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==", + "integrity": "sha1-7vh6QxMA9hSMOaf3X4z+shiyVH4=", "dev": true }, "@octokit/plugin-rest-endpoint-methods": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", + "integrity": "sha1-Mojs9UgfaMSU3QYC/BVAeln69h4=", "dev": true, "requires": { "@octokit/types": "^2.0.1", @@ -7528,7 +7528,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", "dev": true, "requires": { "@types/node": ">= 8" @@ -7539,7 +7539,7 @@ "@octokit/request": { "version": "5.4.7", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.7.tgz", - "integrity": "sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==", + "integrity": "sha1-/XA+4JLgRjzrpJ/3o+YctM+KD94=", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", @@ -7555,7 +7555,7 @@ "@octokit/request-error": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", - "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", + "integrity": "sha1-Dna4P12P3aHbmQJ+pfYXwua6ntA=", "dev": true, "requires": { "@octokit/types": "^5.0.1", @@ -7566,13 +7566,13 @@ "is-plain-object": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", + "integrity": "sha1-GhTWRSy9UHkO3H/aoK7VpAo167U=", "dev": true }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "integrity": "sha1-M4H4UDslHA2c0hvB3pOeyd9UgO4=", "dev": true } } @@ -7580,7 +7580,7 @@ "@octokit/request-error": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", - "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", + "integrity": "sha1-7eBxTHc/MjR1dsJWSdwBOuazGAE=", "dev": true, "requires": { "@octokit/types": "^2.0.0", @@ -7591,7 +7591,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", + "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", "dev": true, "requires": { "@types/node": ">= 8" @@ -7602,7 +7602,7 @@ "@octokit/rest": { "version": "16.43.2", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", - "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", + "integrity": "sha1-xTQm8eHRBE3ulnAj4yecUJk92Rs=", "dev": true, "requires": { "@octokit/auth-token": "^2.4.0", @@ -7626,7 +7626,7 @@ "@octokit/types": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.2.0.tgz", - "integrity": "sha512-XjOk9y4m8xTLIKPe1NFxNWBdzA2/z3PFFA/bwf4EoH6oS8hM0Y46mEa4Cb+KCyj/tFDznJFahzQ0Aj3o1FYq4A==", + "integrity": "sha1-0HXcI78pP1QHOSULaHniwb4vwgw=", "dev": true, "requires": { "@types/node": ">= 8" @@ -7719,12 +7719,12 @@ "@restart/context": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==" + "integrity": "sha1-qZ2HwpmjTCi9hbtInLB7/SMUnAI=" }, "@restart/hooks": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.25.tgz", - "integrity": "sha512-m2v3N5pxTsIiSH74/sb1yW8D9RxkJidGW+5Mfwn/lHb2QzhZNlaU1su7abSyT9EGf0xS/0waLjrf7/XxQHUk7w==", + "integrity": "sha1-EQBBOa0ccNL1llqJOdy1rrlqplI=", "requires": { "lodash": "^4.17.15", "lodash-es": "^4.17.15" @@ -8244,7 +8244,7 @@ "@types/invariant": { "version": "2.2.34", "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz", - "integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg==" + "integrity": "sha1-BeT3n0ZcIAeIQ3TUeVRS+ZVyC74=" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -8423,7 +8423,7 @@ "@types/react-transition-group": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", - "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", + "integrity": "sha1-iCg520Zd8TIOR1Pm6fcMp+m01G0=", "requires": { "@types/react": "*" } @@ -8942,7 +8942,7 @@ "@zkochan/cmd-shim": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@zkochan/cmd-shim/-/cmd-shim-3.1.0.tgz", - "integrity": "sha512-o8l0+x7C7sMZU3v9GuJIAU10qQLtwR1dtRQIOmlNMtyaqhmpXOzx1HWiYoWfmmf9HHZoAkXpc9TM9PQYF9d4Jg==", + "integrity": "sha1-KrjtgfW7VFKoXyV1jrm4aBmC/S4=", "dev": true, "requires": { "is-windows": "^1.0.0", @@ -9430,7 +9430,7 @@ "array-differ": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", + "integrity": "sha1-S5wcPxS5BnVwgpJXaeirkE9IAbE=", "dev": true }, "array-each": { @@ -10001,7 +10001,7 @@ "babel-jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", - "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", + "integrity": "sha1-IGCTrDgKS3jEQEoFsydzkSePgPs=", "dev": true, "requires": { "@jest/transform": "^25.1.0", @@ -10026,7 +10026,7 @@ "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -10036,7 +10036,7 @@ "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", "dev": true, "requires": { "color-name": "~1.1.4" @@ -10045,25 +10045,25 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", "dev": true }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -11160,7 +11160,7 @@ "before-after-hook": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", - "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", + "integrity": "sha1-tsA0h/ROJCAN0wyl5qGXnF0vtjU=", "dev": true }, "big.js": { @@ -12523,7 +12523,7 @@ "byte-size": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-5.0.1.tgz", - "integrity": "sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==", + "integrity": "sha1-S2UQOaXs2Wdn5xo9ftOA5IvtQZE=", "dev": true }, "bytes": { @@ -12674,7 +12674,7 @@ "camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "integrity": "sha1-XnVda6UaoiPsfT1S8ld4IQ+dw8A=", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -13018,7 +13018,7 @@ "classnames": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "integrity": "sha1-Q5Nb/90pHzJtrQogUwmzjQD2UM4=" }, "clean-css": { "version": "4.2.1", @@ -13418,7 +13418,7 @@ "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "integrity": "sha1-xQclrzgIyKsCYP1gsB+/oluVT2k=", "dev": true }, "commander": { @@ -13441,7 +13441,7 @@ "compare-func": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz", - "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==", + "integrity": "sha1-awfExeg0ERm69EV4CFvaD0qCNRY=", "dev": true, "requires": { "array-ify": "^1.0.0", @@ -13699,7 +13699,7 @@ "conventional-changelog-angular": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz", - "integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==", + "integrity": "sha1-XPewDdMVtqalWCI8gNXvJN2zQgU=", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -13709,7 +13709,7 @@ "conventional-changelog-core": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.2.3.tgz", - "integrity": "sha512-LMMX1JlxPIq/Ez5aYAYS5CpuwbOk6QFp8O4HLAcZxe3vxoCtABkhfjetk8IYdRB9CDQGwJFLR3Dr55Za6XKgUQ==", + "integrity": "sha1-sxQQhW9DHIRwhqfctNLKGEp9iPs=", "dev": true, "requires": { "conventional-changelog-writer": "^4.0.6", @@ -13751,7 +13751,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13763,13 +13763,13 @@ "conventional-changelog-preset-loader": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "integrity": "sha1-FKhVq7/9WQJ/1gJYHx802YYupEw=", "dev": true }, "conventional-changelog-writer": { "version": "4.0.16", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz", - "integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==", + "integrity": "sha1-yhDyaRqOptPC63S9Nbz0CqBS3aU=", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -13787,7 +13787,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13799,7 +13799,7 @@ "conventional-commits-filter": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", - "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", + "integrity": "sha1-CTXhJAxcp2mDKa/+4bakbTMyTEw=", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", @@ -13809,7 +13809,7 @@ "conventional-commits-parser": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", - "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", + "integrity": "sha1-EBQGc9Xn71VyYzeRRWxdA7aei+Q=", "dev": true, "requires": { "JSONStream": "^1.0.4", @@ -13824,7 +13824,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13836,7 +13836,7 @@ "conventional-recommended-bump": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-5.0.1.tgz", - "integrity": "sha512-RVdt0elRcCxL90IrNP0fYCpq1uGt2MALko0eyeQ+zQuDVWtMGAy9ng6yYn3kax42lCj9+XBxQ8ZN6S9bdKxDhQ==", + "integrity": "sha1-WvY5A5R7bgied3Z2ActZLKuxBro=", "dev": true, "requires": { "concat-stream": "^2.0.0", @@ -13869,7 +13869,7 @@ "concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "integrity": "sha1-QUz1r3kKSMYKub5FJ9VtXkETPLE=", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -13893,7 +13893,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -13910,7 +13910,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -14875,7 +14875,7 @@ "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "integrity": "sha1-puN0maTZqc+F71hyBE1ikByYia4=", "dev": true }, "deasync": { @@ -15399,7 +15399,7 @@ "deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "integrity": "sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk=", "dev": true }, "deps-sort": { @@ -15564,7 +15564,7 @@ "dom-helpers": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", - "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", + "integrity": "sha1-V/0FTF+PNMUqPu/9t+fpPNNX2Vs=", "requires": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -17392,7 +17392,7 @@ "express-ws": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-4.0.0.tgz", - "integrity": "sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw==", + "integrity": "sha1-2r2NyXRRZBiQKkH+bjDtlJtNNsQ=", "requires": { "ws": "^5.2.0" }, @@ -17400,7 +17400,7 @@ "ws": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "integrity": "sha1-3/7xSGa46NyRM1glFNG++vlumA8=", "requires": { "async-limiter": "~1.0.0" } @@ -19127,7 +19127,7 @@ "genfun": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "integrity": "sha1-ndlxCgaQClxKW/V6yl2k5S/nZTc=", "dev": true }, "gensync": { @@ -19355,7 +19355,7 @@ "get-port": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", + "integrity": "sha1-43Nosehjt2KcQ8WjI2Jflc8ksRk=", "dev": true }, "get-stdin": { @@ -19481,7 +19481,7 @@ "git-raw-commits": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", - "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", + "integrity": "sha1-2Srd90RAwUvMXIPszj+3+KeRGLU=", "dev": true, "requires": { "dargs": "^4.0.1", @@ -19523,7 +19523,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -19540,7 +19540,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -19619,7 +19619,7 @@ "git-semver-tags": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.3.tgz", - "integrity": "sha512-tj4FD4ww2RX2ae//jSrXZzrocla9db5h0V7ikPl1P/WwoZar9epdUhwR7XHXSgc+ZkNq72BEEerqQuicoEQfzA==", + "integrity": "sha1-SJiKcYrPWTgA+ZYiqVKnfEBb+jQ=", "dev": true, "requires": { "meow": "^4.0.0", @@ -19658,7 +19658,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -19675,7 +19675,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -19736,7 +19736,7 @@ "git-up": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz", - "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==", + "integrity": "sha1-yy7whmU2QOch0gQv4xBIV9iQB8A=", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -19746,7 +19746,7 @@ "git-url-parse": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.1.2.tgz", - "integrity": "sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==", + "integrity": "sha1-r/Gol8NsyTaZJwWHvqPby7uV3mc=", "dev": true, "requires": { "git-up": "^4.0.0" @@ -20543,7 +20543,7 @@ "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "integrity": "sha1-1MBcG6+Q6ZRfd6pop6IZqkp9904=", "dev": true, "requires": { "minimist": "^1.2.5", @@ -20556,13 +20556,13 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true }, "uglify-js": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz", - "integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==", + "integrity": "sha1-OXp+bjHOggv9HLVbgE7hQMWHqec=", "dev": true, "optional": true }, @@ -20591,7 +20591,7 @@ "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "integrity": "sha1-HG7aXBaFxjlCdm15u0Cudzzs2IM=", "dev": true }, "harmony-reflect": { @@ -21221,7 +21221,7 @@ "init-package-json": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.10.3.tgz", - "integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==", + "integrity": "sha1-Rf/i9hCoyhNPK9HbVjeyNQcPbL4=", "dev": true, "requires": { "glob": "^7.1.1", @@ -21237,7 +21237,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", + "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -21249,7 +21249,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -22051,7 +22051,7 @@ "is-ssh": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", - "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", + "integrity": "sha1-80moyt0k5lKYA3pSLPdSDy6BoPM=", "dev": true, "requires": { "protocols": "^1.1.0" @@ -24750,7 +24750,7 @@ "lerna": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.22.1.tgz", - "integrity": "sha512-vk1lfVRFm+UuEFA7wkLKeSF7Iz13W+N/vFd48aW2yuS7Kv0RbNm2/qcDPV863056LMfkRlsEe+QYOw3palj5Lg==", + "integrity": "sha1-ggJ6w9qcYn/YvwLM/v+AapjmW2I=", "dev": true, "requires": { "@lerna/add": "3.21.0", @@ -25146,7 +25146,7 @@ "lodash-es": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", - "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==" + "integrity": "sha1-Ib2Wg5NUQS8j16EDQOXqxu5FXXg=" }, "lodash._arraycopy": { "version": "3.0.0", @@ -25317,7 +25317,7 @@ "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "integrity": "sha1-+XYZXPPzR9DV9SSDVp/oAxzM6Ks=", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0", @@ -25327,7 +25327,7 @@ "lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "integrity": "sha1-5IExDwSdPPbUfpEq0JMTsVTw+zM=", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0" @@ -25519,7 +25519,7 @@ "macos-release": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz", - "integrity": "sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==", + "integrity": "sha1-ZAM9Dsal5jdRVadLGh66jlCYIKw=", "dev": true }, "magic-string": { @@ -25779,7 +25779,7 @@ "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "integrity": "sha1-uRIhtUJzS58UJWwBMsiXxdclb9U=", "dev": true }, "map-visit": { @@ -25968,7 +25968,7 @@ "meow": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", + "integrity": "sha1-HtSgpQs4RLRRNpxINi6wUV8Ewdw=", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -25989,19 +25989,19 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=", "dev": true }, "camelcase": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "integrity": "sha1-Uln3ww414njxvcKk2RIws3ytmB4=", "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -26011,7 +26011,7 @@ "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -26020,7 +26020,7 @@ "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", "dev": true, "requires": { "p-try": "^2.0.0" @@ -26029,7 +26029,7 @@ "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -26038,13 +26038,13 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", "dev": true }, "parse-json": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "integrity": "sha1-fP41wczWQbzjmBRn5sLs5hs7OHg=", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -26056,13 +26056,13 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", "dev": true }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "integrity": "sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w=", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", @@ -26074,7 +26074,7 @@ "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "integrity": "sha1-jSojcNPfiG61yQraHFv2GIrPg4s=", "dev": true } } @@ -26082,7 +26082,7 @@ "read-pkg-up": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "integrity": "sha1-86YTV1hFlzOuK5VjgFbhhU5+9Qc=", "dev": true, "requires": { "find-up": "^4.1.0", @@ -26093,7 +26093,7 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=", "dev": true } } @@ -26101,13 +26101,13 @@ "type-fest": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "integrity": "sha1-AXLLW86AsL1ULqNI21DH4hg02TQ=", "dev": true }, "yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "integrity": "sha1-vmjEl1xrKr9GkjawyHA2L6sJp7A=", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -26117,7 +26117,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", "dev": true } } @@ -26392,7 +26392,7 @@ "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "integrity": "sha1-pj9oFnOzBXH76LwlaGrnRu76mGk=", "dev": true }, "mini-css-extract-plugin": { @@ -26452,7 +26452,7 @@ "minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "integrity": "sha1-wGVXE8U6ii69d/+iR9NCxA8BBhk=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -26961,7 +26961,7 @@ "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "integrity": "sha1-s5OfpgVUZHTj4+PGPWS9Q7TuYCI=", "dev": true }, "module-deps": { @@ -27193,7 +27193,7 @@ "multimatch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", + "integrity": "sha1-DiU0zGvCONmrZ+G5zV/Nhabb9ws=", "dev": true, "requires": { "array-differ": "^2.0.3", @@ -27229,7 +27229,7 @@ "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "integrity": "sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI=", "dev": true, "requires": { "any-promise": "^1.0.0", @@ -27758,12 +27758,12 @@ "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "integrity": "sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0=" }, "node-fetch-npm": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", - "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", + "integrity": "sha1-ZQfQ4XqewL477FFpWKSXzsVL9aQ=", "dev": true, "requires": { "encoding": "^0.1.11", @@ -30649,7 +30649,7 @@ "npm-lifecycle": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz", - "integrity": "sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==", + "integrity": "sha1-mILTZCuMgsgVeCoS5qG/7tACYwk=", "dev": true, "requires": { "byline": "^5.0.0", @@ -30665,7 +30665,7 @@ "node-gyp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", - "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", + "integrity": "sha1-65Ffe2Mck30oLjOu1Ey3oCX2Kj4=", "dev": true, "requires": { "env-paths": "^2.2.0", @@ -30684,7 +30684,7 @@ "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "integrity": "sha1-o3XK2dAv2SEnjZVMIlTVqlfhXkg=", "dev": true, "requires": { "abbrev": "1", @@ -30694,13 +30694,13 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -32780,7 +32780,7 @@ "octokit-pagination-methods": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", - "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", + "integrity": "sha1-z0cu3J1VEFX573P25CtNu0yAvqQ=", "dev": true }, "on-finished": { @@ -33601,7 +33601,7 @@ "os-name": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", + "integrity": "sha1-3sGdlmKW4c1i1wGlpm7h3ernCAE=", "dev": true, "requires": { "macos-release": "^2.2.0", @@ -34169,7 +34169,7 @@ "parse-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz", - "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==", + "integrity": "sha1-DsdpcElJd4yzuO2l6ZTDIHOhrf8=", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -34179,7 +34179,7 @@ "parse-url": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz", - "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==", + "integrity": "sha1-mcQIT8Eb4UFB76QbPRF6lvy5Un8=", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -34191,7 +34191,7 @@ "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=", "dev": true } } @@ -35408,7 +35408,7 @@ "prop-types-extra": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "integrity": "sha1-WMO3TL+7ldMEYll1qi8ISDKaAQs=", "requires": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -35429,13 +35429,13 @@ "protocols": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", - "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==", + "integrity": "sha1-lfeIpPDpebKR/+/PVjatET0DfTI=", "dev": true }, "protoduck": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", - "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "integrity": "sha1-A8NlnKGAB7aaUP2Cp+vMUWJhFR8=", "dev": true, "requires": { "genfun": "^5.0.0" @@ -35618,7 +35618,7 @@ "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "integrity": "sha1-W4h48ROlgheEjGSCAmxz4bpXcn8=", "dev": true }, "raf-schd": { @@ -35721,7 +35721,7 @@ "react": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "integrity": "sha1-LoGIIvGpdDEiwGPWQQ2FweOv5I4=", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -35786,7 +35786,7 @@ "react-dom": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "integrity": "sha1-wb03MxoEhsB47lTEdAcgmTsuDn8=", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -35802,7 +35802,7 @@ "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + "integrity": "sha1-TxonOv38jzSIqMUWv9p4+HI1I2I=" }, "react-overlays": { "version": "4.1.0", @@ -35844,7 +35844,7 @@ "react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "integrity": "sha1-Y4aPkyWjjqXulTXYKDJ/hXczRck=", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -35881,7 +35881,7 @@ "read-cmd-shim": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz", - "integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==", + "integrity": "sha1-h+Q+ulAJi6WjLQzrWDq45DuWHBY=", "dev": true, "requires": { "graceful-fs": "^4.1.2" @@ -35937,7 +35937,7 @@ "read-package-json": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.1.tgz", - "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==", + "integrity": "sha1-FqpmxZ59Ta1iiPF53ZKV/Vm7mPE=", "dev": true, "requires": { "glob": "^7.1.1", @@ -35960,7 +35960,7 @@ "read-package-tree": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", - "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", + "integrity": "sha1-oyy2TH8x64pvMe8G+c7fdAaP5jY=", "dev": true, "requires": { "read-package-json": "^2.0.0", @@ -36109,7 +36109,7 @@ "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "integrity": "sha1-5Ve3mYMWu1PJ8fVvpiY1LGljBZ8=", "dev": true, "requires": { "indent-string": "^4.0.0", @@ -37178,7 +37178,7 @@ "scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "integrity": "sha1-Tz4u0sGn1laB9MhU+oxaHMtA8ZY=", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -37922,7 +37922,7 @@ "solc": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.4.tgz", - "integrity": "sha512-IVLqAfUkJqgTS0JIgFPeC50ehUeBXu2eE+iU+rqb6UeOyf6w/BB/EsNcTSTpjtUti8BTG/sCd2qVhrWVYy7p0g==", + "integrity": "sha1-nF7YGuBpLj5hTkfNW1ALD5SFuY0=", "dev": true, "requires": { "command-exists": "^1.2.8", @@ -37939,7 +37939,7 @@ "commander": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "integrity": "sha1-aDfD+2d62ZM9HPukLdFNURfWs54=", "dev": true }, "fs-extra": { @@ -37958,7 +37958,7 @@ "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "integrity": "sha1-ubel2nOvrX3t0PjEY5VMveaBiEA=", "dev": true }, "jsonfile": { @@ -37973,7 +37973,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", "dev": true } } @@ -38165,7 +38165,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "dev": true, "requires": { "through": "2" @@ -38182,7 +38182,7 @@ "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", "dev": true, "requires": { "through2": "^2.0.2" @@ -39072,7 +39072,7 @@ "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "integrity": "sha1-wy4c7pQLazQyx3G8LFS8znPNMAE=", "dev": true, "requires": { "min-indent": "^1.0.0" @@ -39086,7 +39086,7 @@ "strong-log-transformer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", - "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "integrity": "sha1-D17XjTJeBCGsb5D38Q5pHWrjrhA=", "dev": true, "requires": { "duplexer": "^0.1.1", @@ -39690,7 +39690,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", "dev": true, "requires": { "pify": "^3.0.0" @@ -39808,7 +39808,7 @@ "text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "integrity": "sha1-GFPkX+45yUXOb2w2stZZtaq8KiY=", "dev": true }, "text-hex": { @@ -39825,7 +39825,7 @@ "thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "integrity": "sha1-iTLmhqQGYDigFt2eLKRq3Zg4qV8=", "dev": true, "requires": { "any-promise": "^1.0.0" @@ -40152,7 +40152,7 @@ "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "integrity": "sha1-eXJjBKaomKqDc0JymNVMLuixyzA=", "dev": true }, "trim-off-newlines": { @@ -40534,7 +40534,7 @@ "uncontrollable": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz", - "integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==", + "integrity": "sha1-9n/tPvk2NxJlcYCXRjI6nbgV1VY=", "requires": { "@babel/runtime": "^7.6.3", "@types/react": "^16.9.11", @@ -40716,7 +40716,7 @@ "universal-user-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", - "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", + "integrity": "sha1-/Y1st3OmeacJ6WfvgoijH8wD5Vc=", "dev": true, "requires": { "os-name": "^3.1.0" @@ -41296,7 +41296,7 @@ "warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", "requires": { "loose-envify": "^1.0.0" } @@ -42876,7 +42876,7 @@ "windows-release": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz", - "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==", + "integrity": "sha1-y06AOF+FUPcJcnKHv3EDXiCcSs4=", "dev": true, "requires": { "execa": "^1.0.0" @@ -43074,7 +43074,7 @@ "write-json-file": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", - "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", + "integrity": "sha1-Zbvcns2KFFjhWVJ3DMut/P9f5io=", "dev": true, "requires": { "detect-indent": "^5.0.0", @@ -43088,7 +43088,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", "dev": true }, "sort-keys": { @@ -43103,7 +43103,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -43116,7 +43116,7 @@ "write-pkg": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz", - "integrity": "sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==", + "integrity": "sha1-DheP6Xgg04mokovHlTXb5ows/yE=", "dev": true, "requires": { "sort-keys": "^2.0.0", @@ -43126,7 +43126,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", "dev": true, "requires": { "pify": "^3.0.0" @@ -43144,7 +43144,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", "dev": true, "requires": { "graceful-fs": "^4.1.11", From e638250a526c320e30cf4fa24dd6e86bcddc12b0 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 12 May 2021 06:49:37 +0100 Subject: [PATCH 154/199] Revert "Wait for workspace creation before fetching" This reverts commit 3c8912d3dfba91869fb0cb914b348458ea218e32. --- apps/remix-ide/src/app/files/file-explorer.js | 702 ++++++++++++++++++ apps/remix-ide/src/app/panels/file-panel.js | 20 +- .../src/lib/actions/fileSystem.ts | 6 +- package-lock.json | 600 +++++++-------- 4 files changed, 1012 insertions(+), 316 deletions(-) create mode 100644 apps/remix-ide/src/app/files/file-explorer.js diff --git a/apps/remix-ide/src/app/files/file-explorer.js b/apps/remix-ide/src/app/files/file-explorer.js new file mode 100644 index 0000000000..9f5f3e3f69 --- /dev/null +++ b/apps/remix-ide/src/app/files/file-explorer.js @@ -0,0 +1,702 @@ +/* global FileReader */ +/* global fetch */ +const async = require('async') +const Gists = require('gists') +const modalDialogCustom = require('../ui/modal-dialog-custom') +const tooltip = require('../ui/tooltip') +const QueryParams = require('../../lib/query-params') +const helper = require('../../lib/helper') +const yo = require('yo-yo') +const Treeview = require('../ui/TreeView') +const modalDialog = require('../ui/modaldialog') +const EventManager = require('../../lib/events') +const contextMenu = require('../ui/contextMenu') +const css = require('./styles/file-explorer-styles') +const globalRegistry = require('../../global/registry') +const queryParams = new QueryParams() +let MENU_HANDLE + +function fileExplorer (localRegistry, files, menuItems, plugin) { + var self = this + this.events = new EventManager() + // file provider backend + this.files = files + // element currently focused on + this.focusElement = null + // path currently focused on + this.focusPath = null + const allItems = + [ + { + action: 'createNewFile', + title: 'Create New File', + icon: 'fas fa-plus-circle' + }, + { + action: 'publishToGist', + title: 'Publish all [browser] explorer files to a github gist', + icon: 'fab fa-github' + }, + { + action: 'uploadFile', + title: 'Add Local file to the Browser Storage Explorer', + icon: 'far fa-folder-open' + }, + { + action: 'updateGist', + title: 'Update the current [gist] explorer', + icon: 'fab fa-github' + } + ] + // menu items + this.menuItems = allItems.filter( + (item) => { + if (menuItems) return menuItems.find((name) => { return name === item.action }) + } + ) + + self._components = {} + self._components.registry = localRegistry || globalRegistry + self._deps = { + config: self._components.registry.get('config').api, + editor: self._components.registry.get('editor').api, + fileManager: self._components.registry.get('filemanager').api + } + + self.events.register('focus', function (path) { + self._deps.fileManager.open(path) + }) + + self._components.registry.put({ api: self, name: `fileexplorer/${self.files.type}` }) + + // warn if file changed outside of Remix + function remixdDialog () { + return yo`
This file has been changed outside of Remix IDE.
` + } + + this.files.event.register('fileExternallyChanged', (path, file) => { + if (self._deps.config.get('currentFile') === path && self._deps.editor.currentContent() && self._deps.editor.currentContent() !== file.content) { + if (this.files.isReadOnly(path)) return self._deps.editor.setText(file.content) + + modalDialog(path + ' changed', remixdDialog(), + { + label: 'Replace by the new content', + fn: () => { + self._deps.editor.setText(file.content) + } + }, + { + label: 'Keep the content displayed in Remix', + fn: () => {} + } + ) + } + }) + + // register to event of the file provider + files.event.register('fileRemoved', fileRemoved) + files.event.register('fileRenamed', fileRenamed) + files.event.register('fileRenamedError', fileRenamedError) + files.event.register('fileAdded', fileAdded) + files.event.register('folderAdded', folderAdded) + + function fileRenamedError (error) { + modalDialogCustom.alert(error) + } + + function fileAdded (filepath) { + self.ensureRoot(() => { + const folderpath = filepath.split('/').slice(0, -1).join('/') + const currentTree = self.treeView.nodeAt(folderpath) + if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) + if (currentTree) { + self.files.resolveDirectory(folderpath, (error, fileTree) => { + if (error) console.error(error) + if (!fileTree) return + fileTree = normalize(folderpath, fileTree) + self.treeView.updateNodeFromJSON(folderpath, fileTree, true) + self.focusElement = self.treeView.labelAt(self.focusPath) + // TODO: here we update the selected file (it applicable) + // cause we are refreshing the interface of the whole directory when there's a new file. + if (self.focusElement && !self.focusElement.classList.contains('bg-secondary')) { + self.focusElement.classList.add('bg-secondary') + } + }) + } + }) + } + + function extractNameFromKey (key) { + const keyPath = key.split('/') + + return keyPath[keyPath.length - 1] + } + + function folderAdded (folderpath) { + self.ensureRoot(() => { + folderpath = folderpath.split('/').slice(0, -1).join('/') + self.files.resolveDirectory(folderpath, (error, fileTree) => { + if (error) console.error(error) + if (!fileTree) return + fileTree = normalize(folderpath, fileTree) + self.treeView.updateNodeFromJSON(folderpath, fileTree, true) + if (!self.treeView.isExpanded(folderpath)) self.treeView.expand(folderpath) + }) + }) + } + + function fileRemoved (filepath) { + const label = self.treeView.labelAt(filepath) + filepath = filepath.split('/').slice(0, -1).join('/') + + if (label && label.parentElement) { + label.parentElement.removeChild(label) + } + + self.updatePath(filepath) + } + + function fileRenamed (oldName, newName, isFolder) { + fileRemoved(oldName) + fileAdded(newName) + } + + // make interface and register to nodeClick, leafClick + self.treeView = new Treeview({ + extractData: function extractData (value, tree, key) { + var newValue = {} + // var isReadOnly = false + var isFile = false + Object.keys(value).filter(function keep (x) { + if (x === '/content') isFile = true + if (x[0] !== '/') return true + }).forEach(function (x) { newValue[x] = value[x] }) + return { + path: (tree || {}).path ? tree.path + '/' + key : key, + children: isFile ? undefined + : value instanceof Array ? value.map((item, index) => ({ + key: index, value: item + })) : value instanceof Object ? Object.keys(value).map(subkey => ({ + key: subkey, value: value[subkey] + })) : undefined + } + }, + formatSelf: function formatSelf (key, data, li) { + const isRoot = data.path === self.files.type + const isFolder = !!data.children + return yo` +
+ + ${key.split('/').pop()} + + ${isRoot ? self.renderMenuItems() : ''} +
+ ` + } + }) + + /** + * Extracts first two folders as a subpath from the path. + **/ + function extractExternalFolder (path) { + const firstSlIndex = path.indexOf('/', 1) + if (firstSlIndex === -1) return '' + const secondSlIndex = path.indexOf('/', firstSlIndex + 1) + if (secondSlIndex === -1) return '' + return path.substring(0, secondSlIndex) + } + + self.treeView.event.register('nodeRightClick', function (key, data, label, event) { + if (self.files.readonly) return + if (key === self.files.type) return + MENU_HANDLE && MENU_HANDLE.hide(null, true) + const actions = {} + const provider = self._deps.fileManager.fileProviderOf(key) + actions['Create File'] = () => self.createNewFile(key) + actions['Create Folder'] = () => self.createNewFolder(key) + // @todo(#2386) not fully implemented. Readd later when fixed + if (provider.isExternalFolder(key)) { + /* actions['Discard changes'] = () => { + modalDialogCustom.confirm( + 'Discard changes', + 'Are you sure you want to discard all your changes?', + () => { self.files.discardChanges(key) }, + () => {} + ) + } */ + } else { + const folderPath = extractExternalFolder(key) + actions.Rename = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot rename folder. ' + self.files.type + ' is a read only explorer') } + var name = label.querySelector('span[data-path="' + key + '"]') + if (name) editModeOn(name) + } + actions.Delete = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot delete folder. ' + self.files.type + ' is a read only explorer') } + const currentFoldername = extractNameFromKey(key) + + modalDialogCustom.confirm('Confirm to delete folder', `Are you sure you want to delete ${currentFoldername} folder?`, + async () => { + const fileManager = self._deps.fileManager + const removeFolder = await fileManager.remove(key) + + if (!removeFolder) { + tooltip(`failed to remove ${key}. Make sure the directory is empty before removing it.`) + } + }, () => {}) + } + if (folderPath === 'browser/gists') { + actions['Push changes to gist'] = () => { + const id = key.substr(key.lastIndexOf('/') + 1, key.length - 1) + modalDialogCustom.confirm( + 'Push back to Gist', + 'Are you sure you want to push all your changes back to Gist?', + () => { self.toGist(id) }, + () => {} + ) + } + } + } + MENU_HANDLE = contextMenu(event, actions) + }) + + self.treeView.event.register('leafRightClick', function (key, data, label, event) { + if (key === self.files.type) return + MENU_HANDLE && MENU_HANDLE.hide(null, true) + const actions = {} + const provider = self._deps.fileManager.fileProviderOf(key) + if (!provider.isExternalFolder(key)) { + actions['Create Folder'] = () => self.createNewFolder(self._deps.fileManager.extractPathOf(key)) + actions.Rename = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot rename file. ' + self.files.type + ' is a read only explorer') } + var name = label.querySelector('span[data-path="' + key + '"]') + if (name) editModeOn(name) + } + actions.Delete = () => { + if (self.files.isReadOnly(key)) { return tooltip('cannot delete file. ' + self.files.type + ' is a read only explorer') } + const currentFilename = extractNameFromKey(key) + + modalDialogCustom.confirm( + 'Delete file', `Are you sure you want to delete ${currentFilename} file?`, + async () => { + const fileManager = self._deps.fileManager + const removeFile = await fileManager.remove(key) + + if (!removeFile) { + tooltip(`Failed to remove file ${key}.`) + } + }, + () => {} + ) + } + if (key.endsWith('.js')) { + actions.Run = async () => { + provider.get(key, (error, content) => { + if (error) return console.log(error) + plugin.call('scriptRunner', 'execute', content) + }) + } + } + } + MENU_HANDLE = contextMenu(event, actions) + }) + + self.treeView.event.register('leafClick', function (key, data, label) { + self.events.trigger('focus', [key]) + }) + + self.treeView.event.register('nodeClick', function (path, childrenContainer) { + if (!childrenContainer) return + if (childrenContainer.style.display === 'none') return + self.updatePath(path) + }) + + // register to main app, trigger when the current file in the editor changed + self._deps.fileManager.events.on('currentFileChanged', (newFile) => { + const provider = self._deps.fileManager.fileProviderOf(newFile) + if (self.focusElement && self.focusPath !== newFile) { + self.focusElement.classList.remove('bg-secondary') + self.focusElement = null + self.focusPath = null + } + if (provider && (provider.type === files.type)) { + self.focusElement = self.treeView.labelAt(newFile) + if (self.focusElement) { + self.focusElement.classList.add('bg-secondary') + self.focusPath = newFile + } + } + }) + + self._deps.fileManager.events.on('noFileSelected', () => { + if (self.focusElement) { + self.focusElement.classList.remove('bg-secondary') + self.focusElement = null + self.focusPath = null + } + }) + + var textUnderEdit = null + + function selectElementContents (el) { + var range = document.createRange() + range.selectNodeContents(el) + var sel = window.getSelection() + sel.removeAllRanges() + sel.addRange(range) + } + + function editModeOn (label) { + textUnderEdit = label.innerText + label.setAttribute('contenteditable', true) + label.classList.add('bg-light') + label.focus() + selectElementContents(label) + } + + function editModeOff (event) { + const label = this + + const isFolder = label.className.indexOf('folder') !== -1 + function rename () { + var newPath = label.dataset.path + newPath = newPath.split('/') + newPath[newPath.length - 1] = label.innerText + newPath = newPath.join('/') + if (label.innerText === '') { + modalDialogCustom.alert('File name cannot be empty') + label.innerText = textUnderEdit + } else if (helper.checkSpecialChars(label.innerText)) { + modalDialogCustom.alert('Special characters are not allowed') + label.innerText = textUnderEdit + } else { + files.exists(newPath, (error, exist) => { + if (error) return modalDialogCustom.alert('Unexpected error while renaming: ' + error) + if (!exist) { + files.rename(label.dataset.path, newPath, isFolder) + } else { + modalDialogCustom.alert('File already exists.') + label.innerText = textUnderEdit + } + }) + } + } + + if (event.which === 13) event.preventDefault() + if ((event.type === 'blur' || event.which === 13) && label.getAttribute('contenteditable')) { + var save = textUnderEdit !== label.innerText + if (save) { + modalDialogCustom.confirm( + 'Confirm to rename a ' + (isFolder ? 'folder' : 'file'), + 'Are you sure you want to rename ' + textUnderEdit + '?', + () => { rename() }, + () => { label.innerText = textUnderEdit } + ) + } + label.removeAttribute('contenteditable') + label.classList.remove('bg-light') + } + } +} + +fileExplorer.prototype.updatePath = function (path) { + this.files.resolveDirectory(path, (error, fileTree) => { + if (error) console.error(error) + if (!fileTree) return + var newTree = normalize(path, fileTree) + this.treeView.updateNodeFromJSON(path, newTree, true) + }) +} + +fileExplorer.prototype.hide = function () { + if (this.container) this.container.style.display = 'none' +} + +fileExplorer.prototype.show = function () { + if (this.container) this.container.style.display = 'block' +} + +fileExplorer.prototype.init = function () { + this.container = yo`
` + return this.container +} + +fileExplorer.prototype.publishToGist = function () { + modalDialogCustom.confirm( + 'Create a public gist', + 'Are you sure you want to publish all your files in browser directory anonymously as a public gist on github.com? Note: this will not include directories.', + () => { this.toGist() } + ) +} + +fileExplorer.prototype.uploadFile = function (event) { + // 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 + // a file and then just use `files.add`. The file explorer will + // pick that up via the 'fileAdded' event from the files module. + + const self = this + + ;[...event.target.files].forEach((file) => { + const files = this.files + function loadFile () { + var fileReader = new FileReader() + fileReader.onload = async function (event) { + if (helper.checkSpecialChars(file.name)) { + modalDialogCustom.alert('Special characters are not allowed') + return + } + var success = await files.set(name, event.target.result) + if (!success) { + modalDialogCustom.alert('Failed to create file ' + name) + } else { + self.events.trigger('focus', [name]) + } + } + fileReader.readAsText(file) + } + var name = files.type + '/' + file.name + files.exists(name, (error, exist) => { + if (error) console.log(error) + if (!exist) { + loadFile() + } else { + modalDialogCustom.confirm('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, () => { loadFile() }) + } + }) + }) +} + +fileExplorer.prototype.toGist = function (id) { + const proccedResult = function (error, data) { + if (error) { + modalDialogCustom.alert('Failed to manage gist: ' + error) + console.log('Failed to manage gist: ' + error) + } else { + if (data.html_url) { + modalDialogCustom.confirm('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, () => { + window.open(data.html_url, '_blank') + }) + } else { + modalDialogCustom.alert(data.message + ' ' + data.documentation_url + ' ' + JSON.stringify(data.errors, null, '\t')) + } + } + } + + /** + * This function is to get the original content of given gist + * @params id is the gist id to fetch + */ + async function getOriginalFiles (id) { + if (!id) { + return [] + } + + const url = `https://api.github.com/gists/${id}` + const res = await fetch(url) + const data = await res.json() + return data.files || [] + } + + // If 'id' is not defined, it is not a gist update but a creation so we have to take the files from the browser explorer. + const folder = id ? '/gists/' + id : '/' + this.packageFiles(this.files, folder, (error, packaged) => { + if (error) { + console.log(error) + modalDialogCustom.alert('Failed to create gist: ' + error.message) + } else { + // check for token + var tokenAccess = this._deps.config.get('settings/gist-access-token') + if (!tokenAccess) { + modalDialogCustom.alert( + 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.' + ) + } else { + const description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&runs=' + queryParams.get().runs + '&gist=' + const gists = new Gists({ token: tokenAccess }) + + if (id) { + const originalFileList = getOriginalFiles(id) + // Telling the GIST API to remove files + const updatedFileList = Object.keys(packaged) + const allItems = Object.keys(originalFileList) + .filter(fileName => updatedFileList.indexOf(fileName) === -1) + .reduce((acc, deleteFileName) => ({ + ...acc, + [deleteFileName]: null + }), originalFileList) + // adding new files + updatedFileList.forEach((file) => { + const _items = file.split('/') + const _fileName = _items[_items.length - 1] + allItems[_fileName] = packaged[file] + }) + + tooltip('Saving gist (' + id + ') ...') + gists.edit({ + description: description, + public: true, + files: allItems, + id: id + }, (error, result) => { + proccedResult(error, result) + if (!error) { + for (const key in allItems) { + if (allItems[key] === null) delete allItems[key] + } + } + }) + } else { + // id is not existing, need to create a new gist + tooltip('Creating a new gist ...') + gists.create({ + description: description, + public: true, + files: packaged + }, (error, result) => { + proccedResult(error, result) + }) + } + } + } + }) +} + +// return all the files, except the temporary/readonly ones.. +fileExplorer.prototype.packageFiles = function (filesProvider, directory, callback) { + const ret = {} + filesProvider.resolveDirectory(directory, (error, files) => { + if (error) callback(error) + else { + async.eachSeries(Object.keys(files), (path, cb) => { + if (filesProvider.isDirectory(path)) { + cb() + } else { + filesProvider.get(path, (error, content) => { + if (error) return cb(error) + if (/^\s+$/.test(content) || !content.length) { + content = '// this line is added to create a gist. Empty file is not allowed.' + } + ret[path] = { content } + cb() + }) + } + }, (error) => { + callback(error, ret) + }) + } + }) +} + +fileExplorer.prototype.createNewFile = function (parentFolder = '/') { + const self = this + modalDialogCustom.prompt('Create new file', 'File Name (e.g Untitled.sol)', 'Untitled.sol', (input) => { + if (!input) input = 'New file' + helper.createNonClashingName(parentFolder + '/' + input, self.files, async (error, newName) => { + if (error) return tooltip('Failed to create file ' + newName + ' ' + error) + const fileManager = self._deps.fileManager + const createFile = await fileManager.writeFile(newName, '') + + if (!createFile) { + tooltip('Failed to create file ' + newName) + } else { + await fileManager.open(newName) + if (newName.includes('_test.sol')) { + self.events.trigger('newTestFileCreated', [newName]) + } + } + }) + }, null, true) +} + +fileExplorer.prototype.createNewFolder = function (parentFolder) { + const self = this + modalDialogCustom.prompt('Create new folder', '', 'New folder', (input) => { + if (!input) { + return tooltip('Failed to create folder. The name can not be empty') + } + + const currentPath = !parentFolder ? self._deps.fileManager.currentPath() : parentFolder + let newName = currentPath ? currentPath + '/' + input : self.files.type + '/' + input + + newName = newName + '/' + self.files.exists(newName, (error, exist) => { + if (error) return tooltip('Unexpected error while creating folder: ' + error) + if (!exist) { + self.files.set(newName, '') + } else { + tooltip('Folder already exists.', () => {}) + } + }) + }, null, true) +} + +fileExplorer.prototype.renderMenuItems = function () { + let items = '' + if (this.menuItems) { + items = this.menuItems.map(({ action, title, icon }) => { + if (action === 'uploadFile') { + return yo` + + ` + } else { + return yo` + { event.stopPropagation(); this[action]() }} + class="newFile ${icon} ${css.newFile}" + title=${title} + > + + ` + } + }) + } + return yo`${items}` +} + +fileExplorer.prototype.ensureRoot = function (cb) { + cb = cb || (() => {}) + var self = this + if (self.element) return cb() + const root = {} + root[this.files.type] = {} + var element = self.treeView.render(root, false) + element.classList.add(css.fileexplorer) + element.events = self.events + element.api = self.api + self.container.appendChild(element) + self.element = element + if (cb) cb() + self.treeView.expand(self.files.type) +} + +function normalize (path, filesList) { + var prefix = path.split('/')[0] + var newList = {} + Object.keys(filesList).forEach(key => { + newList[prefix + '/' + key] = filesList[key].isDirectory ? {} : { '/content': true } + }) + return newList +} + +module.exports = fileExplorer diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index ccc6ad7967..5628425b34 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -4,7 +4,7 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line import ReactDOM from 'react-dom' import { Workspace } from '@remix-ui/workspace' // eslint-disable-line -import * as ethutil from 'ethereumjs-util' +import { bufferToHex, keccakFromString } from 'ethereumjs-util' import { checkSpecialChars, checkSlash } from '../../lib/helper' var EventManager = require('../../lib/events') var { RemixdHandle } = require('../files/remixd-handle.js') @@ -154,7 +154,7 @@ module.exports = class Filepanel extends ViewPlugin { try { await this.processCreateWorkspace('code-sample') this._deps.fileProviders.workspace.setWorkspace('code-sample') - var hash = ethutil.bufferToHex(ethutil.keccak(params.code)) + var hash = bufferToHex(keccakFromString(params.code)) const fileName = 'contract-' + hash.replace('0x', '').substring(0, 10) + '.sol' const path = fileName await this._deps.fileProviders.workspace.set(path, atob(params.code)) @@ -166,16 +166,12 @@ module.exports = class Filepanel extends ViewPlugin { return } // insert example contracts if there are no files to show - return new Promise((resolve, reject) => { - this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { - if (error) console.error(error) - if (Object.keys(filesList).length === 0) { - await this.createWorkspace('default_workspace') - } - const workspaces = await this.getWorkspaces() - - resolve(workspaces) - }) + this._deps.fileProviders.browser.resolveDirectory('/', async (error, filesList) => { + if (error) console.error(error) + if (Object.keys(filesList).length === 0) { + await this.createWorkspace('default_workspace') + } + this.getWorkspaces() }) } diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 09443366b5..c9b00bb099 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -182,8 +182,7 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { - if (extractParentFromKey(filePath) === '/.workspaces') return - const path = extractParentFromKey(filePath) || workspaceName + const path = extractParentFromKey(filePath) ? extractParentFromKey(filePath) === '/.workspaces' ? workspaceName : extractParentFromKey(filePath) : workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) @@ -192,8 +191,7 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp } }) provider.event.register('folderAdded', async (folderPath) => { - if (extractParentFromKey(folderPath) === '/.workspaces') return - const path = extractParentFromKey(folderPath) || workspaceName + const path = extractParentFromKey(folderPath) ? extractParentFromKey(folderPath) === '/.workspaces' ? workspaceName : extractParentFromKey(folderPath) : workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) diff --git a/package-lock.json b/package-lock.json index 13ca34a1d3..d74204bd8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3634,7 +3634,7 @@ "@evocateur/libnpmaccess": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz", - "integrity": "sha1-7Pf2zmsATp+UKwmNkiAL5KSxyEU=", + "integrity": "sha512-KSCAHwNWro0CF2ukxufCitT9K5LjL/KuMmNzSu8wuwN2rjyKHD8+cmOsiybK+W5hdnwc5M1SmRlVCaMHQo+3rg==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3647,13 +3647,13 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha1-UlILiuW1aSFbNU78DKo/4eRaitw=", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3665,7 +3665,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -3673,7 +3673,7 @@ "@evocateur/libnpmpublish": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz", - "integrity": "sha1-Vd8J0tyhNq+6nIjHWconIZjbnxo=", + "integrity": "sha512-MJrrk9ct1FeY9zRlyeoyMieBjGDG9ihyyD9/Ft6MMrTxql9NyoEx2hw9casTIP4CdqEVu+3nQ2nXxoJ8RCXyFg==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3690,13 +3690,13 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha1-UlILiuW1aSFbNU78DKo/4eRaitw=", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3708,7 +3708,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -3716,7 +3716,7 @@ "@evocateur/npm-registry-fetch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@evocateur/npm-registry-fetch/-/npm-registry-fetch-4.0.0.tgz", - "integrity": "sha1-jEw4dm2NMtMgD8sKg/BktXNl7WY=", + "integrity": "sha512-k1WGfKRQyhJpIr+P17O5vLIo2ko1PFLKwoetatdduUSt/aQ4J2sJrJwwatdI5Z3SiYk/mRH9S3JpdmMFd/IK4g==", "dev": true, "requires": { "JSONStream": "^1.3.4", @@ -3731,7 +3731,7 @@ "agentkeepalive": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha1-oROSTdP6JKC8O3gQjEUMKr7gD2c=", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", "dev": true, "requires": { "humanize-ms": "^1.2.1" @@ -3740,13 +3740,13 @@ "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha1-ObDhat2bYFvwqe89nar0hDtMrNI=", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", "dev": true }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha1-TuenN6vZJniik9mzShr00NCMeHs=", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -3756,7 +3756,7 @@ "make-fetch-happen": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha1-qoOHEE8mh+3KAchofuRQE9AtGb0=", + "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", "dev": true, "requires": { "agentkeepalive": "^3.4.1", @@ -3775,7 +3775,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3787,7 +3787,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -3795,7 +3795,7 @@ "@evocateur/pacote": { "version": "9.6.5", "resolved": "https://registry.npmjs.org/@evocateur/pacote/-/pacote-9.6.5.tgz", - "integrity": "sha1-M94yuiELbxfCDrq01JfvxnVfSuU=", + "integrity": "sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -3832,7 +3832,7 @@ "agentkeepalive": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha1-oROSTdP6JKC8O3gQjEUMKr7gD2c=", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", "dev": true, "requires": { "humanize-ms": "^1.2.1" @@ -3841,13 +3841,13 @@ "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha1-ObDhat2bYFvwqe89nar0hDtMrNI=", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", "dev": true }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha1-TuenN6vZJniik9mzShr00NCMeHs=", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -3857,7 +3857,7 @@ "make-fetch-happen": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", - "integrity": "sha1-qoOHEE8mh+3KAchofuRQE9AtGb0=", + "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", "dev": true, "requires": { "agentkeepalive": "^3.4.1", @@ -3876,7 +3876,7 @@ "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha1-5xN2Ln0+Mv7YAxFc+T4EvKn8yaY=", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "requires": { "safe-buffer": "^5.1.2", @@ -3886,7 +3886,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -3898,7 +3898,7 @@ "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -3909,7 +3909,7 @@ "npm-pick-manifest": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz", - "integrity": "sha1-9Nnl/UviFT5fTl+be+jcQZqZq7c=", + "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -3920,7 +3920,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -4604,7 +4604,7 @@ "@lerna/add": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.21.0.tgz", - "integrity": "sha1-JwB73nHMewopaas8LwrkFXi0V3s=", + "integrity": "sha512-vhUXXF6SpufBE1EkNEXwz1VLW03f177G9uMOFMQkp6OJ30/PWg4Ekifuz9/3YfgB2/GH8Tu4Lk3O51P2Hskg/A==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", @@ -4622,7 +4622,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4634,7 +4634,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -4644,7 +4644,7 @@ "@lerna/bootstrap": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.21.0.tgz", - "integrity": "sha1-vNG2Ub5bCXCyDY+uBMhkVIEjrtY=", + "integrity": "sha512-mtNHlXpmvJn6JTu0KcuTTPl2jLsDNud0QacV/h++qsaKbhAaJr/FElNZ5s7MwZFUM3XaDmvWzHKaszeBMHIbBw==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -4675,7 +4675,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4687,7 +4687,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -4697,7 +4697,7 @@ "@lerna/changed": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.21.0.tgz", - "integrity": "sha1-EI4V9nm/4HevUA9YJIxjTxBE6gs=", + "integrity": "sha512-hzqoyf8MSHVjZp0gfJ7G8jaz+++mgXYiNs9iViQGA8JlN/dnWLI5sWDptEH3/B30Izo+fdVz0S0s7ydVE3pWIw==", "dev": true, "requires": { "@lerna/collect-updates": "3.20.0", @@ -4709,7 +4709,7 @@ "@lerna/check-working-tree": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz", - "integrity": "sha1-tPiuYbtFI1Yd+5+PjYdN1Gu0S6o=", + "integrity": "sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==", "dev": true, "requires": { "@lerna/collect-uncommitted": "3.16.5", @@ -4720,7 +4720,7 @@ "@lerna/child-process": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.16.5.tgz", - "integrity": "sha1-OPo8GAZKpKwHVK2AEUd2p7NqabI=", + "integrity": "sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==", "dev": true, "requires": { "chalk": "^2.3.1", @@ -4731,7 +4731,7 @@ "@lerna/clean": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.21.0.tgz", - "integrity": "sha1-wLRrUwDMPa4s2jvsFLgDCC2jhW0=", + "integrity": "sha512-b/L9l+MDgE/7oGbrav6rG8RTQvRiZLO1zTcG17zgJAAuhlsPxJExMlh2DFwJEVi2les70vMhHfST3Ue1IMMjpg==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -4747,7 +4747,7 @@ "@lerna/cli": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.18.5.tgz", - "integrity": "sha1-yQxGFUL801ttWwFaKQ+w2/tB0kI=", + "integrity": "sha512-erkbxkj9jfc89vVs/jBLY/fM0I80oLmJkFUV3Q3wk9J3miYhP14zgVEBsPZY68IZlEjT6T3Xlq2xO1AVaatHsA==", "dev": true, "requires": { "@lerna/global-options": "3.13.0", @@ -4759,13 +4759,13 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha1-3u/P2y6AB4SqNPRvoI4GhRx7u8U=", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", @@ -4776,7 +4776,7 @@ "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" @@ -4785,13 +4785,13 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", @@ -4801,7 +4801,7 @@ "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4810,7 +4810,7 @@ "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" @@ -4819,19 +4819,19 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", @@ -4842,7 +4842,7 @@ "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" @@ -4851,7 +4851,7 @@ "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha1-H9H2cjXVttD+54EFYAG/tpTAOwk=", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", @@ -4862,7 +4862,7 @@ "yargs": { "version": "14.2.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha1-Ghw+3O0a+yov6jNgS8bR2NaIpBQ=", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -4881,7 +4881,7 @@ "yargs-parser": { "version": "15.0.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha1-VHhq9AuCDcsvuAJbEbTWWddjI7M=", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -4893,7 +4893,7 @@ "@lerna/collect-uncommitted": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz", - "integrity": "sha1-pJTWGqwxzceuxLvlLJZVAnQTLmM=", + "integrity": "sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4905,7 +4905,7 @@ "@lerna/collect-updates": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.20.0.tgz", - "integrity": "sha1-YvnXa6IaJbfZ+/McAt6IdEpWS9E=", + "integrity": "sha512-qBTVT5g4fupVhBFuY4nI/3FSJtQVcDh7/gEPOpRxoXB/yCSnT38MFHXWl+y4einLciCjt/+0x6/4AG80fjay2Q==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4918,7 +4918,7 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true } } @@ -4926,7 +4926,7 @@ "@lerna/command": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.21.0.tgz", - "integrity": "sha1-miODdZ3HtwDaz6iiKy86bhkBIfc=", + "integrity": "sha512-T2bu6R8R3KkH5YoCKdutKv123iUgUbW8efVjdGCDnCMthAQzoentOJfDeodBwn0P2OqCl3ohsiNVtSn9h78fyQ==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -4944,7 +4944,7 @@ "@lerna/conventional-commits": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.22.0.tgz", - "integrity": "sha1-J5j0iB7i70V72uAnq30L8K9vHgk=", + "integrity": "sha512-z4ZZk1e8Mhz7+IS8NxHr64wyklHctCJyWpJKEZZPJiLFJ8yKto/x38O80R10pIzC0rr8Sy/OsjSH4bl0TbbgqA==", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -4974,7 +4974,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -4986,7 +4986,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -4994,7 +4994,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } @@ -5002,7 +5002,7 @@ "@lerna/create": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.22.0.tgz", - "integrity": "sha1-1rvQN8PcW0Jf5fbRuBcFfCePdhk=", + "integrity": "sha512-MdiQQzCcB4E9fBF1TyMOaAEz9lUjIHp1Ju9H7f3lXze5JK6Fl5NYkouAvsLgY6YSIhXMY8AHW2zzXeBDY4yWkw==", "dev": true, "requires": { "@evocateur/pacote": "^9.6.3", @@ -5028,13 +5028,13 @@ "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -5080,7 +5080,7 @@ "globby": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", "dev": true, "requires": { "@types/glob": "^7.1.1", @@ -5096,13 +5096,13 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5114,7 +5114,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -5122,13 +5122,13 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true } } @@ -5136,7 +5136,7 @@ "@lerna/create-symlink": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-3.16.2.tgz", - "integrity": "sha1-QSy45Zpy9afZRj5ORyGtIHAUmWc=", + "integrity": "sha512-pzXIJp6av15P325sgiIRpsPXLFmkisLhMBCy4764d+7yjf2bzrJ4gkWVMhsv4AdF0NN3OyZ5jjzzTtLNqfR+Jw==", "dev": true, "requires": { "@zkochan/cmd-shim": "^3.1.0", @@ -5160,7 +5160,7 @@ "@lerna/describe-ref": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.16.5.tgz", - "integrity": "sha1-ozjCWq7YN9PccLinLER8XGY0asA=", + "integrity": "sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5170,7 +5170,7 @@ "@lerna/diff": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.21.0.tgz", - "integrity": "sha1-5t8Ni5kWFn/1pJ/LAqwGQkKApo0=", + "integrity": "sha512-5viTR33QV3S7O+bjruo1SaR40m7F2aUHJaDAC7fL9Ca6xji+aw1KFkpCtVlISS0G8vikUREGMJh+c/VMSc8Usw==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5182,7 +5182,7 @@ "@lerna/exec": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.21.0.tgz", - "integrity": "sha1-F/B1M4k8uRihe0G8xWbcQ3AW2yY=", + "integrity": "sha512-iLvDBrIE6rpdd4GIKTY9mkXyhwsJ2RvQdB9ZU+/NhR3okXfqKc6py/24tV111jqpXTtZUW6HNydT4dMao2hi1Q==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5197,7 +5197,7 @@ "@lerna/filter-options": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.20.0.tgz", - "integrity": "sha1-Dw9dWkeDhW7s5CBHCMyQLLyK9Zs=", + "integrity": "sha512-bmcHtvxn7SIl/R9gpiNMVG7yjx7WyT0HSGw34YVZ9B+3xF/83N3r5Rgtjh4hheLZ+Q91Or0Jyu5O3Nr+AwZe2g==", "dev": true, "requires": { "@lerna/collect-updates": "3.20.0", @@ -5210,7 +5210,7 @@ "@lerna/filter-packages": { "version": "3.18.0", "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.18.0.tgz", - "integrity": "sha1-ano3bShSCNsDqClYz7gXLhebTnA=", + "integrity": "sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==", "dev": true, "requires": { "@lerna/validation-error": "3.13.0", @@ -5221,7 +5221,7 @@ "@lerna/get-npm-exec-opts": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.13.0.tgz", - "integrity": "sha1-0bVSywCIGZ/D5+Em+RTjmgjfnqU=", + "integrity": "sha512-Y0xWL0rg3boVyJk6An/vurKzubyJKtrxYv2sj4bB8Mc5zZ3tqtv0ccbOkmkXKqbzvNNF7VeUt1OJ3DRgtC/QZw==", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -5230,7 +5230,7 @@ "@lerna/get-packed": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-3.16.0.tgz", - "integrity": "sha1-GzFrcG3O6Gx7qlXlCwh5WUR4Uv8=", + "integrity": "sha512-AjsFiaJzo1GCPnJUJZiTW6J1EihrPkc2y3nMu6m3uWFxoleklsSCyImumzVZJssxMi3CPpztj8LmADLedl9kXw==", "dev": true, "requires": { "fs-extra": "^8.1.0", @@ -5254,7 +5254,7 @@ "@lerna/github-client": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/github-client/-/github-client-3.22.0.tgz", - "integrity": "sha1-XYFqpPdnR+1zauZP+WK48Vw1TZU=", + "integrity": "sha512-O/GwPW+Gzr3Eb5bk+nTzTJ3uv+jh5jGho9BOqKlajXaOkMYGBELEAqV5+uARNGWZFvYAiF4PgqHb6aCUu7XdXg==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5267,7 +5267,7 @@ "@lerna/gitlab-client": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/@lerna/gitlab-client/-/gitlab-client-3.15.0.tgz", - "integrity": "sha1-kfTsjGl7WsV/fyW9UP5lnSSqlqY=", + "integrity": "sha512-OsBvRSejHXUBMgwWQqNoioB8sgzL/Pf1pOUhHKtkiMl6aAWjklaaq5HPMvTIsZPfS6DJ9L5OK2GGZuooP/5c8Q==", "dev": true, "requires": { "node-fetch": "^2.5.0", @@ -5278,13 +5278,13 @@ "@lerna/global-options": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.13.0.tgz", - "integrity": "sha1-IXZiKQ2watnPLEnY4xAO4o6uuuE=", + "integrity": "sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ==", "dev": true }, "@lerna/has-npm-version": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz", - "integrity": "sha1-q4OVbyEdiSPqav6bl5s4zHOxUyY=", + "integrity": "sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5294,7 +5294,7 @@ "@lerna/import": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.22.0.tgz", - "integrity": "sha1-Gl8DlPOOI8T2QqEj5eFRfnDQaNI=", + "integrity": "sha512-uWOlexasM5XR6tXi4YehODtH9Y3OZrFht3mGUFFT3OIl2s+V85xIGFfqFGMTipMPAGb2oF1UBLL48kR43hRsOg==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5323,7 +5323,7 @@ "@lerna/info": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/info/-/info-3.21.0.tgz", - "integrity": "sha1-dmlrZ2/bDzXUjIPGPB4yu143gU8=", + "integrity": "sha512-0XDqGYVBgWxUquFaIptW2bYSIu6jOs1BtkvRTWDDhw4zyEdp6q4eaMvqdSap1CG+7wM5jeLCi6z94wS0AuiuwA==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5334,7 +5334,7 @@ "@lerna/init": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.21.0.tgz", - "integrity": "sha1-HoEJNNyL9OU4bAMQQYgdO0CWqlw=", + "integrity": "sha512-6CM0z+EFUkFfurwdJCR+LQQF6MqHbYDCBPyhu/d086LRf58GtYZYj49J8mKG9ktayp/TOIxL/pKKjgLD8QBPOg==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5360,7 +5360,7 @@ "@lerna/link": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.21.0.tgz", - "integrity": "sha1-i+aP8MzuEEsXS1u9YGMCwvBunZs=", + "integrity": "sha512-tGu9GxrX7Ivs+Wl3w1+jrLi1nQ36kNI32dcOssij6bg0oZ2M2MDEFI9UF2gmoypTaN9uO5TSsjCFS7aR79HbdQ==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5373,7 +5373,7 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true } } @@ -5381,7 +5381,7 @@ "@lerna/list": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.21.0.tgz", - "integrity": "sha1-Qvdvr6Vt6hO2keyMqxODJpHWHaI=", + "integrity": "sha512-KehRjE83B1VaAbRRkRy6jLX1Cin8ltsrQ7FHf2bhwhRHK0S54YuA6LOoBnY/NtA8bHDX/Z+G5sMY78X30NS9tg==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -5393,7 +5393,7 @@ "@lerna/listable": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.18.5.tgz", - "integrity": "sha1-6CeYQFte2PxRhDyO8eeg5Jc4iho=", + "integrity": "sha512-Sdr3pVyaEv5A7ZkGGYR7zN+tTl2iDcinryBPvtuv20VJrXBE8wYcOks1edBTcOWsPjCE/rMP4bo1pseyk3UTsg==", "dev": true, "requires": { "@lerna/query-graph": "3.18.5", @@ -5404,7 +5404,7 @@ "@lerna/log-packed": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-3.16.0.tgz", - "integrity": "sha1-+DmRBB7neySVY04URwtCJZ/SvBY=", + "integrity": "sha512-Fp+McSNBV/P2mnLUYTaSlG8GSmpXM7krKWcllqElGxvAqv6chk2K3c2k80MeVB4WvJ9tRjUUf+i7HUTiQ9/ckQ==", "dev": true, "requires": { "byte-size": "^5.0.1", @@ -5416,7 +5416,7 @@ "@lerna/npm-conf": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.16.0.tgz", - "integrity": "sha1-HBComuL2wu6WliVXc4aFMA03aCc=", + "integrity": "sha512-HbO3DUrTkCAn2iQ9+FF/eisDpWY5POQAOF1m7q//CZjdC2HSW3UYbKEGsSisFxSfaF9Z4jtrV+F/wX6qWs3CuA==", "dev": true, "requires": { "config-chain": "^1.1.11", @@ -5426,7 +5426,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } @@ -5434,7 +5434,7 @@ "@lerna/npm-dist-tag": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.5.tgz", - "integrity": "sha1-nvmrt8EEB3sx9vqyLMc7MU1UrFU=", + "integrity": "sha512-xw0HDoIG6HreVsJND9/dGls1c+lf6vhu7yJoo56Sz5bvncTloYGLUppIfDHQr4ZvmPCK8rsh0euCVh2giPxzKQ==", "dev": true, "requires": { "@evocateur/npm-registry-fetch": "^4.0.0", @@ -5447,7 +5447,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5459,7 +5459,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -5467,7 +5467,7 @@ "@lerna/npm-install": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.16.5.tgz", - "integrity": "sha1-1r/cFvgShdpmUVrkeSTW4njWN9M=", + "integrity": "sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5493,7 +5493,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5505,7 +5505,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -5513,7 +5513,7 @@ "@lerna/npm-publish": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.18.5.tgz", - "integrity": "sha1-JA5AOZWf2YFrScWwdCHhG1ywAK8=", + "integrity": "sha512-3etLT9+2L8JAx5F8uf7qp6iAtOLSMj+ZYWY6oUgozPi/uLqU0/gsMsEXh3F0+YVW33q0M61RpduBoAlOOZnaTg==", "dev": true, "requires": { "@evocateur/libnpmpublish": "^1.2.2", @@ -5541,7 +5541,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5553,13 +5553,13 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -5567,7 +5567,7 @@ "@lerna/npm-run-script": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz", - "integrity": "sha1-nC7IJFOibAtG7cC7fBWBbIIfXBU=", + "integrity": "sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -5578,7 +5578,7 @@ "@lerna/otplease": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/otplease/-/otplease-3.18.5.tgz", - "integrity": "sha1-t3uOdgtAq62fdljZiPPqd9T9AjE=", + "integrity": "sha512-S+SldXAbcXTEDhzdxYLU0ZBKuYyURP/ND2/dK6IpKgLxQYh/z4ScljPDMyKymmEvgiEJmBsPZAAPfmNPEzxjog==", "dev": true, "requires": { "@lerna/prompt": "3.18.5", @@ -5588,7 +5588,7 @@ "@lerna/output": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/output/-/output-3.13.0.tgz", - "integrity": "sha1-Pe18yQiyephyIopjDZUK7a56SYk=", + "integrity": "sha512-7ZnQ9nvUDu/WD+bNsypmPG5MwZBwu86iRoiW6C1WBuXXDxM5cnIAC1m2WxHeFnjyMrYlRXM9PzOQ9VDD+C15Rg==", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -5597,7 +5597,7 @@ "@lerna/pack-directory": { "version": "3.16.4", "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.16.4.tgz", - "integrity": "sha1-Pq5fkb31rP4DhFEO1T+t3EwHRpM=", + "integrity": "sha512-uxSF0HZeGyKaaVHz5FroDY9A5NDDiCibrbYR6+khmrhZtY0Bgn6hWq8Gswl9iIlymA+VzCbshWIMX4o2O8C8ng==", "dev": true, "requires": { "@lerna/get-packed": "3.16.0", @@ -5613,7 +5613,7 @@ "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha1-Vu5swTW5+YrT1Rwcldoiu7my7z4=", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "dev": true, "requires": { "ignore-walk": "^3.0.1", @@ -5626,7 +5626,7 @@ "@lerna/package": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/package/-/package-3.16.0.tgz", - "integrity": "sha1-fgpG5Gl+2LipwU1Zx/iQ4NOLoTw=", + "integrity": "sha512-2lHBWpaxcBoiNVbtyLtPUuTYEaB/Z+eEqRS9duxpZs6D+mTTZMNy6/5vpEVSCBmzvdYpyqhqaYjjSLvjjr5Riw==", "dev": true, "requires": { "load-json-file": "^5.3.0", @@ -5637,7 +5637,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -5650,7 +5650,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5662,19 +5662,19 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "dev": true } } @@ -5682,7 +5682,7 @@ "@lerna/package-graph": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.18.5.tgz", - "integrity": "sha1-x0Di6jV40FnlUWM+lQaQgxuUH2s=", + "integrity": "sha512-8QDrR9T+dBegjeLr+n9WZTVxUYUhIUjUgZ0gvNxUBN8S1WB9r6H5Yk56/MVaB64tA3oGAN9IIxX6w0WvTfFudA==", "dev": true, "requires": { "@lerna/prerelease-id-from-version": "3.16.0", @@ -5695,7 +5695,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5707,7 +5707,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -5717,7 +5717,7 @@ "@lerna/prerelease-id-from-version": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-3.16.0.tgz", - "integrity": "sha1-skv6eJ9eG6q5FNewi6rpt719g6E=", + "integrity": "sha512-qZyeUyrE59uOK8rKdGn7jQz+9uOpAaF/3hbslJVFL1NqF9ELDTqjCPXivuejMX/lN4OgD6BugTO4cR7UTq/sZA==", "dev": true, "requires": { "semver": "^6.2.0" @@ -5726,7 +5726,7 @@ "@lerna/profiler": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-3.20.0.tgz", - "integrity": "sha1-D23CNvTqj56l81jGcDMFpPMq0FE=", + "integrity": "sha512-bh8hKxAlm6yu8WEOvbLENm42i2v9SsR4WbrCWSbsmOElx3foRnMlYk7NkGECa+U5c3K4C6GeBbwgqs54PP7Ljg==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -5751,7 +5751,7 @@ "@lerna/project": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.21.0.tgz", - "integrity": "sha1-XXhNLRDFYaAPIDILzbBAmXwQUC0=", + "integrity": "sha512-xT1mrpET2BF11CY32uypV2GPtPVm6Hgtha7D81GQP9iAitk9EccrdNjYGt5UBYASl4CIDXBRxwmTTVGfrCx82A==", "dev": true, "requires": { "@lerna/package": "3.16.0", @@ -5771,13 +5771,13 @@ "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha1-BA9yaAnFked6F8CjYmykW08Wixo=", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { "import-fresh": "^2.0.0", @@ -5789,7 +5789,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -5798,7 +5798,7 @@ "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", "dev": true, "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", @@ -5835,7 +5835,7 @@ "globby": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", "dev": true, "requires": { "@types/glob": "^7.1.1", @@ -5851,7 +5851,7 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "import-fresh": { @@ -5881,7 +5881,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -5894,25 +5894,25 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "dev": true } } @@ -5920,7 +5920,7 @@ "@lerna/prompt": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-3.18.5.tgz", - "integrity": "sha1-YozVRfIliH0GBJGrld+JnPxSGKE=", + "integrity": "sha512-rkKj4nm1twSbBEb69+Em/2jAERK8htUuV8/xSjN0NPC+6UjzAwY52/x9n5cfmpa9lyKf/uItp7chCI7eDmNTKQ==", "dev": true, "requires": { "inquirer": "^6.2.0", @@ -5930,7 +5930,7 @@ "@lerna/publish": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.22.1.tgz", - "integrity": "sha1-tPfOP7oemvsovkofPYgiImm6lRk=", + "integrity": "sha512-PG9CM9HUYDreb1FbJwFg90TCBQooGjj+n/pb3gw/eH5mEDq0p8wKdLFe0qkiqUkm/Ub5C8DbVFertIo0Vd0zcw==", "dev": true, "requires": { "@evocateur/libnpmaccess": "^3.1.2", @@ -5979,7 +5979,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -5991,7 +5991,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -6001,7 +6001,7 @@ "@lerna/pulse-till-done": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-3.13.0.tgz", - "integrity": "sha1-yOnOW6+vENkwpn1+0My12Vj+ARA=", + "integrity": "sha512-1SOHpy7ZNTPulzIbargrgaJX387csN7cF1cLOGZiJQA6VqnS5eWs2CIrG8i8wmaUavj2QlQ5oEbRMVVXSsGrzA==", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -6010,7 +6010,7 @@ "@lerna/query-graph": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/query-graph/-/query-graph-3.18.5.tgz", - "integrity": "sha1-30gwu1FVJzADvzXo3aHDLQknvYY=", + "integrity": "sha512-50Lf4uuMpMWvJ306be3oQDHrWV42nai9gbIVByPBYJuVW8dT8O8pA3EzitNYBUdLL9/qEVbrR0ry1HD7EXwtRA==", "dev": true, "requires": { "@lerna/package-graph": "3.18.5", @@ -6020,7 +6020,7 @@ "@lerna/resolve-symlink": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-3.16.0.tgz", - "integrity": "sha1-N/xwlfq9vPMXwm63Tg0L3o79I4Y=", + "integrity": "sha512-Ibj5e7njVHNJ/NOqT4HlEgPFPtPLWsO7iu59AM5bJDcAJcR96mLZ7KGVIsS2tvaO7akMEJvt2P+ErwCdloG3jQ==", "dev": true, "requires": { "fs-extra": "^8.1.0", @@ -6044,7 +6044,7 @@ "@lerna/rimraf-dir": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz", - "integrity": "sha1-BDFqtf/SkJZXqvOI6lAsuMLyCgk=", + "integrity": "sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==", "dev": true, "requires": { "@lerna/child-process": "3.16.5", @@ -6056,7 +6056,7 @@ "@lerna/run": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.21.0.tgz", - "integrity": "sha1-KjXshJeeTW5CR0/hSNMuXeHKyJE=", + "integrity": "sha512-fJF68rT3veh+hkToFsBmUJ9MHc9yGXA7LSDvhziAojzOb0AI/jBDp6cEcDQyJ7dbnplba2Lj02IH61QUf9oW0Q==", "dev": true, "requires": { "@lerna/command": "3.21.0", @@ -6073,7 +6073,7 @@ "@lerna/run-lifecycle": { "version": "3.16.2", "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.16.2.tgz", - "integrity": "sha1-Z7KI+OqWTbnqT7H7x3FdW7sLzgA=", + "integrity": "sha512-RqFoznE8rDpyyF0rOJy3+KjZCeTkO8y/OB9orPauR7G2xQ7PTdCpgo7EO6ZNdz3Al+k1BydClZz/j78gNCmL2A==", "dev": true, "requires": { "@lerna/npm-conf": "3.16.0", @@ -6085,7 +6085,7 @@ "@lerna/run-topologically": { "version": "3.18.5", "resolved": "https://registry.npmjs.org/@lerna/run-topologically/-/run-topologically-3.18.5.tgz", - "integrity": "sha1-PNY52iDpZ9dnLLiNsPdWuS8v38M=", + "integrity": "sha512-6N1I+6wf4hLOnPW+XDZqwufyIQ6gqoPfHZFkfWlvTQ+Ue7CuF8qIVQ1Eddw5HKQMkxqN10thKOFfq/9NQZ4NUg==", "dev": true, "requires": { "@lerna/query-graph": "3.18.5", @@ -6096,13 +6096,13 @@ "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha1-LT1I+cNGaY/Og6hdfWZOmFNd9uc=", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", "dev": true }, "p-queue": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-4.0.0.tgz", - "integrity": "sha1-7Q7uh5iSftbywvX1t3/bIGGl00Y=", + "integrity": "sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==", "dev": true, "requires": { "eventemitter3": "^3.1.0" @@ -6113,7 +6113,7 @@ "@lerna/symlink-binary": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz", - "integrity": "sha1-j4AxswmGOBSIPT8AmHf4Ljiu9Fo=", + "integrity": "sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -6138,7 +6138,7 @@ "@lerna/symlink-dependencies": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz", - "integrity": "sha1-SNY2DphYZaDlbNi1GzCKUmMIeEo=", + "integrity": "sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==", "dev": true, "requires": { "@lerna/create-symlink": "3.16.2", @@ -6166,13 +6166,13 @@ "@lerna/timer": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-3.13.0.tgz", - "integrity": "sha1-vNCQRVHbFuCDZNbBjl4hYPyHB4E=", + "integrity": "sha512-RHWrDl8U4XNPqY5MQHkToWS9jHPnkLZEt5VD+uunCKTfzlxGnRCr3/zVr8VGy/uENMYpVP3wJa4RKGY6M0vkRw==", "dev": true }, "@lerna/validation-error": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-3.13.0.tgz", - "integrity": "sha1-yGuPB8WrlTn3db2KVJdukm83WcM=", + "integrity": "sha512-SiJP75nwB8GhgwLKQfdkSnDufAaCbkZWJqEDlKOUPUvVOplRGnfL+BPQZH5nvq2BYSRXsksXWZ4UHVnQZI/HYA==", "dev": true, "requires": { "npmlog": "^4.1.2" @@ -6181,7 +6181,7 @@ "@lerna/version": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.22.1.tgz", - "integrity": "sha1-mAWpJHpH7mLWuBvZ+l+3KLJLWeI=", + "integrity": "sha512-PSGt/K1hVqreAFoi3zjD0VEDupQ2WZVlVIwesrE5GbrL2BjXowjCsTDPqblahDUPy0hp6h7E2kG855yLTp62+g==", "dev": true, "requires": { "@lerna/check-working-tree": "3.16.5", @@ -6215,7 +6215,7 @@ "load-json-file": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha1-TTweAfocA+p4pgrHr5MsnOU0A/M=", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -6228,19 +6228,19 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha1-Y9ANIE4FlHT+Xht8ARESu9HcKeE=", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "dev": true } } @@ -6248,7 +6248,7 @@ "@lerna/write-log-file": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-3.13.0.tgz", - "integrity": "sha1-t42eTPwTSai+ZNkTJMTIGZ6CKiY=", + "integrity": "sha512-RibeMnDPvlL8bFYW5C8cs4mbI3AHfQef73tnJCQ/SgrXZHehmHnsyWUiE7qDQCAo+B1RfTapvSyFF69iPj326A==", "dev": true, "requires": { "npmlog": "^4.1.2", @@ -6258,7 +6258,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -6271,7 +6271,7 @@ "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", "dev": true, "requires": { "call-me-maybe": "^1.0.1", @@ -7452,7 +7452,7 @@ "@octokit/auth-token": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", - "integrity": "sha1-ENCul5sQD6a3L6Do5j4n5tDb/4o=", + "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", "dev": true, "requires": { "@octokit/types": "^5.0.0" @@ -7461,7 +7461,7 @@ "@octokit/endpoint": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.5.tgz", - "integrity": "sha1-Q6at7oE8X/0vcZ4gz9FKH+58GTo=", + "integrity": "sha512-70K5u6zd45ItOny6aHQAsea8HHQjlQq85yqOMe+Aj8dkhN2qSJ9T+Q3YjUjEYfPRBcuUWNgMn62DQnP/4LAIiQ==", "dev": true, "requires": { "@octokit/types": "^5.0.0", @@ -7472,13 +7472,13 @@ "is-plain-object": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha1-GhTWRSy9UHkO3H/aoK7VpAo167U=", + "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", "dev": true }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha1-M4H4UDslHA2c0hvB3pOeyd9UgO4=", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", "dev": true } } @@ -7486,13 +7486,13 @@ "@octokit/plugin-enterprise-rest": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", - "integrity": "sha1-4HiWc5YY2rjafUB3xlgAN3X5VDc=", + "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", "dev": true }, "@octokit/plugin-paginate-rest": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha1-AEFwrPjCvlNauiZyeGfWkve0iPw=", + "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", "dev": true, "requires": { "@octokit/types": "^2.0.1" @@ -7501,7 +7501,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", "dev": true, "requires": { "@types/node": ">= 8" @@ -7512,13 +7512,13 @@ "@octokit/plugin-request-log": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz", - "integrity": "sha1-7vh6QxMA9hSMOaf3X4z+shiyVH4=", + "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==", "dev": true }, "@octokit/plugin-rest-endpoint-methods": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha1-Mojs9UgfaMSU3QYC/BVAeln69h4=", + "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", "dev": true, "requires": { "@octokit/types": "^2.0.1", @@ -7528,7 +7528,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", "dev": true, "requires": { "@types/node": ">= 8" @@ -7539,7 +7539,7 @@ "@octokit/request": { "version": "5.4.7", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.7.tgz", - "integrity": "sha1-/XA+4JLgRjzrpJ/3o+YctM+KD94=", + "integrity": "sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", @@ -7555,7 +7555,7 @@ "@octokit/request-error": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", - "integrity": "sha1-Dna4P12P3aHbmQJ+pfYXwua6ntA=", + "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", "dev": true, "requires": { "@octokit/types": "^5.0.1", @@ -7566,13 +7566,13 @@ "is-plain-object": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha1-GhTWRSy9UHkO3H/aoK7VpAo167U=", + "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", "dev": true }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha1-M4H4UDslHA2c0hvB3pOeyd9UgO4=", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", "dev": true } } @@ -7580,7 +7580,7 @@ "@octokit/request-error": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", - "integrity": "sha1-7eBxTHc/MjR1dsJWSdwBOuazGAE=", + "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", "dev": true, "requires": { "@octokit/types": "^2.0.0", @@ -7591,7 +7591,7 @@ "@octokit/types": { "version": "2.16.2", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz", - "integrity": "sha1-TF+No8b+zz2hgRrvZ4/aA+2sNdI=", + "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==", "dev": true, "requires": { "@types/node": ">= 8" @@ -7602,7 +7602,7 @@ "@octokit/rest": { "version": "16.43.2", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.2.tgz", - "integrity": "sha1-xTQm8eHRBE3ulnAj4yecUJk92Rs=", + "integrity": "sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.0", @@ -7626,7 +7626,7 @@ "@octokit/types": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.2.0.tgz", - "integrity": "sha1-0HXcI78pP1QHOSULaHniwb4vwgw=", + "integrity": "sha512-XjOk9y4m8xTLIKPe1NFxNWBdzA2/z3PFFA/bwf4EoH6oS8hM0Y46mEa4Cb+KCyj/tFDznJFahzQ0Aj3o1FYq4A==", "dev": true, "requires": { "@types/node": ">= 8" @@ -7719,12 +7719,12 @@ "@restart/context": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", - "integrity": "sha1-qZ2HwpmjTCi9hbtInLB7/SMUnAI=" + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==" }, "@restart/hooks": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.25.tgz", - "integrity": "sha1-EQBBOa0ccNL1llqJOdy1rrlqplI=", + "integrity": "sha512-m2v3N5pxTsIiSH74/sb1yW8D9RxkJidGW+5Mfwn/lHb2QzhZNlaU1su7abSyT9EGf0xS/0waLjrf7/XxQHUk7w==", "requires": { "lodash": "^4.17.15", "lodash-es": "^4.17.15" @@ -8244,7 +8244,7 @@ "@types/invariant": { "version": "2.2.34", "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz", - "integrity": "sha1-BeT3n0ZcIAeIQ3TUeVRS+ZVyC74=" + "integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg==" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -8423,7 +8423,7 @@ "@types/react-transition-group": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz", - "integrity": "sha1-iCg520Zd8TIOR1Pm6fcMp+m01G0=", + "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==", "requires": { "@types/react": "*" } @@ -8942,7 +8942,7 @@ "@zkochan/cmd-shim": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@zkochan/cmd-shim/-/cmd-shim-3.1.0.tgz", - "integrity": "sha1-KrjtgfW7VFKoXyV1jrm4aBmC/S4=", + "integrity": "sha512-o8l0+x7C7sMZU3v9GuJIAU10qQLtwR1dtRQIOmlNMtyaqhmpXOzx1HWiYoWfmmf9HHZoAkXpc9TM9PQYF9d4Jg==", "dev": true, "requires": { "is-windows": "^1.0.0", @@ -9430,7 +9430,7 @@ "array-differ": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha1-S5wcPxS5BnVwgpJXaeirkE9IAbE=", + "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", "dev": true }, "array-each": { @@ -10001,7 +10001,7 @@ "babel-jest": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", - "integrity": "sha1-IGCTrDgKS3jEQEoFsydzkSePgPs=", + "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", "dev": true, "requires": { "@jest/transform": "^25.1.0", @@ -10026,7 +10026,7 @@ "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -10036,7 +10036,7 @@ "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -10045,25 +10045,25 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -11160,7 +11160,7 @@ "before-after-hook": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", - "integrity": "sha1-tsA0h/ROJCAN0wyl5qGXnF0vtjU=", + "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", "dev": true }, "big.js": { @@ -12523,7 +12523,7 @@ "byte-size": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-5.0.1.tgz", - "integrity": "sha1-S2UQOaXs2Wdn5xo9ftOA5IvtQZE=", + "integrity": "sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==", "dev": true }, "bytes": { @@ -12674,7 +12674,7 @@ "camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha1-XnVda6UaoiPsfT1S8ld4IQ+dw8A=", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -13018,7 +13018,7 @@ "classnames": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha1-Q5Nb/90pHzJtrQogUwmzjQD2UM4=" + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" }, "clean-css": { "version": "4.2.1", @@ -13418,7 +13418,7 @@ "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha1-xQclrzgIyKsCYP1gsB+/oluVT2k=", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", "dev": true }, "commander": { @@ -13441,7 +13441,7 @@ "compare-func": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz", - "integrity": "sha1-awfExeg0ERm69EV4CFvaD0qCNRY=", + "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==", "dev": true, "requires": { "array-ify": "^1.0.0", @@ -13699,7 +13699,7 @@ "conventional-changelog-angular": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz", - "integrity": "sha1-XPewDdMVtqalWCI8gNXvJN2zQgU=", + "integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -13709,7 +13709,7 @@ "conventional-changelog-core": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.2.3.tgz", - "integrity": "sha1-sxQQhW9DHIRwhqfctNLKGEp9iPs=", + "integrity": "sha512-LMMX1JlxPIq/Ez5aYAYS5CpuwbOk6QFp8O4HLAcZxe3vxoCtABkhfjetk8IYdRB9CDQGwJFLR3Dr55Za6XKgUQ==", "dev": true, "requires": { "conventional-changelog-writer": "^4.0.6", @@ -13751,7 +13751,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13763,13 +13763,13 @@ "conventional-changelog-preset-loader": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", - "integrity": "sha1-FKhVq7/9WQJ/1gJYHx802YYupEw=", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true }, "conventional-changelog-writer": { "version": "4.0.16", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz", - "integrity": "sha1-yhDyaRqOptPC63S9Nbz0CqBS3aU=", + "integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==", "dev": true, "requires": { "compare-func": "^1.3.1", @@ -13787,7 +13787,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13799,7 +13799,7 @@ "conventional-commits-filter": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", - "integrity": "sha1-CTXhJAxcp2mDKa/+4bakbTMyTEw=", + "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", @@ -13809,7 +13809,7 @@ "conventional-commits-parser": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", - "integrity": "sha1-EBQGc9Xn71VyYzeRRWxdA7aei+Q=", + "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", "dev": true, "requires": { "JSONStream": "^1.0.4", @@ -13824,7 +13824,7 @@ "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha1-mfiJMc/HYex2eLQdXXM2tbage/Q=", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, "requires": { "inherits": "^2.0.4", @@ -13836,7 +13836,7 @@ "conventional-recommended-bump": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-5.0.1.tgz", - "integrity": "sha1-WvY5A5R7bgied3Z2ActZLKuxBro=", + "integrity": "sha512-RVdt0elRcCxL90IrNP0fYCpq1uGt2MALko0eyeQ+zQuDVWtMGAy9ng6yYn3kax42lCj9+XBxQ8ZN6S9bdKxDhQ==", "dev": true, "requires": { "concat-stream": "^2.0.0", @@ -13869,7 +13869,7 @@ "concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha1-QUz1r3kKSMYKub5FJ9VtXkETPLE=", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -13893,7 +13893,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -13910,7 +13910,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -14875,7 +14875,7 @@ "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha1-puN0maTZqc+F71hyBE1ikByYia4=", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, "deasync": { @@ -15399,7 +15399,7 @@ "deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha1-Y2jL20Cr8zc7UlrIfkomDDpwCRk=", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", "dev": true }, "deps-sort": { @@ -15564,7 +15564,7 @@ "dom-helpers": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", - "integrity": "sha1-V/0FTF+PNMUqPu/9t+fpPNNX2Vs=", + "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", "requires": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" @@ -17392,7 +17392,7 @@ "express-ws": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-4.0.0.tgz", - "integrity": "sha1-2r2NyXRRZBiQKkH+bjDtlJtNNsQ=", + "integrity": "sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw==", "requires": { "ws": "^5.2.0" }, @@ -17400,7 +17400,7 @@ "ws": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha1-3/7xSGa46NyRM1glFNG++vlumA8=", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "requires": { "async-limiter": "~1.0.0" } @@ -19127,7 +19127,7 @@ "genfun": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha1-ndlxCgaQClxKW/V6yl2k5S/nZTc=", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", "dev": true }, "gensync": { @@ -19355,7 +19355,7 @@ "get-port": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha1-43Nosehjt2KcQ8WjI2Jflc8ksRk=", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", "dev": true }, "get-stdin": { @@ -19481,7 +19481,7 @@ "git-raw-commits": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", - "integrity": "sha1-2Srd90RAwUvMXIPszj+3+KeRGLU=", + "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", "dev": true, "requires": { "dargs": "^4.0.1", @@ -19523,7 +19523,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -19540,7 +19540,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -19619,7 +19619,7 @@ "git-semver-tags": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.3.tgz", - "integrity": "sha1-SJiKcYrPWTgA+ZYiqVKnfEBb+jQ=", + "integrity": "sha512-tj4FD4ww2RX2ae//jSrXZzrocla9db5h0V7ikPl1P/WwoZar9epdUhwR7XHXSgc+ZkNq72BEEerqQuicoEQfzA==", "dev": true, "requires": { "meow": "^4.0.0", @@ -19658,7 +19658,7 @@ "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha1-1IWY9vSxRy81v2MXqVlFrONH+XU=", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", "dev": true, "requires": { "camelcase-keys": "^4.0.0", @@ -19675,7 +19675,7 @@ "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha1-+6TIGRM54T7PTWG+sD8HAQPz2VQ=", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -19736,7 +19736,7 @@ "git-up": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz", - "integrity": "sha1-yy7whmU2QOch0gQv4xBIV9iQB8A=", + "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -19746,7 +19746,7 @@ "git-url-parse": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.1.2.tgz", - "integrity": "sha1-r/Gol8NsyTaZJwWHvqPby7uV3mc=", + "integrity": "sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ==", "dev": true, "requires": { "git-up": "^4.0.0" @@ -20543,7 +20543,7 @@ "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha1-1MBcG6+Q6ZRfd6pop6IZqkp9904=", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "dev": true, "requires": { "minimist": "^1.2.5", @@ -20556,13 +20556,13 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "uglify-js": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz", - "integrity": "sha1-OXp+bjHOggv9HLVbgE7hQMWHqec=", + "integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==", "dev": true, "optional": true }, @@ -20591,7 +20591,7 @@ "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha1-HG7aXBaFxjlCdm15u0Cudzzs2IM=", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, "harmony-reflect": { @@ -21221,7 +21221,7 @@ "init-package-json": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.10.3.tgz", - "integrity": "sha1-Rf/i9hCoyhNPK9HbVjeyNQcPbL4=", + "integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==", "dev": true, "requires": { "glob": "^7.1.1", @@ -21237,7 +21237,7 @@ "npm-package-arg": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.1.tgz", - "integrity": "sha1-AhaMsKSaK3W/mIooaY3ntSnfXLc=", + "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==", "dev": true, "requires": { "hosted-git-info": "^2.7.1", @@ -21249,7 +21249,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -22051,7 +22051,7 @@ "is-ssh": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", - "integrity": "sha1-80moyt0k5lKYA3pSLPdSDy6BoPM=", + "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", "dev": true, "requires": { "protocols": "^1.1.0" @@ -24750,7 +24750,7 @@ "lerna": { "version": "3.22.1", "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.22.1.tgz", - "integrity": "sha1-ggJ6w9qcYn/YvwLM/v+AapjmW2I=", + "integrity": "sha512-vk1lfVRFm+UuEFA7wkLKeSF7Iz13W+N/vFd48aW2yuS7Kv0RbNm2/qcDPV863056LMfkRlsEe+QYOw3palj5Lg==", "dev": true, "requires": { "@lerna/add": "3.21.0", @@ -25146,7 +25146,7 @@ "lodash-es": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz", - "integrity": "sha1-Ib2Wg5NUQS8j16EDQOXqxu5FXXg=" + "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==" }, "lodash._arraycopy": { "version": "3.0.0", @@ -25317,7 +25317,7 @@ "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha1-+XYZXPPzR9DV9SSDVp/oAxzM6Ks=", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0", @@ -25327,7 +25327,7 @@ "lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha1-5IExDwSdPPbUfpEq0JMTsVTw+zM=", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0" @@ -25519,7 +25519,7 @@ "macos-release": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.4.1.tgz", - "integrity": "sha1-ZAM9Dsal5jdRVadLGh66jlCYIKw=", + "integrity": "sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==", "dev": true }, "magic-string": { @@ -25779,7 +25779,7 @@ "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha1-uRIhtUJzS58UJWwBMsiXxdclb9U=", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "map-visit": { @@ -25968,7 +25968,7 @@ "meow": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha1-HtSgpQs4RLRRNpxINi6wUV8Ewdw=", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -25989,19 +25989,19 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, "camelcase": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha1-Uln3ww414njxvcKk2RIws3ytmB4=", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", @@ -26011,7 +26011,7 @@ "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" @@ -26020,7 +26020,7 @@ "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE=", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -26029,7 +26029,7 @@ "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha1-o0KLtwiLOmApL2aRkni3wpetTwc=", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" @@ -26038,13 +26038,13 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-json": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha1-fP41wczWQbzjmBRn5sLs5hs7OHg=", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -26056,13 +26056,13 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha1-e/KVQ4yloz5WzTDgU7NO5yUMk8w=", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", @@ -26074,7 +26074,7 @@ "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha1-jSojcNPfiG61yQraHFv2GIrPg4s=", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true } } @@ -26082,7 +26082,7 @@ "read-pkg-up": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha1-86YTV1hFlzOuK5VjgFbhhU5+9Qc=", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { "find-up": "^4.1.0", @@ -26093,7 +26093,7 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } @@ -26101,13 +26101,13 @@ "type-fest": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha1-AXLLW86AsL1ULqNI21DH4hg02TQ=", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true }, "yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha1-vmjEl1xrKr9GkjawyHA2L6sJp7A=", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -26117,7 +26117,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true } } @@ -26392,7 +26392,7 @@ "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha1-pj9oFnOzBXH76LwlaGrnRu76mGk=", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, "mini-css-extract-plugin": { @@ -26452,7 +26452,7 @@ "minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha1-wGVXE8U6ii69d/+iR9NCxA8BBhk=", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", @@ -26961,7 +26961,7 @@ "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha1-s5OfpgVUZHTj4+PGPWS9Q7TuYCI=", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true }, "module-deps": { @@ -27193,7 +27193,7 @@ "multimatch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", - "integrity": "sha1-DiU0zGvCONmrZ+G5zV/Nhabb9ws=", + "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", "dev": true, "requires": { "array-differ": "^2.0.3", @@ -27229,7 +27229,7 @@ "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha1-lQCAV6Vsr63CvGPd5/n/aVWUjjI=", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, "requires": { "any-promise": "^1.0.0", @@ -27758,12 +27758,12 @@ "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0=" + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "node-fetch-npm": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", - "integrity": "sha1-ZQfQ4XqewL477FFpWKSXzsVL9aQ=", + "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", "dev": true, "requires": { "encoding": "^0.1.11", @@ -30649,7 +30649,7 @@ "npm-lifecycle": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz", - "integrity": "sha1-mILTZCuMgsgVeCoS5qG/7tACYwk=", + "integrity": "sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==", "dev": true, "requires": { "byline": "^5.0.0", @@ -30665,7 +30665,7 @@ "node-gyp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", - "integrity": "sha1-65Ffe2Mck30oLjOu1Ey3oCX2Kj4=", + "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", "dev": true, "requires": { "env-paths": "^2.2.0", @@ -30684,7 +30684,7 @@ "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha1-o3XK2dAv2SEnjZVMIlTVqlfhXkg=", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "requires": { "abbrev": "1", @@ -30694,13 +30694,13 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -32780,7 +32780,7 @@ "octokit-pagination-methods": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", - "integrity": "sha1-z0cu3J1VEFX573P25CtNu0yAvqQ=", + "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", "dev": true }, "on-finished": { @@ -33601,7 +33601,7 @@ "os-name": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha1-3sGdlmKW4c1i1wGlpm7h3ernCAE=", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", "dev": true, "requires": { "macos-release": "^2.2.0", @@ -34169,7 +34169,7 @@ "parse-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz", - "integrity": "sha1-DsdpcElJd4yzuO2l6ZTDIHOhrf8=", + "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -34179,7 +34179,7 @@ "parse-url": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz", - "integrity": "sha1-mcQIT8Eb4UFB76QbPRF6lvy5Un8=", + "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==", "dev": true, "requires": { "is-ssh": "^1.3.0", @@ -34191,7 +34191,7 @@ "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", "dev": true } } @@ -35408,7 +35408,7 @@ "prop-types-extra": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", - "integrity": "sha1-WMO3TL+7ldMEYll1qi8ISDKaAQs=", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", "requires": { "react-is": "^16.3.2", "warning": "^4.0.0" @@ -35429,13 +35429,13 @@ "protocols": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", - "integrity": "sha1-lfeIpPDpebKR/+/PVjatET0DfTI=", + "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==", "dev": true }, "protoduck": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", - "integrity": "sha1-A8NlnKGAB7aaUP2Cp+vMUWJhFR8=", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", "dev": true, "requires": { "genfun": "^5.0.0" @@ -35618,7 +35618,7 @@ "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha1-W4h48ROlgheEjGSCAmxz4bpXcn8=", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "raf-schd": { @@ -35721,7 +35721,7 @@ "react": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha1-LoGIIvGpdDEiwGPWQQ2FweOv5I4=", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -35786,7 +35786,7 @@ "react-dom": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha1-wb03MxoEhsB47lTEdAcgmTsuDn8=", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -35802,7 +35802,7 @@ "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha1-TxonOv38jzSIqMUWv9p4+HI1I2I=" + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-overlays": { "version": "4.1.0", @@ -35844,7 +35844,7 @@ "react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha1-Y4aPkyWjjqXulTXYKDJ/hXczRck=", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -35881,7 +35881,7 @@ "read-cmd-shim": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz", - "integrity": "sha1-h+Q+ulAJi6WjLQzrWDq45DuWHBY=", + "integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==", "dev": true, "requires": { "graceful-fs": "^4.1.2" @@ -35937,7 +35937,7 @@ "read-package-json": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.1.tgz", - "integrity": "sha1-FqpmxZ59Ta1iiPF53ZKV/Vm7mPE=", + "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==", "dev": true, "requires": { "glob": "^7.1.1", @@ -35960,7 +35960,7 @@ "read-package-tree": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz", - "integrity": "sha1-oyy2TH8x64pvMe8G+c7fdAaP5jY=", + "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==", "dev": true, "requires": { "read-package-json": "^2.0.0", @@ -36109,7 +36109,7 @@ "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha1-5Ve3mYMWu1PJ8fVvpiY1LGljBZ8=", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { "indent-string": "^4.0.0", @@ -37178,7 +37178,7 @@ "scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha1-Tz4u0sGn1laB9MhU+oxaHMtA8ZY=", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -37922,7 +37922,7 @@ "solc": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.4.tgz", - "integrity": "sha1-nF7YGuBpLj5hTkfNW1ALD5SFuY0=", + "integrity": "sha512-IVLqAfUkJqgTS0JIgFPeC50ehUeBXu2eE+iU+rqb6UeOyf6w/BB/EsNcTSTpjtUti8BTG/sCd2qVhrWVYy7p0g==", "dev": true, "requires": { "command-exists": "^1.2.8", @@ -37939,7 +37939,7 @@ "commander": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha1-aDfD+2d62ZM9HPukLdFNURfWs54=", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, "fs-extra": { @@ -37958,7 +37958,7 @@ "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha1-ubel2nOvrX3t0PjEY5VMveaBiEA=", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "dev": true }, "jsonfile": { @@ -37973,7 +37973,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -38165,7 +38165,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" @@ -38182,7 +38182,7 @@ "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "dev": true, "requires": { "through2": "^2.0.2" @@ -39072,7 +39072,7 @@ "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha1-wy4c7pQLazQyx3G8LFS8znPNMAE=", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { "min-indent": "^1.0.0" @@ -39086,7 +39086,7 @@ "strong-log-transformer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", - "integrity": "sha1-D17XjTJeBCGsb5D38Q5pHWrjrhA=", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, "requires": { "duplexer": "^0.1.1", @@ -39690,7 +39690,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { "pify": "^3.0.0" @@ -39808,7 +39808,7 @@ "text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha1-GFPkX+45yUXOb2w2stZZtaq8KiY=", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, "text-hex": { @@ -39825,7 +39825,7 @@ "thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha1-iTLmhqQGYDigFt2eLKRq3Zg4qV8=", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, "requires": { "any-promise": "^1.0.0" @@ -40152,7 +40152,7 @@ "trim-newlines": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha1-eXJjBKaomKqDc0JymNVMLuixyzA=", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "dev": true }, "trim-off-newlines": { @@ -40534,7 +40534,7 @@ "uncontrollable": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz", - "integrity": "sha1-9n/tPvk2NxJlcYCXRjI6nbgV1VY=", + "integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==", "requires": { "@babel/runtime": "^7.6.3", "@types/react": "^16.9.11", @@ -40716,7 +40716,7 @@ "universal-user-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", - "integrity": "sha1-/Y1st3OmeacJ6WfvgoijH8wD5Vc=", + "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", "dev": true, "requires": { "os-name": "^3.1.0" @@ -41296,7 +41296,7 @@ "warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", - "integrity": "sha1-Fungd+uKhtavfWSqHgX9hbRnjKM=", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", "requires": { "loose-envify": "^1.0.0" } @@ -42876,7 +42876,7 @@ "windows-release": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.1.tgz", - "integrity": "sha1-y06AOF+FUPcJcnKHv3EDXiCcSs4=", + "integrity": "sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==", "dev": true, "requires": { "execa": "^1.0.0" @@ -43074,7 +43074,7 @@ "write-json-file": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", - "integrity": "sha1-Zbvcns2KFFjhWVJ3DMut/P9f5io=", + "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", "dev": true, "requires": { "detect-indent": "^5.0.0", @@ -43088,7 +43088,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "sort-keys": { @@ -43103,7 +43103,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -43116,7 +43116,7 @@ "write-pkg": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz", - "integrity": "sha1-DheP6Xgg04mokovHlTXb5ows/yE=", + "integrity": "sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==", "dev": true, "requires": { "sort-keys": "^2.0.0", @@ -43126,7 +43126,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { "pify": "^3.0.0" @@ -43144,7 +43144,7 @@ "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha1-H9Lprh3z51uNjDZ0Q8aS1MqB9IE=", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", From 9fb30ce775e8c5ff196ed34a87f67919d65fe039 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 12 May 2021 07:29:09 +0100 Subject: [PATCH 155/199] Wait for exists asynchronous check. --- apps/remix-ide/src/app/panels/file-panel.js | 7 +++++-- libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 5628425b34..8e1c656fad 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -188,8 +188,11 @@ module.exports = class Filepanel extends ViewPlugin { const browserProvider = this._deps.fileProviders.browser const workspacePath = 'browser/' + workspaceProvider.workspacesPath + '/' + name const workspaceRootPath = 'browser/' + workspaceProvider.workspacesPath - if (!browserProvider.exists(workspaceRootPath)) browserProvider.createDir(workspaceRootPath) - if (!browserProvider.exists(workspacePath)) browserProvider.createDir(workspacePath) + const workspaceRootPathExists = await browserProvider.exists(workspaceRootPath) + const workspacePathExists = await browserProvider.exists(workspacePath) + + if (!workspaceRootPathExists) browserProvider.createDir(workspaceRootPath) + if (!workspacePathExists) browserProvider.createDir(workspacePath) } async workspaceExists (name) { diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index c9b00bb099..09443366b5 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -182,7 +182,8 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { provider.event.register('fileAdded', async (filePath) => { - const path = extractParentFromKey(filePath) ? extractParentFromKey(filePath) === '/.workspaces' ? workspaceName : extractParentFromKey(filePath) : workspaceName + if (extractParentFromKey(filePath) === '/.workspaces') return + const path = extractParentFromKey(filePath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) @@ -191,7 +192,8 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp } }) provider.event.register('folderAdded', async (folderPath) => { - const path = extractParentFromKey(folderPath) ? extractParentFromKey(folderPath) === '/.workspaces' ? workspaceName : extractParentFromKey(folderPath) : workspaceName + if (extractParentFromKey(folderPath) === '/.workspaces') return + const path = extractParentFromKey(folderPath) || workspaceName const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) From 3e0c62ae6f1f499629864f304f33980d2716faf7 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 12 May 2021 13:36:47 +0100 Subject: [PATCH 156/199] Use provider name in callback --- apps/remix-ide-e2e/src/tests/solidityImport.spec.ts | 2 +- apps/remix-ide/src/app/panels/file-panel.js | 2 +- .../remix-ui/file-explorer/src/lib/actions/fileSystem.ts | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts b/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts index 7c8e66f309..8be5c1899c 100644 --- a/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityImport.spec.ts @@ -26,7 +26,7 @@ module.exports = { 'Test Failed Import': function (browser: NightwatchBrowser) { browser.addFile('Untitled3.sol', sources[2]['Untitled3.sol']) .clickLaunchIcon('solidity') - .assert.containsText('#compileTabView .error pre', 'not found default_workspace/Untitled11.sol') + .assert.containsText('#compileTabView .error pre', 'not found Untitled11.sol') }, 'Test Github Import - from master branch': function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 8e1c656fad..991108285c 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -218,7 +218,7 @@ module.exports = class Filepanel extends ViewPlugin { } catch (error) { console.error(error) } - }, 200) + }, 10) } } } diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 09443366b5..8e3bc9f1c4 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -183,7 +183,7 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp if (provider) { provider.event.register('fileAdded', async (filePath) => { if (extractParentFromKey(filePath) === '/.workspaces') return - const path = extractParentFromKey(filePath) || workspaceName + const path = extractParentFromKey(filePath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) @@ -193,18 +193,18 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp }) provider.event.register('folderAdded', async (folderPath) => { if (extractParentFromKey(folderPath) === '/.workspaces') return - const path = extractParentFromKey(folderPath) || workspaceName + const path = extractParentFromKey(folderPath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) }) provider.event.register('fileRemoved', async (removePath) => { - const path = extractParentFromKey(removePath) || workspaceName + const path = extractParentFromKey(removePath) || provider.workspace || provider.type || '' dispatch(fileRemovedSuccess(path, removePath)) }) provider.event.register('fileRenamed', async (oldPath) => { - const path = extractParentFromKey(oldPath) || workspaceName + const path = extractParentFromKey(oldPath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(fileRenamedSuccess(path, oldPath, data)) @@ -229,6 +229,7 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel')) }) provider.event.register('rootFolderChanged', async () => { + workspaceName = provider.workspace || provider.type || '' fetchDirectory(provider, workspaceName)(dispatch) }) dispatch(fetchProviderSuccess(provider)) From cb86b5d502cf46c976d6c458c9d4fafbf085105c Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 12 May 2021 15:01:45 +0100 Subject: [PATCH 157/199] Fixed failing chrome test --- apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts index 3601539f3d..f4558e9907 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts @@ -180,7 +180,8 @@ function runTests (browser: NightwatchBrowser) { .openFile('contracts/3_Ballot.sol') .clickLaunchIcon('solidityUnitTesting') .pause(500) - .setValue('*[data-id="uiPathInput"]', 'tests') + .setValue('*[data-id="uiPathInput"]', '') // clear before input chrome hack + .setValue('*[data-id="uiPathInput"]', 'test') .pause(2000) .scrollAndClick('#runTestsTabRunAction') .waitForElementVisible('*[data-id="testTabSolidityUnitTestsOutputheader"]', 120000) From 90eb487b08d351ada63cd78a2a6e989219fa0618 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Wed, 12 May 2021 15:31:17 +0100 Subject: [PATCH 158/199] Fixed e2e tests --- apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts index f4558e9907..9223ae1728 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts @@ -179,10 +179,8 @@ function runTests (browser: NightwatchBrowser) { .click('*[data-id="treeViewLitreeViewItemcontracts"]') .openFile('contracts/3_Ballot.sol') .clickLaunchIcon('solidityUnitTesting') - .pause(500) - .setValue('*[data-id="uiPathInput"]', '') // clear before input chrome hack - .setValue('*[data-id="uiPathInput"]', 'test') .pause(2000) + .verify.attributeEquals('*[data-id="uiPathInput"]', 'value', 'tests') .scrollAndClick('#runTestsTabRunAction') .waitForElementVisible('*[data-id="testTabSolidityUnitTestsOutputheader"]', 120000) .waitForElementPresent('#solidityUnittestsOutput div[class^="testPass"]', 60000) From 9fa49102b6901b7bb4496011a4062abdd8d857dd Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 14 May 2021 07:03:53 +0200 Subject: [PATCH 159/199] decode calldata during debugging (#1179) fix https://github.com/ethereum/remix-project/issues/481 --- apps/remix-ide-e2e/src/tests/debugger.spec.ts | 4 +-- libs/remix-debug/src/Ethdebugger.ts | 3 +- .../src/debugger/solidityLocals.ts | 11 ++++++- .../src/solidity-decoder/internalCallTree.ts | 10 +++--- .../src/solidity-decoder/localDecoder.ts | 4 +-- .../src/solidity-decoder/types/RefType.ts | 33 ++++++++++++++++++- .../src/solidity-decoder/types/StringType.ts | 4 +-- .../src/solidity-decoder/types/ValueType.ts | 2 +- .../test/decoder/localsTests/helper.ts | 10 +++++- 9 files changed, 66 insertions(+), 15 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/debugger.spec.ts b/apps/remix-ide-e2e/src/tests/debugger.spec.ts index ac2f1489fc..b43b94559b 100644 --- a/apps/remix-ide-e2e/src/tests/debugger.spec.ts +++ b/apps/remix-ide-e2e/src/tests/debugger.spec.ts @@ -323,7 +323,7 @@ const localVariable_step266_ABIEncoder = { // eslint-disable-line value: '0x0000000000000000000000000000000000000000000000000000000000000002' }, userData: { - error: '', + value: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4', type: 'bytes' } } @@ -360,7 +360,7 @@ const localVariable_step717_ABIEncoder = { // eslint-disable-line value: '0x5b38da6a701c568545dcfcb03fcb875f56beddc45b38da6a701c568545dcfcb03fcb875f56beddc400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001' }, userData: { - error: '', + value: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4', type: 'bytes' } } diff --git a/libs/remix-debug/src/Ethdebugger.ts b/libs/remix-debug/src/Ethdebugger.ts index 7f2ea7667a..3c492e1812 100644 --- a/libs/remix-debug/src/Ethdebugger.ts +++ b/libs/remix-debug/src/Ethdebugger.ts @@ -104,9 +104,10 @@ export class Ethdebugger { const stack = this.traceManager.getStackAt(step) const memory = this.traceManager.getMemoryAt(step) const address = this.traceManager.getCurrentCalledAddressAt(step) + const calldata = this.traceManager.getCallDataAt(step) try { const storageViewer = new StorageViewer({ stepIndex: step, tx: this.tx, address: address }, this.storageResolver, this.traceManager) - const locals = await localDecoder.solidityLocals(step, this.callTree, stack, memory, storageViewer, sourceLocation, null) + const locals = await localDecoder.solidityLocals(step, this.callTree, stack, memory, storageViewer, calldata, sourceLocation, null) if (locals['error']) { return callback(locals['error']) } diff --git a/libs/remix-debug/src/debugger/solidityLocals.ts b/libs/remix-debug/src/debugger/solidityLocals.ts index 64796a5f50..c7f25d01b8 100644 --- a/libs/remix-debug/src/debugger/solidityLocals.ts +++ b/libs/remix-debug/src/debugger/solidityLocals.ts @@ -62,6 +62,14 @@ export class DebuggerSolidityLocals { } catch (error) { next(error) } + }, + function getCallDataAt (stepIndex, next) { + try { + const calldata = self.traceManager.getCallDataAt(stepIndex) + next(null, calldata) + } catch (error) { + next(error) + } }], this.stepManager.currentStepIndex, (error, result) => { @@ -70,9 +78,10 @@ export class DebuggerSolidityLocals { } var stack = result[0].value var memory = result[1].value + var calldata = result[3].value try { var storageViewer = new StorageViewer({ stepIndex: this.stepManager.currentStepIndex, tx: this.tx, address: result[2].value }, this.storageResolver, this.traceManager) - solidityLocals(this.stepManager.currentStepIndex, this.internalTreeCall, stack, memory, storageViewer, sourceLocation, cursor).then((locals) => { + solidityLocals(this.stepManager.currentStepIndex, this.internalTreeCall, stack, memory, storageViewer, calldata, sourceLocation, cursor).then((locals) => { if (!cursor) { if (!locals['error']) { this.event.trigger('solidityLocals', [locals]) diff --git a/libs/remix-debug/src/solidity-decoder/internalCallTree.ts b/libs/remix-debug/src/solidity-decoder/internalCallTree.ts index acdeae4749..d84e023047 100644 --- a/libs/remix-debug/src/solidity-decoder/internalCallTree.ts +++ b/libs/remix-debug/src/solidity-decoder/internalCallTree.ts @@ -310,10 +310,10 @@ async function includeVariableDeclaration (tree, step, sourceLocation, scopeId, // } // input params if (inputs && inputs.parameters) { - functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractObj.name, previousSourceLocation, stack.length, inputs.parameters.length, -1) + functionDefinitionAndInputs.inputs = addParams(inputs, tree, scopeId, states, contractObj, previousSourceLocation, stack.length, inputs.parameters.length, -1) } // output params - if (outputs) addParams(outputs, tree, scopeId, states, contractObj.name, previousSourceLocation, stack.length, 0, 1) + if (outputs) addParams(outputs, tree, scopeId, states, contractObj, previousSourceLocation, stack.length, 0, 1) } } catch (error) { console.log(error) @@ -373,7 +373,8 @@ function extractFunctionDefinitions (ast, astWalker) { return ret } -function addParams (parameterList, tree, scopeId, states, contractName, sourceLocation, stackLength, stackPosition, dir) { +function addParams (parameterList, tree, scopeId, states, contractObj, sourceLocation, stackLength, stackPosition, dir) { + const contractName = contractObj.name const params = [] for (const inputParam in parameterList.parameters) { const param = parameterList.parameters[inputParam] @@ -386,7 +387,8 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo name: attributesName, type: parseType(param.typeDescriptions.typeString, states, contractName, location), stackDepth: stackDepth, - sourceLocation: sourceLocation + sourceLocation: sourceLocation, + abi: contractObj.contract.abi } params.push(attributesName) } diff --git a/libs/remix-debug/src/solidity-decoder/localDecoder.ts b/libs/remix-debug/src/solidity-decoder/localDecoder.ts index 89aba92a2a..9564efc93b 100644 --- a/libs/remix-debug/src/solidity-decoder/localDecoder.ts +++ b/libs/remix-debug/src/solidity-decoder/localDecoder.ts @@ -1,6 +1,6 @@ 'use strict' -export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storageResolver, currentSourceLocation, cursor) { +export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, memory, storageResolver, calldata, currentSourceLocation, cursor) { const scope = internalTreeCall.findScope(vmtraceIndex) if (!scope) { const error = { message: 'Can\'t display locals. reason: compilation result might not have been provided' } @@ -18,7 +18,7 @@ export async function solidityLocals (vmtraceIndex, internalTreeCall, stack, mem anonymousIncr++ } try { - locals[name] = await variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageResolver, cursor) + locals[name] = await variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageResolver, calldata, cursor, variable) } catch (e) { console.log(e) locals[name] = '' diff --git a/libs/remix-debug/src/solidity-decoder/types/RefType.ts b/libs/remix-debug/src/solidity-decoder/types/RefType.ts index 97ce46a6a0..031d52f295 100644 --- a/libs/remix-debug/src/solidity-decoder/types/RefType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/RefType.ts @@ -1,4 +1,5 @@ 'use strict' +import { ethers } from 'ethers' import { toBN } from './util' export class RefType { @@ -7,6 +8,7 @@ export class RefType { storageBytes typeName basicType + underlyingType constructor (storageSlots, storageBytes, typeName, location) { this.location = location @@ -33,7 +35,7 @@ export class RefType { * @param {Object} - storageResolver * @return {Object} decoded value */ - async decodeFromStack (stackDepth, stack, memory, storageResolver, cursor): Promise { + async decodeFromStack (stackDepth, stack, memory, storageResolver, calldata, cursor, variableDetails?): Promise { if (stack.length - 1 < stackDepth) { return { error: '', type: this.typeName } } @@ -49,6 +51,26 @@ export class RefType { } else if (this.isInMemory()) { offset = parseInt(offset, 16) return this.decodeFromMemoryInternal(offset, memory, cursor) + } else if (this.isInCallData()) { + calldata = calldata.length > 0 ? calldata[0] : '0x' + const ethersAbi = new ethers.utils.Interface(variableDetails.abi) + const fnSign = calldata.substr(0, 10) + const decodedData = ethersAbi.decodeFunctionData(ethersAbi.getFunction(fnSign), calldata) + let decodedValue = decodedData[variableDetails.name] + const isArray = Array.isArray(decodedValue) + if (isArray) { + decodedValue = decodedValue.map((el) => { + return { + value: el.toString(), + type: this.underlyingType.typeName + } + }) + } + return { + length: Array.isArray(decodedValue) ? '0x' + decodedValue.length.toString(16) : undefined, + value: decodedValue, + type: this.typeName + } } else { return { error: '', type: this.typeName } } @@ -84,4 +106,13 @@ export class RefType { isInMemory () { return this.location.indexOf('memory') === 0 } + + /** + * current type defined in storage + * + * @return {Bool} - return true if the type is defined in the storage + */ + isInCallData () { + return this.location.indexOf('calldata') === 0 + } } diff --git a/libs/remix-debug/src/solidity-decoder/types/StringType.ts b/libs/remix-debug/src/solidity-decoder/types/StringType.ts index 2c8f4cac60..8e31b3d17f 100644 --- a/libs/remix-debug/src/solidity-decoder/types/StringType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/StringType.ts @@ -20,9 +20,9 @@ export class StringType extends DynamicByteArray { return format(decoded) } - async decodeFromStack (stackDepth, stack, memory) { + async decodeFromStack (stackDepth, stack, memory, calldata, variableDetails?) { try { - return await super.decodeFromStack(stackDepth, stack, memory, null, null) + return await super.decodeFromStack(stackDepth, stack, memory, null, calldata, variableDetails) } catch (e) { console.log(e) return '' diff --git a/libs/remix-debug/src/solidity-decoder/types/ValueType.ts b/libs/remix-debug/src/solidity-decoder/types/ValueType.ts index 61b4c65c54..63bd4ae0f0 100644 --- a/libs/remix-debug/src/solidity-decoder/types/ValueType.ts +++ b/libs/remix-debug/src/solidity-decoder/types/ValueType.ts @@ -43,7 +43,7 @@ export class ValueType { * @param {String} - memory * @return {Object} - decoded value */ - async decodeFromStack (stackDepth, stack, memory) { + async decodeFromStack (stackDepth, stack, memory, calldata, variableDetails?) { let value if (stackDepth >= stack.length) { value = this.decodeValue('') diff --git a/libs/remix-debug/test/decoder/localsTests/helper.ts b/libs/remix-debug/test/decoder/localsTests/helper.ts index 10537faee1..c041f4364a 100644 --- a/libs/remix-debug/test/decoder/localsTests/helper.ts +++ b/libs/remix-debug/test/decoder/localsTests/helper.ts @@ -22,13 +22,21 @@ export function decodeLocals (st, index, traceManager, callTree, verifier) { } catch (error) { callback(error) } + }, + function getCallDataAt (stepIndex, callback) { + try { + const result = traceManager.getCallDataAt(stepIndex) + callback(null, result) + } catch (error) { + callback(error) + } }], index, function (error, result) { if (error) { return st.fail(error) } - solidityLocals(index, callTree, result[0].value, result[1].value, {}, { start: 5000 }, null).then((locals) => { + solidityLocals(index, callTree, result[0].value, result[1].value, {}, result[2].value, { start: 5000 }, null).then((locals) => { verifier(locals) }) }) From 816df569f060db85197182db32d9b187c5e6c12d Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 17 May 2021 07:56:32 +0200 Subject: [PATCH 160/199] new lable for local stable version --- apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js index f64cdead77..88880bff22 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js @@ -517,7 +517,7 @@ class CompilerContainer { // fetching both normal and wasm builds and creating a [version, baseUrl] map async fetchAllVersion (callback) { let selectedVersion, allVersionsWasm, isURL - let allVersions = [{ path: 'builtin', longVersion: 'latest local version - 0.7.4' }] + let allVersions = [{ path: 'builtin', longVersion: 'Stable local version - 0.7.4' }] // fetch normal builds const binRes = await promisedMiniXhr(`${baseURLBin}/list.json`) // fetch wasm builds From 00a4585cf4b96b26181626991f64805f98e7e5b9 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 17 May 2021 14:52:20 +0100 Subject: [PATCH 161/199] Expand props --- .../file-explorer/src/lib/file-explorer.tsx | 152 +++++------------- .../src/lib/remix-ui-modal-dialog.tsx | 18 +-- .../modal-dialog/src/lib/types/index.ts | 6 +- libs/remix-ui/toaster/src/lib/toaster.tsx | 6 +- .../workspace/src/lib/remix-ui-workspace.tsx | 55 ++----- 5 files changed, 76 insertions(+), 161 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index fc8c89450a..d925bc3f0b 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -88,14 +88,10 @@ export const FileExplorer = (props: FileExplorerProps) => { hide: true, title: '', message: '', - ok: { - label: '', - fn: () => {} - }, - cancel: { - label: '', - fn: () => {} - }, + okLabel: '', + okFn: () => {}, + cancelLabel: '', + cancelFn: () => {}, handleHide: null }, modals: [], @@ -122,13 +118,7 @@ export const FileExplorer = (props: FileExplorerProps) => { useEffect(() => { if (fileSystem.notification.message) { - modal(fileSystem.notification.title, fileSystem.notification.message, { - label: fileSystem.notification.labelOk, - fn: fileSystem.notification.actionOk - }, { - label: fileSystem.notification.labelCancel, - fn: fileSystem.notification.actionCancel - }) + modal(fileSystem.notification.title, fileSystem.notification.message, fileSystem.notification.labelOk, fileSystem.notification.actionOk, fileSystem.notification.labelCancel, fileSystem.notification.actionCancel) } }, [fileSystem.notification.message]) @@ -201,8 +191,10 @@ export const FileExplorer = (props: FileExplorerProps) => { hide: false, title: prevState.modals[0].title, message: prevState.modals[0].message, - ok: prevState.modals[0].ok, - cancel: prevState.modals[0].cancel, + okLabel: prevState.modals[0].okLabel, + okFn: prevState.modals[0].okFn, + cancelLabel: prevState.modals[0].cancelLabel, + cancelFn: prevState.modals[0].cancelFn, handleHide: prevState.modals[0].handleHide } @@ -248,10 +240,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } } catch (error) { - return modal('File Creation Failed', typeof error === 'string' ? error : error.message, { - label: 'Close', - fn: async () => {} - }, null) + return modal('File Creation Failed', typeof error === 'string' ? error : error.message, 'Close', async () => {}) } } @@ -263,20 +252,14 @@ export const FileExplorer = (props: FileExplorerProps) => { const exists = await fileManager.exists(dirName) if (exists) { - return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, { - label: 'Close', - fn: () => {} - }, null) + return modal('Rename File Failed', `A file or folder ${extractNameFromKey(newFolderPath)} already exists at this location. Please choose a different name.`, 'Close', () => {}) } await fileManager.mkdir(dirName) setState(prevState => { return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] } }) } catch (e) { - return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, { - label: 'Close', - fn: async () => {} - }, null) + return modal('Folder Creation Failed', typeof e === 'string' ? e : e.message, 'Close', async () => {}) } } @@ -288,21 +271,15 @@ export const FileExplorer = (props: FileExplorerProps) => { } const isDir = state.fileManager.isDirectory(path) - modal(`Delete ${isDir ? 'folder' : 'file'}`, `Are you sure you want to delete ${path} ${isDir ? 'folder' : 'file'}?`, { - label: 'OK', - fn: async () => { - try { - const fileManager = state.fileManager + modal(`Delete ${isDir ? 'folder' : 'file'}`, `Are you sure you want to delete ${path} ${isDir ? 'folder' : 'file'}?`, 'OK', async () => { + try { + const fileManager = state.fileManager - await fileManager.remove(path) - } catch (e) { - toast(`Failed to remove ${isDir ? 'folder' : 'file'} ${path}.`) - } + await fileManager.remove(path) + } catch (e) { + toast(`Failed to remove ${isDir ? 'folder' : 'file'} ${path}.`) } - }, { - label: 'Cancel', - fn: () => {} - }) + }, 'Cancel', () => {}) } const renamePath = async (oldPath: string, newPath: string) => { @@ -311,18 +288,12 @@ export const FileExplorer = (props: FileExplorerProps) => { const exists = await fileManager.exists(newPath) if (exists) { - modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, { - label: 'Close', - fn: () => {} - }, null) + modal('Rename File Failed', `A file or folder ${extractNameFromKey(newPath)} already exists at this location. Please choose a different name.`, 'Close', () => {}) } else { await fileManager.rename(oldPath, newPath) } } catch (error) { - modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, { - label: 'Close', - fn: async () => {} - }, null) + modal('Rename File Failed', 'Unexpected error while renaming: ' + typeof error === 'string' ? error : error.message, 'Close', async () => {}) } } @@ -345,19 +316,13 @@ export const FileExplorer = (props: FileExplorerProps) => { fileReader.onload = async function (event) { if (helper.checkSpecialChars(file.name)) { - modal('File Upload Failed', 'Special characters are not allowed', { - label: 'Close', - fn: async () => {} - }, null) + modal('File Upload Failed', 'Special characters are not allowed', 'Close', async () => {}) return } const success = await filesProvider.set(name, event.target.result) if (!success) { - return modal('File Upload Failed', 'Failed to create file ' + name, { - label: 'Close', - fn: async () => {} - }, null) + return modal('File Upload Failed', 'Failed to create file ' + name, 'Close', async () => {}) } const config = registry.get('config').api const editor = registry.get('editor').api @@ -374,15 +339,9 @@ export const FileExplorer = (props: FileExplorerProps) => { if (!exist) { loadFile(name) } else { - modal('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, { - label: 'OK', - fn: () => { - loadFile(name) - } - }, { - label: 'Cancel', - fn: () => {} - }) + modal('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, 'OK', () => { + loadFile(name) + }, 'Cancel', () => {}) } }).catch(error => { if (error) console.log(error) @@ -391,41 +350,23 @@ export const FileExplorer = (props: FileExplorerProps) => { } const publishToGist = () => { - modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${name} workspace as a public gist on github.com?`, { - label: 'OK', - fn: toGist - }, { - label: 'Cancel', - fn: () => {} - }) + modal('Create a public gist', `Are you sure you want to anonymously publish all your files in the ${name} workspace as a public gist on github.com?`, 'OK', toGist, 'Cancel', () => {}) } const toGist = (id?: string) => { const filesProvider = fileSystem.provider.provider const proccedResult = function (error, data) { if (error) { - modal('Publish to gist Failed', 'Failed to manage gist: ' + error, { - label: 'Close', - fn: async () => {} - }, null) + modal('Publish to gist Failed', 'Failed to manage gist: ' + error, 'Close', () => {}) } else { if (data.html_url) { - modal('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, { - label: 'OK', - fn: () => { - window.open(data.html_url, '_blank') - } - }, { - label: 'Cancel', - fn: () => {} - }) + modal('Gist is ready', `The gist is at ${data.html_url}. Would you like to open it in a new window?`, 'OK', () => { + window.open(data.html_url, '_blank') + }, 'Cancel', () => {}) } else { const error = JSON.stringify(data.errors, null, '\t') || '' const message = data.message === 'Not Found' ? data.message + '. Please make sure the API token has right to create a gist.' : data.message - modal('Publish to gist Failed', message + ' ' + data.documentation_url + ' ' + error, { - label: 'Close', - fn: async () => {} - }, null) + modal('Publish to gist Failed', message + ' ' + data.documentation_url + ' ' + error, 'Close', () => {}) } } } @@ -451,20 +392,14 @@ export const FileExplorer = (props: FileExplorerProps) => { packageFiles(filesProvider, folder, async (error, packaged) => { if (error) { console.log(error) - modal('Publish to gist Failed', 'Failed to create gist: ' + error.message, { - label: 'Close', - fn: async () => {} - }, null) + modal('Publish to gist Failed', 'Failed to create gist: ' + error.message, 'Close', async () => {}) } else { // check for token const config = registry.get('config').api const accessToken = config.get('settings/gist-access-token') if (!accessToken) { - modal('Authorize Token', 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.', { - label: 'Close', - fn: async () => {} - }, null) + modal('Authorize Token', 'Remix requires an access token (which includes gists creation permission). Please go to the settings tab to create one.', 'Close', () => {}) } else { const description = 'Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. \n Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=' + queryParams.get().version + '&optimize=' + queryParams.get().optimize + '&runs=' + queryParams.get().runs + '&gist=' @@ -536,7 +471,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } - const modal = (title: string, message: string, ok: { label: string, fn: () => void }, cancel: { label: string, fn: () => void }) => { + const modal = (title: string, message: string, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => { setState(prevState => { return { ...prevState, @@ -544,8 +479,10 @@ export const FileExplorer = (props: FileExplorerProps) => { { message, title, - ok, - cancel, + okLabel, + okFn, + cancelLabel, + cancelFn, handleHide: handleHideModal }] } @@ -644,10 +581,7 @@ export const FileExplorer = (props: FileExplorerProps) => { }) } if (helper.checkSpecialChars(content)) { - modal('Validation Error', 'Special characters are not allowed', { - label: 'OK', - fn: () => {} - }, null) + modal('Validation Error', 'Special characters are not allowed', 'OK', () => {}) } else { if (state.focusEdit.isNew) { state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) @@ -865,8 +799,10 @@ export const FileExplorer = (props: FileExplorerProps) => { title={ state.focusModal.title } message={ state.focusModal.message } hide={ state.focusModal.hide } - ok={ state.focusModal.ok } - cancel={ state.focusModal.cancel } + okLabel={ state.focusModal.okLabel } + okFn={ state.focusModal.okFn } + cancelLabel={ state.focusModal.cancelLabel } + cancelFn={ state.focusModal.cancelFn } handleHide={ handleHideModal } /> } diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index 2caa41219d..ec016068e9 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -18,7 +18,7 @@ export const ModalDialog = (props: ModalDialogProps) => { const modalKeyEvent = (keyCode) => { if (keyCode === 27) { // Esc - if (props.cancel && props.cancel.fn) props.cancel.fn() + if (props.cancelFn) props.cancelFn() handleHide() } else if (keyCode === 13) { // Enter enterHandler() @@ -33,9 +33,9 @@ export const ModalDialog = (props: ModalDialogProps) => { const enterHandler = () => { if (state.toggleBtn) { - if (props.ok && props.ok.fn) props.ok.fn() + if (props.okFn) props.okFn() } else { - if (props.cancel && props.cancel.fn) props.cancel.fn() + if (props.cancelFn) props.cancelFn() } handleHide() } @@ -79,29 +79,29 @@ export const ModalDialog = (props: ModalDialogProps) => {
{/* todo add autofocus ^^ */} - { props.ok && + { props.okLabel && { - if (props.ok.fn) props.ok.fn() + if (props.okFn) props.okFn() handleHide() }} > - { props.ok.label ? props.ok.label : 'OK' } + { props.okLabel ? props.okLabel : 'OK' } } - { props.cancel && + { props.cancelLabel && { - if (props.cancel.fn) props.cancel.fn() + if (props.cancelFn) props.cancelFn() handleHide() }} > - { props.cancel.label ? props.cancel.label : 'Cancel' } + { props.cancelLabel ? props.cancelLabel : 'Cancel' } }
diff --git a/libs/remix-ui/modal-dialog/src/lib/types/index.ts b/libs/remix-ui/modal-dialog/src/lib/types/index.ts index 29c4d39505..58d15cdb87 100644 --- a/libs/remix-ui/modal-dialog/src/lib/types/index.ts +++ b/libs/remix-ui/modal-dialog/src/lib/types/index.ts @@ -2,8 +2,10 @@ export interface ModalDialogProps { id?: string title?: string, message?: string, - ok?: { label: string, fn: () => void }, - cancel: { label: string, fn: () => void }, + okLabel?: string, + okFn?: () => void, + cancelLabel?: string, + cancelFn?: () => void, modalClass?: string, showCancelIcon?: boolean, hide: boolean, diff --git a/libs/remix-ui/toaster/src/lib/toaster.tsx b/libs/remix-ui/toaster/src/lib/toaster.tsx index b7573f72cc..d3cd160c5c 100644 --- a/libs/remix-ui/toaster/src/lib/toaster.tsx +++ b/libs/remix-ui/toaster/src/lib/toaster.tsx @@ -91,10 +91,8 @@ export const Toaster = (props: ToasterProps) => { <> {} - }} + cancelLabel='Close' + cancelFn={() => {}} hide={!state.showModal} handleHide={hideFullMessage} /> diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 1baca04eb7..8286163970 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -145,14 +145,10 @@ export const Workspace = (props: WorkspaceProps) => { hide: true, title: '', message: null, - ok: { - label: '', - fn: () => {} - }, - cancel: { - label: '', - fn: () => {} - }, + okLabel: '', + okFn: () => {}, + cancelLabel: '', + cancelFn: () => {}, handleHide: null }, loadingLocalhost: false, @@ -168,41 +164,20 @@ export const Workspace = (props: WorkspaceProps) => { /* workspace creation, renaming and deletion */ const renameCurrentWorkspace = () => { - modal('Rename Current Workspace', renameModalMessage(), { - label: 'OK', - fn: onFinishRenameWorkspace - }, { - label: '', - fn: () => {} - }) + modal('Rename Current Workspace', renameModalMessage(), 'OK', onFinishRenameWorkspace, '', () => {}) } const createWorkspace = () => { - modal('Create Workspace', createModalMessage(), { - label: 'OK', - fn: onFinishCreateWorkspace - }, { - label: '', - fn: () => {} - }) + modal('Create Workspace', createModalMessage(), 'OK', onFinishCreateWorkspace, '', () => {}) } const deleteCurrentWorkspace = () => { - modal('Delete Current Workspace', 'Are you sure to delete the current workspace?', { - label: 'OK', - fn: onFinishDeleteWorkspace - }, { - label: '', - fn: () => {} - }) + modal('Delete Current Workspace', 'Are you sure to delete the current workspace?', 'OK', onFinishDeleteWorkspace, '', () => {}) } const modalMessage = (title: string, body: string) => { setTimeout(() => { // wait for any previous modal a chance to close - modal(title, body, { - label: 'OK', - fn: () => {} - }, null) + modal(title, body, 'OK', () => {}, '', null) }, 200) } @@ -297,7 +272,7 @@ export const Workspace = (props: WorkspaceProps) => { }) } - const modal = async (title: string, message: string | JSX.Element, ok: { label: string, fn: () => void }, cancel: { label: string, fn: () => void }) => { + const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel: string, cancelFn: () => void) => { await setState(prevState => { return { ...prevState, @@ -306,8 +281,10 @@ export const Workspace = (props: WorkspaceProps) => { hide: false, message, title, - ok, - cancel, + okLabel, + okFn, + cancelLabel, + cancelFn, handleHide: handleHideModal } } @@ -339,8 +316,10 @@ export const Workspace = (props: WorkspaceProps) => { title={ state.modal.title } message={ state.modal.message } hide={ state.modal.hide } - ok={ state.modal.ok } - cancel={ state.modal.cancel } + okLabel={ state.modal.okLabel } + okFn={ state.modal.okFn } + cancelLabel={ state.modal.cancelLabel } + cancelFn={ state.modal.cancelFn } handleHide={ handleHideModal }> { (typeof state.modal.message !== 'string') && state.modal.message } From ad44e1ec17635023ff53ffc44842fa5c2a331430 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 17 May 2021 12:55:22 +0530 Subject: [PATCH 162/199] check if remixd activated before switching --- .../workspace/src/lib/remix-ui-workspace.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 1baca04eb7..51516d87f5 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -272,11 +272,13 @@ export const Workspace = (props: WorkspaceProps) => { const remixdExplorer = { hide: async () => { - await setWorkspace(NO_WORKSPACE) - props.fileManager.setMode('browser') - setState(prevState => { - return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } - }) + if (props.fileManager.mode === 'localhost') { + await setWorkspace(NO_WORKSPACE) + props.fileManager.setMode('browser') + setState(prevState => { + return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } + }) + } }, show: () => { props.fileManager.setMode('localhost') From 0acf34ba9f3aec56163318a88239b3d3a03a4713 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 17 May 2021 13:03:05 +0530 Subject: [PATCH 163/199] hide spinner --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 51516d87f5..2774a75cd4 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -278,6 +278,10 @@ export const Workspace = (props: WorkspaceProps) => { setState(prevState => { return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } }) + } else { + setState(prevState => { + return { ...prevState, loadingLocalhost: false } + }) } }, show: () => { From d3ac2b1be7ca17b91da7309819aa9afa3790801a Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 17 May 2021 13:55:59 +0530 Subject: [PATCH 164/199] switch to previous workspace from localhost --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 2774a75cd4..f7d9994211 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -91,6 +91,7 @@ export const Workspace = (props: WorkspaceProps) => { const localhostDisconnect = () => { if (state.currentWorkspace === LOCALHOST) setWorkspace(props.workspaces.length > 0 ? props.workspaces[0] : NO_WORKSPACE) + else setWorkspace(state.currentWorkspace) // Useful to switch to last selcted workspace when remixd is disconnected } props.localhost.event.unregister('disconnected', localhostDisconnect) props.localhost.event.register('disconnected', localhostDisconnect) @@ -272,6 +273,7 @@ export const Workspace = (props: WorkspaceProps) => { const remixdExplorer = { hide: async () => { + // If 'connect to localhost' is clicked from home tab, mode is not 'localhost' if (props.fileManager.mode === 'localhost') { await setWorkspace(NO_WORKSPACE) props.fileManager.setMode('browser') @@ -279,6 +281,7 @@ export const Workspace = (props: WorkspaceProps) => { return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } }) } else { + // Hide spinner in file explorer setState(prevState => { return { ...prevState, loadingLocalhost: false } }) From c3e568311605c5e6ad0dc5cca9f2e278aaa4dbc9 Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Mon, 17 May 2021 17:51:31 +0100 Subject: [PATCH 165/199] Catch reserved keywords and display modal --- .../file-explorer/src/lib/file-explorer.tsx | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index d925bc3f0b..4ce0c9cace 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -584,15 +584,31 @@ export const FileExplorer = (props: FileExplorerProps) => { modal('Validation Error', 'Special characters are not allowed', 'OK', () => {}) } else { if (state.focusEdit.isNew) { - state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) - removeInputField(parentFolder)(dispatch) + if ((content === props.name) || (content.indexOf('gist-') === 0)) { + removeInputField(parentFolder)(dispatch) + modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { + label: 'Close', + fn: () => {} + }, null) + } else { + state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) + removeInputField(parentFolder)(dispatch) + } } else { - const oldPath: string = state.focusEdit.element - const oldName = extractNameFromKey(oldPath) - const newPath = oldPath.replace(oldName, content) + if ((content === props.name) || (content.indexOf('gist-') === 0)) { + editRef.current.textContent = state.focusEdit.lastEdit + modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { + label: 'Close', + fn: () => {} + }, null) + } else { + const oldPath: string = state.focusEdit.element + const oldName = extractNameFromKey(oldPath) + const newPath = oldPath.replace(oldName, content) - editRef.current.textContent = extractNameFromKey(oldPath) - renamePath(oldPath, newPath) + editRef.current.textContent = extractNameFromKey(oldPath) + renamePath(oldPath, newPath) + } } setState(prevState => { return { ...prevState, focusEdit: { element: null, isNew: false, type: '', lastEdit: '' } } From 6a8442f568ab4b9b25d3670af8d8edc59c9a6f0f Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 18 May 2021 10:46:08 +0100 Subject: [PATCH 166/199] Optimised mode for managing reserved words --- .../remix-ui/file-explorer/src/lib/file-explorer.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 4ce0c9cace..57eda46094 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -97,7 +97,8 @@ export const FileExplorer = (props: FileExplorerProps) => { modals: [], toasterMsg: '', mouseOverElement: null, - showContextMenu: false + showContextMenu: false, + reservedKeywords: [name, 'gist-'] }) const [fileSystem, dispatch] = useReducer(fileSystemReducer, fileSystemInitialState) const editRef = useRef(null) @@ -222,6 +223,11 @@ export const FileExplorer = (props: FileExplorerProps) => { return keyPath.join('/') } + const hasReservedKeyword = (content: string): boolean => { + if (state.reservedKeywords.findIndex(value => content.startsWith(value)) !== -1) return true + else return false + } + const createNewFile = async (newFilePath: string) => { const fileManager = state.fileManager @@ -584,7 +590,7 @@ export const FileExplorer = (props: FileExplorerProps) => { modal('Validation Error', 'Special characters are not allowed', 'OK', () => {}) } else { if (state.focusEdit.isNew) { - if ((content === props.name) || (content.indexOf('gist-') === 0)) { + if (hasReservedKeyword(content)) { removeInputField(parentFolder)(dispatch) modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { label: 'Close', @@ -595,7 +601,7 @@ export const FileExplorer = (props: FileExplorerProps) => { removeInputField(parentFolder)(dispatch) } } else { - if ((content === props.name) || (content.indexOf('gist-') === 0)) { + if (hasReservedKeyword(content)) { editRef.current.textContent = state.focusEdit.lastEdit modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { label: 'Close', From d6a3e6c728ac67a4812e838430438229407be1ce Mon Sep 17 00:00:00 2001 From: ioedeveloper Date: Tue, 18 May 2021 11:56:42 +0100 Subject: [PATCH 167/199] Update modal parameters --- libs/remix-ui/file-explorer/src/lib/file-explorer.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx index 57eda46094..c471449ac4 100644 --- a/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx +++ b/libs/remix-ui/file-explorer/src/lib/file-explorer.tsx @@ -592,10 +592,7 @@ export const FileExplorer = (props: FileExplorerProps) => { if (state.focusEdit.isNew) { if (hasReservedKeyword(content)) { removeInputField(parentFolder)(dispatch) - modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { - label: 'Close', - fn: () => {} - }, null) + modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {}) } else { state.focusEdit.type === 'file' ? createNewFile(joinPath(parentFolder, content)) : createNewFolder(joinPath(parentFolder, content)) removeInputField(parentFolder)(dispatch) @@ -603,10 +600,7 @@ export const FileExplorer = (props: FileExplorerProps) => { } else { if (hasReservedKeyword(content)) { editRef.current.textContent = state.focusEdit.lastEdit - modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, { - label: 'Close', - fn: () => {} - }, null) + modal('Reserved Keyword', `File name contains remix reserved keywords. '${content}'`, 'Close', () => {}) } else { const oldPath: string = state.focusEdit.element const oldName = extractNameFromKey(oldPath) From 6dfd7d91d94293a817d2c7289c253e72245fc653 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 11 May 2021 13:16:44 +0530 Subject: [PATCH 168/199] compile with hardhat and remixd --- .../remix-ide/src/app/files/remixDProvider.js | 5 + apps/remix-ide/src/app/files/remixd-handle.js | 2 +- .../src/app/tabs/compileTab/compileTab.js | 5 + libs/remixd/src/services/remixdClient.ts | 9 +- package-lock.json | 1008 +++++++++++++++-- package.json | 1 + 6 files changed, 955 insertions(+), 75 deletions(-) diff --git a/apps/remix-ide/src/app/files/remixDProvider.js b/apps/remix-ide/src/app/files/remixDProvider.js index 60337c11e4..044e46a165 100644 --- a/apps/remix-ide/src/app/files/remixDProvider.js +++ b/apps/remix-ide/src/app/files/remixDProvider.js @@ -50,6 +50,11 @@ module.exports = class RemixDProvider extends FileProvider { return this._isReady } + async compileWithHardhat () { + console.log('Inside compileWithHardhat, calling hardhatCompile using _appManager') + return await this._appManager.call('remixd', 'hardhatCompile', {}) + } + close (cb) { this._isReady = false cb() diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index 3ec635040c..e8145f58d8 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -22,7 +22,7 @@ const profile = { name: 'remixd', displayName: 'RemixD', url: 'ws://127.0.0.1:65520', - methods: ['folderIsReadOnly', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir'], + methods: ['folderIsReadOnly', 'hardhatCompile', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir'], events: [], description: 'Using Remixd daemon, allow to access file system', kind: 'other', diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index 79228d1663..ea7377c3fd 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -80,6 +80,11 @@ class CompileTab { runCompiler () { try { + console.log('mode is - ', this.fileManager.mode) + if(this.fileManager.mode === 'localhost') { + console.log('calling compilehardhat') + this.fileProvider.compileWithHardhat().then(console.log) + } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() var currentFile = this.config.get('currentFile') diff --git a/libs/remixd/src/services/remixdClient.ts b/libs/remixd/src/services/remixdClient.ts index 31588628ea..42752c3adc 100644 --- a/libs/remixd/src/services/remixdClient.ts +++ b/libs/remixd/src/services/remixdClient.ts @@ -5,6 +5,7 @@ import * as utils from '../utils' import * as chokidar from 'chokidar' import * as fs from 'fs-extra' import * as isbinaryfile from 'isbinaryfile' +const hre = require("hardhat"); export class RemixdClient extends PluginClient { methods: Array @@ -14,7 +15,7 @@ export class RemixdClient extends PluginClient { constructor (private readOnly = false) { super() - this.methods = ['folderIsReadOnly', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir', 'canDeactivate'] + this.methods = ['folderIsReadOnly', 'hardhatCompile', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir', 'canDeactivate'] } setWebSocket (websocket: WS): void { @@ -26,6 +27,12 @@ export class RemixdClient extends PluginClient { if (this.isLoaded) this.emit('rootFolderChanged') } + async hardhatCompile() { + console.log('inside hardhatCompile') + console.log('here is hre-->', hre.tasks) + // await hre.tasks.accounts.action(); + } + list (): Filelist { try { return utils.walkSync(this.currentSharedFolder, {}, this.currentSharedFolder) diff --git a/package-lock.json b/package-lock.json index d74204bd8f..ad004a82fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7796,6 +7796,112 @@ "any-observable": "^0.3.0" } }, + "@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "requires": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "requires": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + } + } + }, + "@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "requires": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==" + }, + "@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "requires": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -7810,6 +7916,11 @@ "type-detect": "4.0.8" } }, + "@solidity-parser/parser": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz", + "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==" + }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", @@ -8299,6 +8410,11 @@ "@types/node": "*" } }, + "@types/lru-cache": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", + "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==" + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -8976,11 +9092,22 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "requires": { "event-target-shim": "^5.0.0" } }, + "abstract-leveldown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", + "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -9081,6 +9208,11 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + }, "aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", @@ -11177,8 +11309,7 @@ "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, "bindings": { "version": "1.5.0", @@ -11560,8 +11691,7 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "browserify": { "version": "16.5.1", @@ -12471,8 +12601,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-indexof": { "version": "1.1.1", @@ -12621,7 +12750,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -13418,8 +13546,7 @@ "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" }, "commander": { "version": "2.20.3", @@ -14917,8 +15044,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decamelize-keys": { "version": "1.1.0", @@ -15239,6 +15365,29 @@ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, + "deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + } + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -15884,8 +16033,7 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "emojis-list": { "version": "3.0.0", @@ -15923,6 +16071,17 @@ } } }, + "encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "requires": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -15942,6 +16101,21 @@ "tapable": "^1.0.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + }, + "dependencies": { + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + } + } + }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -15957,8 +16131,7 @@ "env-paths": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", - "dev": true + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==" }, "envinfo": { "version": "7.5.1", @@ -16825,6 +16998,38 @@ } } }, + "eth-sig-util": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.4.tgz", + "integrity": "sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A==", + "requires": { + "ethereumjs-abi": "0.6.8", + "ethereumjs-util": "^5.1.1", + "tweetnacl": "^1.0.3", + "tweetnacl-util": "^0.15.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", + "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", + "requires": { + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "^0.1.3", + "rlp": "^2.0.0", + "safe-buffer": "^5.1.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, "ethereum-bloom-filters": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", @@ -16883,6 +17088,31 @@ } } }, + "ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "requires": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + }, + "dependencies": { + "ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "requires": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + } + } + }, "ethereumjs-common": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.1.tgz", @@ -17014,8 +17244,7 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, "eventemitter2": { "version": "6.4.2", @@ -17891,7 +18120,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, "requires": { "is-buffer": "~2.0.3" }, @@ -17899,8 +18127,7 @@ "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" } } }, @@ -18107,6 +18334,11 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -19151,7 +19383,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -19851,7 +20082,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -20257,8 +20487,7 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, "growly": { "version": "1.3.0", @@ -20594,6 +20823,495 @@ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, + "hardhat": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.2.1.tgz", + "integrity": "sha512-8s7MtGXdh0NDwQKdlA8m8QdloVIN1+hv5aFpn0G5Ljj9vfNY9kUoc0a9pMboeGbd9WrS+XrZs5YlsPgQjaW/Tg==", + "requires": { + "@ethereumjs/block": "^3.2.1", + "@ethereumjs/blockchain": "^5.2.1", + "@ethereumjs/common": "^2.2.0", + "@ethereumjs/tx": "^3.1.3", + "@ethereumjs/vm": "^5.3.2", + "@sentry/node": "^5.18.1", + "@solidity-parser/parser": "^0.11.0", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "^5.1.0", + "abort-controller": "^3.0.0", + "adm-zip": "^0.4.16", + "ansi-escapes": "^4.3.0", + "chalk": "^2.4.2", + "chokidar": "^3.4.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "eth-sig-util": "^2.5.2", + "ethereum-cryptography": "^0.1.2", + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^7.0.10", + "find-up": "^2.1.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "glob": "^7.1.3", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "lodash": "^4.17.11", + "merkle-patricia-tree": "^4.1.0", + "mnemonist": "^0.38.0", + "mocha": "^7.1.2", + "node-fetch": "^2.6.0", + "qs": "^6.7.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "slash": "^3.0.0", + "solc": "0.7.3", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "true-case-path": "^2.2.1", + "tsort": "0.0.1", + "uuid": "^3.3.2", + "ws": "^7.2.1" + }, + "dependencies": { + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mocha": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.5", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "requires": { + "picomatch": "^2.0.4" + } + } + } + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "solc": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", + "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "requires": { + "command-exists": "^1.2.8", + "commander": "3.0.2", + "follow-redirects": "^1.12.1", + "fs-extra": "^0.30.0", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "require-from-string": "^2.0.0", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "harmony-reflect": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz", @@ -21118,6 +21836,11 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, + "immutable": { + "version": "4.0.0-rc.12", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", + "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==" + }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -21413,6 +22136,14 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, + "io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "requires": { + "fp-ts": "^1.0.0" + } + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -21680,7 +22411,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -21822,8 +22552,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { "version": "1.0.2", @@ -24611,7 +25340,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, "requires": { "graceful-fs": "^4.1.9" } @@ -24831,11 +25559,55 @@ } } }, + "level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "requires": { + "buffer": "^5.6.0" + } + }, "level-concat-iterator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" }, + "level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, + "level-mem": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", + "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", + "requires": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + } + }, + "level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "requires": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + } + }, "level-supports": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", @@ -24851,6 +25623,28 @@ } } }, + "level-ws": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", + "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + } + }, + "levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -25349,7 +26143,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, "requires": { "chalk": "^2.4.2" } @@ -25505,6 +26298,11 @@ "yallist": "^3.0.2" } }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -25906,6 +26704,38 @@ "p-is-promise": "^2.0.0" } }, + "memdown": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", + "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", + "requires": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" + } + } + }, "memoize-one": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", @@ -25962,8 +26792,7 @@ "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", - "dev": true + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" }, "meow": { "version": "7.0.1", @@ -26235,6 +27064,20 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "merkle-patricia-tree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.1.0.tgz", + "integrity": "sha512-vmP1J7FwIpprFMVjjSMM1JAwFce85Q+tp0TYIedYv8qaMh2oLUZ3ETXn9wbgi9S6elySzKzGa+Ai6VNKGEwSlg==", + "requires": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.0.8", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "rlp": "^2.2.3", + "semaphore-async-await": "^1.5.1" + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -26661,6 +27504,14 @@ "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", "dev": true }, + "mnemonist": { + "version": "0.38.3", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", + "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", + "requires": { + "obliterator": "^1.6.1" + } + }, "mocha": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", @@ -32763,6 +33614,11 @@ "has": "^1.0.3" } }, + "obliterator": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", + "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==" + }, "oboe": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz", @@ -33611,8 +34467,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { "version": "0.1.5", @@ -36434,14 +37289,12 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "1.0.1", @@ -36615,7 +37468,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -37506,8 +38358,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -38035,7 +38886,6 @@ "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -38044,8 +38894,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -38235,6 +39084,21 @@ "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" + } + } + }, "standard": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/standard/-/standard-12.0.1.tgz", @@ -38944,7 +39808,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -38953,14 +39816,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -39975,7 +40836,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -40172,6 +41032,11 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "true-case-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", + "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" + }, "truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -40344,6 +41209,11 @@ } } }, + "tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=" + }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", @@ -40372,6 +41242,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "tweetnacl-util": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" + }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -42806,14 +43681,12 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -43276,11 +44149,15 @@ "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yaeti": { "version": "0.0.6", @@ -43377,7 +44254,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, "requires": { "flat": "^4.1.0", "lodash": "^4.17.15", @@ -43387,14 +44263,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -43405,7 +44279,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -43413,14 +44286,12 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -43430,7 +44301,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -43439,7 +44309,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -43447,20 +44316,17 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -43471,7 +44337,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -43480,7 +44345,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -43491,7 +44355,6 @@ "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -43509,7 +44372,6 @@ "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/package.json b/package.json index 0e3b262c5e..26bf88ca92 100644 --- a/package.json +++ b/package.json @@ -155,6 +155,7 @@ "ethers": "^5.1.4", "express-ws": "^4.0.0", "fs-extra": "^3.0.1", + "hardhat": "^2.2.1", "http-server": "^0.11.1", "isbinaryfile": "^3.0.2", "jquery": "^3.3.1", From d79bdab5f5a19acb7524fe9277e702053fe5783d Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 11 May 2021 14:53:30 +0530 Subject: [PATCH 169/199] hardhat websocket plugin --- .../remix-ide/src/app/files/hardhat-handle.js | 18 ++++++ .../remix-ide/src/app/files/remixDProvider.js | 5 -- apps/remix-ide/src/app/files/remixd-handle.js | 2 +- .../src/app/tabs/compileTab/compileTab.js | 2 +- libs/remixd/src/bin/remixd.ts | 8 ++- libs/remixd/src/index.ts | 4 +- libs/remixd/src/serviceList.ts | 1 + libs/remixd/src/services/hardhatClient.ts | 55 +++++++++++++++++++ libs/remixd/src/services/remixdClient.ts | 8 +-- 9 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 apps/remix-ide/src/app/files/hardhat-handle.js create mode 100644 libs/remixd/src/services/hardhatClient.ts diff --git a/apps/remix-ide/src/app/files/hardhat-handle.js b/apps/remix-ide/src/app/files/hardhat-handle.js new file mode 100644 index 0000000000..9f95211b76 --- /dev/null +++ b/apps/remix-ide/src/app/files/hardhat-handle.js @@ -0,0 +1,18 @@ +import { WebsocketPlugin } from '@remixproject/engine-web' +import * as packageJson from '../../../../../package.json' + +const profile = { + name: 'hardhat', + displayName: 'Hardhat', + url: 'ws://127.0.0.1:65522', + methods: ['compile'], + description: 'Using Remixd daemon, allow to access hardhat API', + kind: 'other', + version: packageJson.version +} + +export class hardhatHandle extends WebsocketPlugin { + constructor () { + super(profile) + } +} diff --git a/apps/remix-ide/src/app/files/remixDProvider.js b/apps/remix-ide/src/app/files/remixDProvider.js index 044e46a165..60337c11e4 100644 --- a/apps/remix-ide/src/app/files/remixDProvider.js +++ b/apps/remix-ide/src/app/files/remixDProvider.js @@ -50,11 +50,6 @@ module.exports = class RemixDProvider extends FileProvider { return this._isReady } - async compileWithHardhat () { - console.log('Inside compileWithHardhat, calling hardhatCompile using _appManager') - return await this._appManager.call('remixd', 'hardhatCompile', {}) - } - close (cb) { this._isReady = false cb() diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index e8145f58d8..3ec635040c 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -22,7 +22,7 @@ const profile = { name: 'remixd', displayName: 'RemixD', url: 'ws://127.0.0.1:65520', - methods: ['folderIsReadOnly', 'hardhatCompile', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir'], + methods: ['folderIsReadOnly', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir'], events: [], description: 'Using Remixd daemon, allow to access file system', kind: 'other', diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index ea7377c3fd..c80514370b 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -83,7 +83,7 @@ class CompileTab { console.log('mode is - ', this.fileManager.mode) if(this.fileManager.mode === 'localhost') { console.log('calling compilehardhat') - this.fileProvider.compileWithHardhat().then(console.log) + // this.fileProvider.compileWithHardhat().then(console.log) } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() diff --git a/libs/remixd/src/bin/remixd.ts b/libs/remixd/src/bin/remixd.ts index 5b7076fd0d..8d2ebe9bb2 100644 --- a/libs/remixd/src/bin/remixd.ts +++ b/libs/remixd/src/bin/remixd.ts @@ -24,16 +24,18 @@ async function warnLatestVersion () { const services = { git: (readOnly: boolean) => new servicesList.GitClient(readOnly), + hardhat: (readOnly: boolean) => new servicesList.HardhatClient(readOnly), folder: (readOnly: boolean) => new servicesList.Sharedfolder(readOnly) } const ports = { git: 65521, + hardhat: 65522, folder: 65520 } const killCallBack: Array = [] -function startService (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder) => void) { +function startService (service: S, callback: (ws: WS, sharedFolderClient: servicesList.Sharedfolder) => void) { const socket = new WebSocket(ports[service], { remixIdeUrl: program.remixIde }, () => services[service](program.readOnly || false)) socket.start(callback) killCallBack.push(socket.close.bind(socket)) @@ -78,6 +80,10 @@ function startService (service: S, callback: (ws: WS sharedFolderClient.setupNotifications(program.sharedFolder) sharedFolderClient.sharedFolder(program.sharedFolder) }) + startService('hardhat', (ws: WS, sharedFolderClient: servicesList.Sharedfolder) => { + sharedFolderClient.setWebSocket(ws) + sharedFolderClient.sharedFolder(program.sharedFolder) + }) /* startService('git', (ws: WS, sharedFolderClient: servicesList.Sharedfolder) => { sharedFolderClient.setWebSocket(ws) diff --git a/libs/remixd/src/index.ts b/libs/remixd/src/index.ts index 04725c14f2..849f35b6fa 100644 --- a/libs/remixd/src/index.ts +++ b/libs/remixd/src/index.ts @@ -1,6 +1,7 @@ 'use strict' import { RemixdClient as sharedFolder } from './services/remixdClient' import { GitClient } from './services/gitClient' +import { HardhatClient } from './services/hardhatClient' import Websocket from './websocket' import * as utils from './utils' @@ -9,6 +10,7 @@ module.exports = { utils, services: { sharedFolder, - GitClient + GitClient, + HardhatClient } } diff --git a/libs/remixd/src/serviceList.ts b/libs/remixd/src/serviceList.ts index 5db445ee66..19d613b7c2 100644 --- a/libs/remixd/src/serviceList.ts +++ b/libs/remixd/src/serviceList.ts @@ -1,2 +1,3 @@ export { RemixdClient as Sharedfolder } from './services/remixdClient' export { GitClient } from './services/gitClient' +export { HardhatClient } from './services/hardhatClient' diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts new file mode 100644 index 0000000000..3b86a2e637 --- /dev/null +++ b/libs/remixd/src/services/hardhatClient.ts @@ -0,0 +1,55 @@ +import * as WS from 'ws' // eslint-disable-line +import { PluginClient } from '@remixproject/plugin' +const { spawn } = require('child_process') + +export class HardhatClient extends PluginClient { + methods: Array + websocket: WS + currentSharedFolder: string + + constructor (private readOnly = false) { + super() + console.log('this is HardhatClient constructor') + this.methods = ['compile'] + } + + setWebSocket (websocket: WS): void { + this.websocket = websocket + } + + sharedFolder (currentSharedFolder: string): void { + this.currentSharedFolder = currentSharedFolder + } + + compile (cmd: string) { + // assertCommand(cmd) + const options = { cwd: this.currentSharedFolder, shell: true } + const child = spawn(cmd, options) + let result = '' + let error = '' + return new Promise((resolve, reject) => { + child.stdout.on('data', (data) => { + console.log('data in compile in HardhatClient', data) + result += data.toString() + }) + child.stderr.on('data', (err) => { + error += err.toString() + }) + child.on('close', () => { + if (error) reject(error) + else resolve(result) + }) + }) + } +} + +/** + * Validate that command can be run by service + * @param cmd + */ +function assertCommand (cmd) { + const regex = '^hardhat\\s[^&|;]*$' + if (!RegExp(regex).test(cmd)) { // git then space and then everything else + throw new Error('Invalid command for service!') + } +} diff --git a/libs/remixd/src/services/remixdClient.ts b/libs/remixd/src/services/remixdClient.ts index 42752c3adc..7fb5062335 100644 --- a/libs/remixd/src/services/remixdClient.ts +++ b/libs/remixd/src/services/remixdClient.ts @@ -15,7 +15,7 @@ export class RemixdClient extends PluginClient { constructor (private readOnly = false) { super() - this.methods = ['folderIsReadOnly', 'hardhatCompile', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir', 'canDeactivate'] + this.methods = ['folderIsReadOnly', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir', 'canDeactivate'] } setWebSocket (websocket: WS): void { @@ -27,12 +27,6 @@ export class RemixdClient extends PluginClient { if (this.isLoaded) this.emit('rootFolderChanged') } - async hardhatCompile() { - console.log('inside hardhatCompile') - console.log('here is hre-->', hre.tasks) - // await hre.tasks.accounts.action(); - } - list (): Filelist { try { return utils.walkSync(this.currentSharedFolder, {}, this.currentSharedFolder) From 234c362a91de8f341c15414155bdb9a91c0f43da Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 11 May 2021 21:05:00 +0530 Subject: [PATCH 170/199] compile using hardhat --- apps/remix-ide/src/app.js | 3 ++- apps/remix-ide/src/app/files/fileManager.js | 5 +++++ apps/remix-ide/src/app/files/hardhat-handle.js | 2 +- apps/remix-ide/src/app/files/remixd-handle.js | 2 +- apps/remix-ide/src/app/panels/file-panel.js | 2 ++ apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 2 +- libs/remixd/src/services/remixdClient.ts | 1 - 7 files changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index b05b4ef488..a22f388004 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -436,7 +436,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org analysis, test, filePanel.remixdHandle, - filePanel.gitHandle + filePanel.gitHandle, + filePanel.hardhatHandle ]) if (isElectron()) { diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index fd74b1722d..10f89a4759 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -57,6 +57,11 @@ class FileManager extends Plugin { this.mode = mode } + async compileWithHardhat (cmd) { + console.log('Inside compileWithHardhat, calling hardhat compile using appManager') + return await this.appManager.call('hardhat', 'compile', cmd) + } + limitPluginScope (path) { return path.replace(/^\/browser\//, '').replace(/^browser\//, '') // forbids plugin to access the root filesystem } diff --git a/apps/remix-ide/src/app/files/hardhat-handle.js b/apps/remix-ide/src/app/files/hardhat-handle.js index 9f95211b76..e9e8b770ef 100644 --- a/apps/remix-ide/src/app/files/hardhat-handle.js +++ b/apps/remix-ide/src/app/files/hardhat-handle.js @@ -11,7 +11,7 @@ const profile = { version: packageJson.version } -export class hardhatHandle extends WebsocketPlugin { +export class HardhatHandle extends WebsocketPlugin { constructor () { super(profile) } diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index 3ec635040c..8b8cfd8b98 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -81,7 +81,7 @@ export class RemixdHandle extends WebsocketPlugin { } }, 3000) this.locahostProvider.init(() => {}) - // this.call('manager', 'activatePlugin', 'git') + this.call('manager', 'activatePlugin', 'hardhat') } } if (this.locahostProvider.isConnected()) { diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 991108285c..6bdef578d6 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -9,6 +9,7 @@ import { checkSpecialChars, checkSlash } from '../../lib/helper' var EventManager = require('../../lib/events') var { RemixdHandle } = require('../files/remixd-handle.js') var { GitHandle } = require('../files/git-handle.js') +var { HardhatHandle } = require('../files/hardhat-handle.js') var globalRegistry = require('../../global/registry') var examples = require('../editor/examples') var GistHandler = require('../../lib/gist-handler') @@ -60,6 +61,7 @@ module.exports = class Filepanel extends ViewPlugin { this.remixdHandle = new RemixdHandle(this._deps.fileProviders.localhost, appManager) this.gitHandle = new GitHandle() + this.hardhatHandle = new HardhatHandle() this.registeredMenuItems = [] this.request = {} this.workspaces = [] diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index c80514370b..2d2ff32217 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -83,7 +83,7 @@ class CompileTab { console.log('mode is - ', this.fileManager.mode) if(this.fileManager.mode === 'localhost') { console.log('calling compilehardhat') - // this.fileProvider.compileWithHardhat().then(console.log) + this.fileManager.compileWithHardhat('npx hardhat compile').then(console.log) } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() diff --git a/libs/remixd/src/services/remixdClient.ts b/libs/remixd/src/services/remixdClient.ts index 7fb5062335..31588628ea 100644 --- a/libs/remixd/src/services/remixdClient.ts +++ b/libs/remixd/src/services/remixdClient.ts @@ -5,7 +5,6 @@ import * as utils from '../utils' import * as chokidar from 'chokidar' import * as fs from 'fs-extra' import * as isbinaryfile from 'isbinaryfile' -const hre = require("hardhat"); export class RemixdClient extends PluginClient { methods: Array From 2c9149e67ae81291353cad7870674016eae26ebe Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 11 May 2021 21:07:48 +0530 Subject: [PATCH 171/199] linting fix --- apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index 2d2ff32217..87cdc1b9a1 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -81,7 +81,7 @@ class CompileTab { runCompiler () { try { console.log('mode is - ', this.fileManager.mode) - if(this.fileManager.mode === 'localhost') { + if (this.fileManager.mode === 'localhost') { console.log('calling compilehardhat') this.fileManager.compileWithHardhat('npx hardhat compile').then(console.log) } From 25edaefe269986509026af6ce7bca242e021465e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 12 May 2021 10:10:40 +0530 Subject: [PATCH 172/199] assertCommand removed --- libs/remixd/src/services/hardhatClient.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts index 3b86a2e637..e2f58ee624 100644 --- a/libs/remixd/src/services/hardhatClient.ts +++ b/libs/remixd/src/services/hardhatClient.ts @@ -22,7 +22,6 @@ export class HardhatClient extends PluginClient { } compile (cmd: string) { - // assertCommand(cmd) const options = { cwd: this.currentSharedFolder, shell: true } const child = spawn(cmd, options) let result = '' @@ -42,14 +41,3 @@ export class HardhatClient extends PluginClient { }) } } - -/** - * Validate that command can be run by service - * @param cmd - */ -function assertCommand (cmd) { - const regex = '^hardhat\\s[^&|;]*$' - if (!RegExp(regex).test(cmd)) { // git then space and then everything else - throw new Error('Invalid command for service!') - } -} From 29b4eb7ef71510bc71b20b16eeb9410dec8028e7 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 12 May 2021 11:23:13 +0530 Subject: [PATCH 173/199] compiler configuration from remix IDE --- apps/remix-ide/src/app/files/fileManager.js | 7 ++++--- .../remix-ide/src/app/tabs/compileTab/compileTab.js | 13 ++++++++++++- libs/remixd/src/services/hardhatClient.ts | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index 10f89a4759..0ba692c32e 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -57,9 +57,10 @@ class FileManager extends Plugin { this.mode = mode } - async compileWithHardhat (cmd) { - console.log('Inside compileWithHardhat, calling hardhat compile using appManager') - return await this.appManager.call('hardhat', 'compile', cmd) + async compileWithHardhat (fileContent) { + const configFilePath = 'remixCompiler.config.js' + this.setFileContent(configFilePath, fileContent) + return await this.appManager.call('hardhat', 'compile', configFilePath) } limitPluginScope (path) { diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index 87cdc1b9a1..b4367cbb70 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -83,7 +83,18 @@ class CompileTab { console.log('mode is - ', this.fileManager.mode) if (this.fileManager.mode === 'localhost') { console.log('calling compilehardhat') - this.fileManager.compileWithHardhat('npx hardhat compile').then(console.log) + const { currentVersion, optimize, runs } = this.compiler.state + const fileContent = `module.exports = { + solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}', + settings: { + optimizer: { + enabled: ${optimize}, + runs: ${runs} + } + } + } + ` + this.fileManager.compileWithHardhat(fileContent).then(console.log) } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts index e2f58ee624..b03fa19cab 100644 --- a/libs/remixd/src/services/hardhatClient.ts +++ b/libs/remixd/src/services/hardhatClient.ts @@ -21,7 +21,8 @@ export class HardhatClient extends PluginClient { this.currentSharedFolder = currentSharedFolder } - compile (cmd: string) { + compile (configPath: string) { + const cmd = `npx hardhat compile --config ${configPath}` const options = { cwd: this.currentSharedFolder, shell: true } const child = spawn(cmd, options) let result = '' From 465bd76fd5eece496bac041c3cb4cf66d432491e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Wed, 12 May 2021 21:45:03 +0530 Subject: [PATCH 174/199] enable checkbox UI --- apps/remix-ide/src/app/tabs/compile-tab.js | 6 ++++++ apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 7 ++++++- .../remix-ide/src/app/tabs/compileTab/compilerContainer.js | 5 +++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 12b93ff594..1ced69c7d7 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -90,6 +90,12 @@ class CompileTab extends ViewPlugin { */ listenToEvents () { + this.on('filePanel', 'setWorkspace', (workspace) => { + this.compileTabLogic.isHardhatProject().then((result) => { + if (result) this.compilerContainer.hardhatCompilation.style.display = 'flex' + }) + }) + this.data.eventHandlers.onContentChanged = () => { this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' }) } diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index b4367cbb70..c469870904 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -78,11 +78,16 @@ class CompileTab { }) } + async isHardhatProject () { + if (this.fileManager.mode === 'localhost') { + return await this.fileManager.exists('hardhat.config.js') + } else return false + } + runCompiler () { try { console.log('mode is - ', this.fileManager.mode) if (this.fileManager.mode === 'localhost') { - console.log('calling compilehardhat') const { currentVersion, optimize, runs } = this.compiler.state const fileContent = `module.exports = { solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}', diff --git a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js index 88880bff22..ac8b0a0d1e 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js @@ -183,6 +183,10 @@ class CompilerContainer { } }) + this.hardhatCompilation = yo`` this._view.warnCompilationSlow = yo`` this._view.compileIcon = yo`` this._view.autoCompile = yo` this.updateAutoCompile()} data-id="compilerContainerAutoCompile" id="autoCompile" type="checkbox" title="Auto compile">` @@ -299,6 +303,7 @@ class CompilerContainer {
+ ${this.hardhatCompilation} ${this._view.compilationButton} From ed3abb38a84ce341b4b99cb9ccdb988981e591cb Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 13 May 2021 10:12:47 +0530 Subject: [PATCH 175/199] compile only when enabled --- apps/remix-ide/src/app/tabs/compile-tab.js | 1 + apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 4 ++-- .../src/app/tabs/compileTab/compilerContainer.js | 9 +++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 1ced69c7d7..930430260d 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -93,6 +93,7 @@ class CompileTab extends ViewPlugin { this.on('filePanel', 'setWorkspace', (workspace) => { this.compileTabLogic.isHardhatProject().then((result) => { if (result) this.compilerContainer.hardhatCompilation.style.display = 'flex' + else this.compilerContainer.hardhatCompilation.style.display = 'none' }) }) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index c469870904..d6359836dd 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -84,10 +84,10 @@ class CompileTab { } else return false } - runCompiler () { + runCompiler (hhCompilation) { try { console.log('mode is - ', this.fileManager.mode) - if (this.fileManager.mode === 'localhost') { + if (this.fileManager.mode === 'localhost' && hhCompilation) { const { currentVersion, optimize, runs } = this.compiler.state const fileContent = `module.exports = { solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}', diff --git a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js index ac8b0a0d1e..73d0802bf4 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js @@ -15,6 +15,7 @@ class CompilerContainer { this.editor = editor this.config = config this.queryParams = queryParams + this.hhCompilation = false this.data = { hideWarnings: config.get('hideWarnings') || false, @@ -184,7 +185,7 @@ class CompilerContainer { }) this.hardhatCompilation = yo`` this._view.warnCompilationSlow = yo`` @@ -331,12 +332,16 @@ class CompilerContainer { this.config.set('autoCompile', this._view.autoCompile.checked) } + updatehhCompilation (event) { + this.hhCompilation = event.target.checked + } + compile (event) { const currentFile = this.config.get('currentFile') if (!this.isSolFileSelected()) return this._setCompilerVersionFromPragma(currentFile) - this.compileTabLogic.runCompiler() + this.compileTabLogic.runCompiler(this.hhCompilation) } compileIfAutoCompileOn () { From 3dd02801d7e6baeb3c16b0422c903134086e5fdb Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 13 May 2021 10:46:47 +0530 Subject: [PATCH 176/199] do not compile in read only mode --- libs/remixd/src/services/hardhatClient.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts index b03fa19cab..216e853a0a 100644 --- a/libs/remixd/src/services/hardhatClient.ts +++ b/libs/remixd/src/services/hardhatClient.ts @@ -9,7 +9,6 @@ export class HardhatClient extends PluginClient { constructor (private readOnly = false) { super() - console.log('this is HardhatClient constructor') this.methods = ['compile'] } @@ -22,12 +21,13 @@ export class HardhatClient extends PluginClient { } compile (configPath: string) { - const cmd = `npx hardhat compile --config ${configPath}` - const options = { cwd: this.currentSharedFolder, shell: true } - const child = spawn(cmd, options) - let result = '' - let error = '' return new Promise((resolve, reject) => { + if (this.readOnly) return reject(new Error('Cannot run Hardhat compilation in read-only mode')) + const cmd = `npx hardhat compile --config ${configPath}` + const options = { cwd: this.currentSharedFolder, shell: true } + const child = spawn(cmd, options) + let result = '' + let error = '' child.stdout.on('data', (data) => { console.log('data in compile in HardhatClient', data) result += data.toString() From 2ead1c597fc85509608aa3ab1db59728290184f3 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 13 May 2021 10:56:45 +0530 Subject: [PATCH 177/199] hardhat npm dep removed --- package-lock.json | 1008 ++++----------------------------------------- package.json | 1 - 2 files changed, 73 insertions(+), 936 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad004a82fc..d74204bd8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7796,112 +7796,6 @@ "any-observable": "^0.3.0" } }, - "@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "requires": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "requires": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "dependencies": { - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - } - } - }, - "@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "requires": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - } - }, - "@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==" - }, - "@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "requires": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -7916,11 +7810,6 @@ "type-detect": "4.0.8" } }, - "@solidity-parser/parser": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz", - "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==" - }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", @@ -8410,11 +8299,6 @@ "@types/node": "*" } }, - "@types/lru-cache": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", - "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==" - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -9092,22 +8976,11 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, "requires": { "event-target-shim": "^5.0.0" } }, - "abstract-leveldown": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", - "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -9208,11 +9081,6 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, - "adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" - }, "aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", @@ -11309,7 +11177,8 @@ "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true }, "bindings": { "version": "1.5.0", @@ -11691,7 +11560,8 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "browserify": { "version": "16.5.1", @@ -12601,7 +12471,8 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "buffer-indexof": { "version": "1.1.1", @@ -12750,6 +12621,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -13546,7 +13418,8 @@ "command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true }, "commander": { "version": "2.20.3", @@ -15044,7 +14917,8 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true }, "decamelize-keys": { "version": "1.1.0", @@ -15365,29 +15239,6 @@ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - } - } - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -16033,7 +15884,8 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "emojis-list": { "version": "3.0.0", @@ -16071,17 +15923,6 @@ } } }, - "encoding-down": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", - "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "requires": { - "abstract-leveldown": "^6.2.1", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0" - } - }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -16101,21 +15942,6 @@ "tapable": "^1.0.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" - } - } - }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -16131,7 +15957,8 @@ "env-paths": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", - "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==" + "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", + "dev": true }, "envinfo": { "version": "7.5.1", @@ -16998,38 +16825,6 @@ } } }, - "eth-sig-util": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.5.4.tgz", - "integrity": "sha512-aCMBwp8q/4wrW4QLsF/HYBOSA7TpLKmkVwP3pYQNkEEseW2Rr8Z5Uxc9/h6HX+OG3tuHo+2bINVSihIeBfym6A==", - "requires": { - "ethereumjs-abi": "0.6.8", - "ethereumjs-util": "^5.1.1", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", - "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "^0.1.3", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - } - } - }, "ethereum-bloom-filters": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", @@ -17088,31 +16883,6 @@ } } }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, "ethereumjs-common": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.1.tgz", @@ -17244,7 +17014,8 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true }, "eventemitter2": { "version": "6.4.2", @@ -18120,6 +17891,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, "requires": { "is-buffer": "~2.0.3" }, @@ -18127,7 +17899,8 @@ "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true } } }, @@ -18334,11 +18107,6 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, - "fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" - }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -19383,6 +19151,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -20082,6 +19851,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -20487,7 +20257,8 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true }, "growly": { "version": "1.3.0", @@ -20823,495 +20594,6 @@ "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, - "hardhat": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.2.1.tgz", - "integrity": "sha512-8s7MtGXdh0NDwQKdlA8m8QdloVIN1+hv5aFpn0G5Ljj9vfNY9kUoc0a9pMboeGbd9WrS+XrZs5YlsPgQjaW/Tg==", - "requires": { - "@ethereumjs/block": "^3.2.1", - "@ethereumjs/blockchain": "^5.2.1", - "@ethereumjs/common": "^2.2.0", - "@ethereumjs/tx": "^3.1.3", - "@ethereumjs/vm": "^5.3.2", - "@sentry/node": "^5.18.1", - "@solidity-parser/parser": "^0.11.0", - "@types/bn.js": "^5.1.0", - "@types/lru-cache": "^5.1.0", - "abort-controller": "^3.0.0", - "adm-zip": "^0.4.16", - "ansi-escapes": "^4.3.0", - "chalk": "^2.4.2", - "chokidar": "^3.4.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "eth-sig-util": "^2.5.2", - "ethereum-cryptography": "^0.1.2", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.0.10", - "find-up": "^2.1.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "glob": "^7.1.3", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "lodash": "^4.17.11", - "merkle-patricia-tree": "^4.1.0", - "mnemonist": "^0.38.0", - "mocha": "^7.1.2", - "node-fetch": "^2.6.0", - "qs": "^6.7.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "slash": "^3.0.0", - "solc": "0.7.3", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "true-case-path": "^2.2.1", - "tsort": "0.0.1", - "uuid": "^3.3.2", - "ws": "^7.2.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "requires": { - "picomatch": "^2.0.4" - } - } - } - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "requires": { - "command-exists": "^1.2.8", - "commander": "3.0.2", - "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "harmony-reflect": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz", @@ -21836,11 +21118,6 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, - "immutable": { - "version": "4.0.0-rc.12", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.12.tgz", - "integrity": "sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A==" - }, "import-cwd": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", @@ -22136,14 +21413,6 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "requires": { - "fp-ts": "^1.0.0" - } - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -22411,6 +21680,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -22552,7 +21822,8 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true }, "is-function": { "version": "1.0.2", @@ -25340,6 +24611,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, "requires": { "graceful-fs": "^4.1.9" } @@ -25559,55 +24831,11 @@ } } }, - "level-codec": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", - "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "requires": { - "buffer": "^5.6.0" - } - }, "level-concat-iterator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-mem": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", - "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", - "requires": { - "level-packager": "^5.0.3", - "memdown": "^5.0.0" - } - }, - "level-packager": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", - "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "requires": { - "encoding-down": "^6.3.0", - "levelup": "^4.3.2" - } - }, "level-supports": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", @@ -25623,28 +24851,6 @@ } } }, - "level-ws": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", - "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^3.1.0", - "xtend": "^4.0.1" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -26143,6 +25349,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, "requires": { "chalk": "^2.4.2" } @@ -26298,11 +25505,6 @@ "yallist": "^3.0.2" } }, - "lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" - }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -26704,38 +25906,6 @@ "p-is-promise": "^2.0.0" } }, - "memdown": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", - "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", - "requires": { - "abstract-leveldown": "~6.2.1", - "functional-red-black-tree": "~1.0.1", - "immediate": "~3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - } - } - }, "memoize-one": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", @@ -26792,7 +25962,8 @@ "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true }, "meow": { "version": "7.0.1", @@ -27064,20 +26235,6 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, - "merkle-patricia-tree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.1.0.tgz", - "integrity": "sha512-vmP1J7FwIpprFMVjjSMM1JAwFce85Q+tp0TYIedYv8qaMh2oLUZ3ETXn9wbgi9S6elySzKzGa+Ai6VNKGEwSlg==", - "requires": { - "@types/levelup": "^4.3.0", - "ethereumjs-util": "^7.0.8", - "level-mem": "^5.0.1", - "level-ws": "^2.0.0", - "readable-stream": "^3.6.0", - "rlp": "^2.2.3", - "semaphore-async-await": "^1.5.1" - } - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -27504,14 +26661,6 @@ "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", "dev": true }, - "mnemonist": { - "version": "0.38.3", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.3.tgz", - "integrity": "sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==", - "requires": { - "obliterator": "^1.6.1" - } - }, "mocha": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.0.1.tgz", @@ -33614,11 +32763,6 @@ "has": "^1.0.3" } }, - "obliterator": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-1.6.1.tgz", - "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==" - }, "oboe": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.4.tgz", @@ -34467,7 +33611,8 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true }, "osenv": { "version": "0.1.5", @@ -37289,12 +36434,14 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, "require-main-filename": { "version": "1.0.1", @@ -37468,6 +36615,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -38358,7 +37506,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "set-immediate-shim": { "version": "1.0.1", @@ -38886,6 +38035,7 @@ "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -38894,7 +38044,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -39084,21 +38235,6 @@ "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, - "stacktrace-parser": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", - "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "requires": { - "type-fest": "^0.7.1" - }, - "dependencies": { - "type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" - } - } - }, "standard": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/standard/-/standard-12.0.1.tgz", @@ -39808,6 +38944,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -39816,12 +38953,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -40836,6 +39975,7 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -41032,11 +40172,6 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, - "true-case-path": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", - "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" - }, "truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -41209,11 +40344,6 @@ } } }, - "tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=" - }, "tsutils": { "version": "3.17.1", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", @@ -41242,11 +40372,6 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", @@ -43681,12 +42806,14 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -44149,15 +43276,11 @@ "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", "dev": true }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true }, "yaeti": { "version": "0.0.6", @@ -44254,6 +43377,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, "requires": { "flat": "^4.1.0", "lodash": "^4.17.15", @@ -44263,12 +43387,14 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -44279,6 +43405,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -44286,12 +43413,14 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -44301,6 +43430,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -44309,6 +43439,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -44316,17 +43447,20 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -44337,6 +43471,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -44345,6 +43480,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -44355,6 +43491,7 @@ "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -44372,6 +43509,7 @@ "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/package.json b/package.json index 26bf88ca92..0e3b262c5e 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,6 @@ "ethers": "^5.1.4", "express-ws": "^4.0.0", "fs-extra": "^3.0.1", - "hardhat": "^2.2.1", "http-server": "^0.11.1", "isbinaryfile": "^3.0.2", "jquery": "^3.3.1", From 5ed00420b08f43220320ffe47c8373cda1dc657e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 13 May 2021 12:07:11 +0530 Subject: [PATCH 178/199] logging for hardhat conmpilation --- libs/remixd/src/services/hardhatClient.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts index 216e853a0a..7c2efd463a 100644 --- a/libs/remixd/src/services/hardhatClient.ts +++ b/libs/remixd/src/services/hardhatClient.ts @@ -22,17 +22,22 @@ export class HardhatClient extends PluginClient { compile (configPath: string) { return new Promise((resolve, reject) => { - if (this.readOnly) return reject(new Error('Cannot run Hardhat compilation in read-only mode')) + if (this.readOnly) { + const errMsg = '[Hardhat Compilation]: Cannot compile in read-only mode' + console.log('\x1b[31m%s\x1b[0m', `${errMsg}`) + return reject(new Error(errMsg)) + } const cmd = `npx hardhat compile --config ${configPath}` const options = { cwd: this.currentSharedFolder, shell: true } const child = spawn(cmd, options) let result = '' let error = '' child.stdout.on('data', (data) => { - console.log('data in compile in HardhatClient', data) + console.log('\x1b[32m%s\x1b[0m', `[Hardhat Compilation]: ${data.toString()}`) result += data.toString() }) child.stderr.on('data', (err) => { + console.log('\x1b[31m%s\x1b[0m', `[Hardhat Compilation]: ${err.toString()}`) error += err.toString() }) child.on('close', () => { From d311842fdec9ff93caa61876f150d74de3ba76fc Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 13 May 2021 12:24:30 +0530 Subject: [PATCH 179/199] removed console --- apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index d6359836dd..ad1be493ed 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -86,7 +86,6 @@ class CompileTab { runCompiler (hhCompilation) { try { - console.log('mode is - ', this.fileManager.mode) if (this.fileManager.mode === 'localhost' && hhCompilation) { const { currentVersion, optimize, runs } = this.compiler.state const fileContent = `module.exports = { From 06e0fc129c58012626db2cdaf39a99e62b71689e Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 11:33:48 +0530 Subject: [PATCH 180/199] compileWithHardhat moved to compileTab --- apps/remix-ide/src/app/files/fileManager.js | 6 ------ apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 4 +++- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index 0ba692c32e..fd74b1722d 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -57,12 +57,6 @@ class FileManager extends Plugin { this.mode = mode } - async compileWithHardhat (fileContent) { - const configFilePath = 'remixCompiler.config.js' - this.setFileContent(configFilePath, fileContent) - return await this.appManager.call('hardhat', 'compile', configFilePath) - } - limitPluginScope (path) { return path.replace(/^\/browser\//, '').replace(/^browser\//, '') // forbids plugin to access the root filesystem } diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index ad1be493ed..69390b68e9 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -98,7 +98,9 @@ class CompileTab { } } ` - this.fileManager.compileWithHardhat(fileContent).then(console.log) + const configFilePath = 'remix-compiler.config.js' + this.fileManager.setFileContent(configFilePath, fileContent) + this.fileManager.appManager.call('hardhat', 'compile', configFilePath) } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() From 24a433b285120bcb837a72100e9f5a364df188f5 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 11:40:00 +0530 Subject: [PATCH 181/199] deactivatePlugin hardhat --- apps/remix-ide/src/app/files/remixd-handle.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/remix-ide/src/app/files/remixd-handle.js b/apps/remix-ide/src/app/files/remixd-handle.js index 8b8cfd8b98..a2d94eb3ea 100644 --- a/apps/remix-ide/src/app/files/remixd-handle.js +++ b/apps/remix-ide/src/app/files/remixd-handle.js @@ -39,6 +39,7 @@ export class RemixdHandle extends WebsocketPlugin { deactivate () { if (super.socket) super.deactivate() // this.appManager.deactivatePlugin('git') // plugin call doesn't work.. see issue https://github.com/ethereum/remix-plugin/issues/342 + this.appManager.deactivatePlugin('hardhat') this.locahostProvider.close((error) => { if (error) console.log(error) }) @@ -51,6 +52,7 @@ export class RemixdHandle extends WebsocketPlugin { async canceled () { // await this.appManager.deactivatePlugin('git') // plugin call doesn't work.. see issue https://github.com/ethereum/remix-plugin/issues/342 await this.appManager.deactivatePlugin('remixd') + await this.appManager.deactivatePlugin('hardhat') } /** From dcca04fa4ec87745b4ca7e04b6622831037ba33d Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 13:22:08 +0530 Subject: [PATCH 182/199] handled checkbox display on switching from localhost --- apps/remix-ide/src/app/tabs/compile-tab.js | 2 +- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 930430260d..790202688c 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -92,7 +92,7 @@ class CompileTab extends ViewPlugin { listenToEvents () { this.on('filePanel', 'setWorkspace', (workspace) => { this.compileTabLogic.isHardhatProject().then((result) => { - if (result) this.compilerContainer.hardhatCompilation.style.display = 'flex' + if (result && workspace.isLocalhost) this.compilerContainer.hardhatCompilation.style.display = 'flex' else this.compilerContainer.hardhatCompilation.style.display = 'none' }) }) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 883f5c1785..59bda8e917 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -91,7 +91,11 @@ export const Workspace = (props: WorkspaceProps) => { const localhostDisconnect = () => { if (state.currentWorkspace === LOCALHOST) setWorkspace(props.workspaces.length > 0 ? props.workspaces[0] : NO_WORKSPACE) - else setWorkspace(state.currentWorkspace) // Useful to switch to last selcted workspace when remixd is disconnected + // This should be removed some time after refactoring: https://github.com/ethereum/remix-project/issues/1197 + else { + setWorkspace(state.currentWorkspace) // Useful to switch to last selcted workspace when remixd is disconnected + props.fileManager.setMode('browser') + } } props.localhost.event.unregister('disconnected', localhostDisconnect) props.localhost.event.register('disconnected', localhostDisconnect) @@ -251,6 +255,7 @@ export const Workspace = (props: WorkspaceProps) => { // If 'connect to localhost' is clicked from home tab, mode is not 'localhost' if (props.fileManager.mode === 'localhost') { await setWorkspace(NO_WORKSPACE) + console.log('remixdExplorer.hide') props.fileManager.setMode('browser') setState(prevState => { return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } From cd3a35af3a007ace009944ae8c4bb2c2b934113c Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 18:44:03 +0530 Subject: [PATCH 183/199] updated hardhat API call --- apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index 69390b68e9..a3010dbc2d 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -100,7 +100,7 @@ class CompileTab { ` const configFilePath = 'remix-compiler.config.js' this.fileManager.setFileContent(configFilePath, fileContent) - this.fileManager.appManager.call('hardhat', 'compile', configFilePath) + this.fileManager.call('hardhat', 'compile', configFilePath) } this.fileManager.saveCurrentFile() this.miscApi.clearAnnotations() From 28ade3a200ef298336cc97c41232ae9ff92722f6 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 18:56:36 +0530 Subject: [PATCH 184/199] hardhat as dependentModule --- apps/remix-ide/src/remixAppManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index b495f53c81..650a87b14d 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -11,7 +11,7 @@ const requiredModules = [ // services + layout views + system views 'fileManager', 'contentImport', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp'] -const dependentModules = ['git'] // module which shouldn't be manually activated (e.g git is activated by remixd) +const dependentModules = ['git', 'hardhat'] // module which shouldn't be manually activated (e.g git is activated by remixd) export function isNative (name) { const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons'] From b402490e05126626273a6cad4867d3351cb6b8b7 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Tue, 18 May 2021 19:02:52 +0530 Subject: [PATCH 185/199] removed console --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 59bda8e917..3feff714c1 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -255,7 +255,6 @@ export const Workspace = (props: WorkspaceProps) => { // If 'connect to localhost' is clicked from home tab, mode is not 'localhost' if (props.fileManager.mode === 'localhost') { await setWorkspace(NO_WORKSPACE) - console.log('remixdExplorer.hide') props.fileManager.setMode('browser') setState(prevState => { return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false } From d62c6c4c08dc6797a07ce02b9e44781a80c3044a Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 18 May 2021 16:30:31 +0200 Subject: [PATCH 186/199] fix runCompiler parameter --- apps/remix-ide/src/app/tabs/compile-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 790202688c..fe49f60037 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -206,7 +206,7 @@ class CompileTab extends ViewPlugin { // ctrl+s or command+s if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) { e.preventDefault() - this.compileTabLogic.runCompiler() + this.compileTabLogic.runCompiler(this.compilerContainer.hhCompilation) } }) } From 39dc990573dc818be441c120faee2354c315191f Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 18 May 2021 16:31:47 +0200 Subject: [PATCH 187/199] make compileTabLogic a plugin --- apps/remix-ide/src/app.js | 1 + apps/remix-ide/src/app/tabs/compile-tab.js | 9 +++------ .../src/app/tabs/compileTab/compileTab.js | 19 ++++++++++++++----- apps/remix-ide/src/remixAppManager.js | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index a22f388004..93dd6753b5 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -431,6 +431,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org engine.register([ compileTab, + compileTab.compileTabLogic, run, debug, analysis, diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index fe49f60037..400ef25d76 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -65,15 +65,10 @@ class CompileTab extends ViewPlugin { eventHandlers: {}, loading: false } + this.compileTabLogic = new CompileTabLogic(this.queryParams, this.fileManager, this.editor, this.config, this.fileProvider, this.contentImport) } onActivationInternal () { - const miscApi = { - clearAnnotations: () => { - this.call('editor', 'clearAnnotations') - } - } - this.compileTabLogic = new CompileTabLogic(this.queryParams, this.fileManager, this.editor, this.config, this.fileProvider, this.contentImport, miscApi) this.compiler = this.compileTabLogic.compiler this.compileTabLogic.init() @@ -486,6 +481,7 @@ class CompileTab extends ViewPlugin { } onActivation () { + this.call('manager', 'activatePlugin', 'solidity-logic') this.listenToEvents() } @@ -499,6 +495,7 @@ class CompileTab extends ViewPlugin { this.fileManager.events.removeListener('noFileSelected', this.data.eventHandlers.onNoFileSelected) this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished) globalRegistry.get('themeModule').api.events.removeListener('themeChanged', this.data.eventHandlers.onThemeChanged) + this.call('manager', 'deactivatePlugin', 'solidity-logic') } } diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index a3010dbc2d..d5b1168b93 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -1,10 +1,19 @@ const EventEmitter = require('events') var Compiler = require('@remix-project/remix-solidity').Compiler +import * as packageJson from '../../../../../../package.json' +import { Plugin } from '@remixproject/engine' -class CompileTab { - constructor (queryParams, fileManager, editor, config, fileProvider, contentImport, miscApi) { +const profile = { + name: 'solidity-logic', + displayName: 'Solidity compiler logic', + description: 'Compile solidity contracts - Logic', + version: packageJson.version +} + +class CompileTab extends Plugin { + constructor (queryParams, fileManager, editor, config, fileProvider, contentImport) { + super(profile) this.event = new EventEmitter() - this.miscApi = miscApi this.queryParams = queryParams this.compilerImport = contentImport this.compiler = new Compiler((url, cb) => this.compilerImport.resolveAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message))) @@ -100,10 +109,10 @@ class CompileTab { ` const configFilePath = 'remix-compiler.config.js' this.fileManager.setFileContent(configFilePath, fileContent) - this.fileManager.call('hardhat', 'compile', configFilePath) + this.call('hardhat', 'compile', configFilePath) } this.fileManager.saveCurrentFile() - this.miscApi.clearAnnotations() + this.call('editor', 'clearAnnotations') var currentFile = this.config.get('currentFile') return this.compileFile(currentFile) } catch (err) { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 650a87b14d..7e7f9cd10f 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -14,7 +14,7 @@ const requiredModules = [ // services + layout views + system views const dependentModules = ['git', 'hardhat'] // module which shouldn't be manually activated (e.g git is activated by remixd) export function isNative (name) { - const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons'] + const nativePlugins = ['vyper', 'workshops', 'debugger', 'remixd', 'menuicons', 'solidity'] return nativePlugins.includes(name) || requiredModules.includes(name) } From 46d44abc9dadcc309ac78afaad05522fd42682b4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 18 May 2021 16:51:57 +0200 Subject: [PATCH 188/199] linting --- apps/remix-ide/src/app/tabs/compileTab/compileTab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index d5b1168b93..1e5de9d5c7 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -1,7 +1,7 @@ -const EventEmitter = require('events') -var Compiler = require('@remix-project/remix-solidity').Compiler import * as packageJson from '../../../../../../package.json' import { Plugin } from '@remixproject/engine' +const EventEmitter = require('events') +var Compiler = require('@remix-project/remix-solidity').Compiler const profile = { name: 'solidity-logic', From 3163c33464e7548f8fd21cd0cfdc939569da22e8 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 14 Apr 2021 21:43:59 +0200 Subject: [PATCH 189/199] refactors events --- apps/remix-ide/src/app/files/fileManager.js | 24 +++++++++---------- apps/remix-ide/src/app/files/fileProvider.js | 16 ++++++------- .../remix-ide/src/app/files/remixDProvider.js | 24 +++++++++---------- .../src/app/files/workspaceFileProvider.js | 4 ++-- .../workspace/src/lib/remix-ui-workspace.tsx | 12 +++++----- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/apps/remix-ide/src/app/files/fileManager.js b/apps/remix-ide/src/app/files/fileManager.js index fd74b1722d..44e33ff0d2 100644 --- a/apps/remix-ide/src/app/files/fileManager.js +++ b/apps/remix-ide/src/app/files/fileManager.js @@ -329,18 +329,18 @@ class FileManager extends Plugin { workspaceExplorer: this._components.registry.get('fileproviders/workspace').api, filesProviders: this._components.registry.get('fileproviders').api } - this._deps.browserExplorer.event.register('fileChanged', (path) => { this.fileChangedEvent(path) }) - this._deps.browserExplorer.event.register('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) - this._deps.localhostExplorer.event.register('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) - this._deps.browserExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) }) - this._deps.browserExplorer.event.register('fileAdded', (path) => { this.fileAddedEvent(path) }) - this._deps.localhostExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) }) - this._deps.localhostExplorer.event.register('errored', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) - this._deps.localhostExplorer.event.register('closed', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) - this._deps.workspaceExplorer.event.register('fileChanged', (path) => { this.fileChangedEvent(path) }) - this._deps.workspaceExplorer.event.register('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) - this._deps.workspaceExplorer.event.register('fileRemoved', (path) => { this.fileRemovedEvent(path) }) - this._deps.workspaceExplorer.event.register('fileAdded', (path) => { this.fileAddedEvent(path) }) + this._deps.browserExplorer.event.on('fileChanged', (path) => { this.fileChangedEvent(path) }) + this._deps.browserExplorer.event.on('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) + this._deps.localhostExplorer.event.on('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) + this._deps.browserExplorer.event.on('fileRemoved', (path) => { this.fileRemovedEvent(path) }) + this._deps.browserExplorer.event.on('fileAdded', (path) => { this.fileAddedEvent(path) }) + this._deps.localhostExplorer.event.on('fileRemoved', (path) => { this.fileRemovedEvent(path) }) + this._deps.localhostExplorer.event.on('errored', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) + this._deps.localhostExplorer.event.on('closed', (event) => { this.removeTabsOf(this._deps.localhostExplorer) }) + this._deps.workspaceExplorer.event.on('fileChanged', (path) => { this.fileChangedEvent(path) }) + this._deps.workspaceExplorer.event.on('fileRenamed', (oldName, newName, isFolder) => { this.fileRenamedEvent(oldName, newName, isFolder) }) + this._deps.workspaceExplorer.event.on('fileRemoved', (path) => { this.fileRemovedEvent(path) }) + this._deps.workspaceExplorer.event.on('fileAdded', (path) => { this.fileAddedEvent(path) }) this.getCurrentFile = this.file this.getFile = this.readFile diff --git a/apps/remix-ide/src/app/files/fileProvider.js b/apps/remix-ide/src/app/files/fileProvider.js index 521dcec453..5d152ec74b 100644 --- a/apps/remix-ide/src/app/files/fileProvider.js +++ b/apps/remix-ide/src/app/files/fileProvider.js @@ -1,7 +1,7 @@ 'use strict' const CompilerImport = require('../compiler/compiler-imports') -const EventManager = require('../../lib/events') +const EventManager = require('events') const modalDialogCustom = require('../ui/modal-dialog-custom') const tooltip = require('../ui/tooltip') const remixLib = require('@remix-project/remix-lib') @@ -111,9 +111,9 @@ class FileProvider { return false } if (!exists) { - this.event.trigger('fileAdded', [this._normalizePath(unprefixedpath), false]) + this.event.emit('fileAdded', this._normalizePath(unprefixedpath), false) } else { - this.event.trigger('fileChanged', [this._normalizePath(unprefixedpath)]) + this.event.emit('fileChanged', this._normalizePath(unprefixedpath)) } cb() return true @@ -128,7 +128,7 @@ class FileProvider { currentCheck = currentCheck + '/' + value if (!window.remixFileSystem.existsSync(currentCheck)) { window.remixFileSystem.mkdirSync(currentCheck) - this.event.trigger('folderAdded', [this._normalizePath(currentCheck)]) + this.event.emit('folderAdded', this._normalizePath(currentCheck)) } }) if (cb) cb() @@ -184,7 +184,7 @@ class FileProvider { // folder is empty window.remixFileSystem.rmdirSync(path, console.log) } - this.event.trigger('fileRemoved', [this._normalizePath(path)]) + this.event.emit('fileRemoved', this._normalizePath(path)) } } catch (e) { console.log(e) @@ -249,7 +249,7 @@ class FileProvider { path = this.removePrefix(path) if (window.remixFileSystem.existsSync(path) && !window.remixFileSystem.statSync(path).isDirectory()) { window.remixFileSystem.unlinkSync(path, console.log) - this.event.trigger('fileRemoved', [this._normalizePath(path)]) + this.event.emit('fileRemoved', this._normalizePath(path)) return true } else return false } @@ -259,11 +259,11 @@ class FileProvider { var unprefixednewPath = this.removePrefix(newPath) if (this._exists(unprefixedoldPath)) { window.remixFileSystem.renameSync(unprefixedoldPath, unprefixednewPath) - this.event.trigger('fileRenamed', [ + this.event.emit('fileRenamed', this._normalizePath(unprefixedoldPath), this._normalizePath(unprefixednewPath), isFolder - ]) + ) return true } return false diff --git a/apps/remix-ide/src/app/files/remixDProvider.js b/apps/remix-ide/src/app/files/remixDProvider.js index 60337c11e4..bc59bfe90b 100644 --- a/apps/remix-ide/src/app/files/remixDProvider.js +++ b/apps/remix-ide/src/app/files/remixDProvider.js @@ -17,32 +17,32 @@ module.exports = class RemixDProvider extends FileProvider { var remixdEvents = ['connecting', 'connected', 'errored', 'closed'] remixdEvents.forEach((value) => { this._appManager.on('remixd', value, (event) => { - this.event.trigger(value, [event]) + this.event.emit(value, event) }) }) this._appManager.on('remixd', 'folderAdded', (path) => { - this.event.trigger('folderAdded', [path]) + this.event.emit('folderAdded', path) }) this._appManager.on('remixd', 'fileAdded', (path) => { - this.event.trigger('fileAdded', [path]) + this.event.emit('fileAdded', path) }) this._appManager.on('remixd', 'fileChanged', (path) => { - this.event.trigger('fileChanged', [path]) + this.event.emit('fileChanged', path) }) this._appManager.on('remixd', 'fileRemoved', (path) => { - this.event.trigger('fileRemoved', [path]) + this.event.emit('fileRemoved', path) }) this._appManager.on('remixd', 'fileRenamed', (oldPath, newPath) => { - this.event.trigger('fileRemoved', [oldPath, newPath]) + this.event.emit('fileRemoved', oldPath, newPath) }) this._appManager.on('remixd', 'rootFolderChanged', () => { - this.event.trigger('rootFolderChanged', []) + this.event.emit('rootFolderChanged') }) } @@ -53,11 +53,11 @@ module.exports = class RemixDProvider extends FileProvider { close (cb) { this._isReady = false cb() - this.event.trigger('disconnected') + this.event.emit('disconnected') } preInit () { - this.event.trigger('loading') + this.event.emit('loading') } init (cb) { @@ -67,7 +67,7 @@ module.exports = class RemixDProvider extends FileProvider { this._isReady = true this._readOnlyMode = result this._registerEvent() - this.event.trigger('connected') + this.event.emit('connected') cb && cb() }).catch((error) => { cb && cb(error) @@ -164,13 +164,13 @@ module.exports = class RemixDProvider extends FileProvider { this.filesContent[newPath] = this.filesContent[oldPath] delete this.filesContent[oldPath] this.init(() => { - this.event.trigger('fileRenamed', [oldPath, newPath, isFolder]) + this.event.emit('fileRenamed', oldPath, newPath, isFolder) }) return result }).catch(error => { console.log(error) if (this.error[error.code]) error = this.error[error.code] - this.event.trigger('fileRenamedError', [this.error[error.code]]) + this.event.emit('fileRenamedError', this.error[error.code]) }) } diff --git a/apps/remix-ide/src/app/files/workspaceFileProvider.js b/apps/remix-ide/src/app/files/workspaceFileProvider.js index 156723b622..4b0ac2af2e 100644 --- a/apps/remix-ide/src/app/files/workspaceFileProvider.js +++ b/apps/remix-ide/src/app/files/workspaceFileProvider.js @@ -1,6 +1,6 @@ 'use strict' -const EventManager = require('../../lib/events') +const EventManager = require('events') const FileProvider = require('./fileProvider') const pathModule = require('path') @@ -82,7 +82,7 @@ class WorkspaceFileProvider extends FileProvider { createWorkspace (name) { if (!name) name = 'default_workspace' - this.event.trigger('createWorkspace', [name]) + this.event.emit('createWorkspace', name) } } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 3feff714c1..1c7e063aa3 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -97,24 +97,24 @@ export const Workspace = (props: WorkspaceProps) => { props.fileManager.setMode('browser') } } - props.localhost.event.unregister('disconnected', localhostDisconnect) - props.localhost.event.register('disconnected', localhostDisconnect) + props.localhost.event.off('disconnected', localhostDisconnect) + props.localhost.event.on('disconnected', localhostDisconnect) useEffect(() => { - props.localhost.event.register('connected', () => { + props.localhost.event.on('connected', () => { remixdExplorer.show() setWorkspace(LOCALHOST) }) - props.localhost.event.register('disconnected', () => { + props.localhost.event.on('disconnected', () => { remixdExplorer.hide() }) - props.localhost.event.register('loading', () => { + props.localhost.event.on('loading', () => { remixdExplorer.loading() }) - props.workspace.event.register('createWorkspace', (name) => { + props.workspace.event.on('createWorkspace', (name) => { createNewWorkspace(name) }) From 7672eeb255159262163452d65ba6fec602a72bce Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 15 Apr 2021 17:20:38 +0200 Subject: [PATCH 190/199] updated require --- apps/remix-ide/src/app/files/file-explorer.js | 2 +- apps/remix-ide/src/app/panels/file-panel.js | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/remix-ide/src/app/files/file-explorer.js b/apps/remix-ide/src/app/files/file-explorer.js index 9f5f3e3f69..cc9986aebf 100644 --- a/apps/remix-ide/src/app/files/file-explorer.js +++ b/apps/remix-ide/src/app/files/file-explorer.js @@ -9,7 +9,7 @@ const helper = require('../../lib/helper') const yo = require('yo-yo') const Treeview = require('../ui/TreeView') const modalDialog = require('../ui/modaldialog') -const EventManager = require('../../lib/events') +const EventManager = require('events') const contextMenu = require('../ui/contextMenu') const css = require('./styles/file-explorer-styles') const globalRegistry = require('../../global/registry') diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 6bdef578d6..020c02a62d 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -6,14 +6,13 @@ import ReactDOM from 'react-dom' import { Workspace } from '@remix-ui/workspace' // eslint-disable-line import { bufferToHex, keccakFromString } from 'ethereumjs-util' import { checkSpecialChars, checkSlash } from '../../lib/helper' -var EventManager = require('../../lib/events') -var { RemixdHandle } = require('../files/remixd-handle.js') -var { GitHandle } = require('../files/git-handle.js') -var { HardhatHandle } = require('../files/hardhat-handle.js') -var globalRegistry = require('../../global/registry') -var examples = require('../editor/examples') -var GistHandler = require('../../lib/gist-handler') -var QueryParams = require('../../lib/query-params') +const { RemixdHandle } = require('../files/remixd-handle.js') +const { GitHandle } = require('../files/git-handle.js') +const { HardhatHandle } = require('../files/hardhat-handle.js') +const globalRegistry = require('../../global/registry') +const examples = require('../editor/examples') +const GistHandler = require('../../lib/gist-handler') +const QueryParams = require('../../lib/query-params') const modalDialogCustom = require('../ui/modal-dialog-custom') /* Overview of APIs: @@ -48,7 +47,7 @@ const profile = { module.exports = class Filepanel extends ViewPlugin { constructor (appManager) { super(profile) - this.event = new EventManager() + this.event = new EventEmitter() this._components = {} this._components.registry = globalRegistry this._deps = { From c6e58bf9330060d960356884d39a07a6e117f572 Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 19 Apr 2021 13:30:42 +0200 Subject: [PATCH 191/199] fixed event listening for file explorer --- apps/remix-ide/src/app/files/file-explorer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/remix-ide/src/app/files/file-explorer.js b/apps/remix-ide/src/app/files/file-explorer.js index cc9986aebf..cef877b68b 100644 --- a/apps/remix-ide/src/app/files/file-explorer.js +++ b/apps/remix-ide/src/app/files/file-explorer.js @@ -94,11 +94,11 @@ function fileExplorer (localRegistry, files, menuItems, plugin) { }) // register to event of the file provider - files.event.register('fileRemoved', fileRemoved) - files.event.register('fileRenamed', fileRenamed) - files.event.register('fileRenamedError', fileRenamedError) - files.event.register('fileAdded', fileAdded) - files.event.register('folderAdded', folderAdded) + files.event.on('fileRemoved', fileRemoved) + files.event.on('fileRenamed', fileRenamed) + files.event.on('fileRenamedError', fileRenamedError) + files.event.on('fileAdded', fileAdded) + files.event.on('folderAdded', folderAdded) function fileRenamedError (error) { modalDialogCustom.alert(error) From 9d0efcec4f45b423f93a5ab127b5c2fce2d60a68 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 10:52:55 +0200 Subject: [PATCH 192/199] fix some event definitions --- apps/remix-ide/src/app/panels/file-panel.js | 1 - apps/remix-ide/src/app/tabs/test-tab.js | 2 +- .../file-explorer/src/lib/actions/fileSystem.ts | 16 ++++++++-------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/apps/remix-ide/src/app/panels/file-panel.js b/apps/remix-ide/src/app/panels/file-panel.js index 020c02a62d..ac7ae97089 100644 --- a/apps/remix-ide/src/app/panels/file-panel.js +++ b/apps/remix-ide/src/app/panels/file-panel.js @@ -47,7 +47,6 @@ const profile = { module.exports = class Filepanel extends ViewPlugin { constructor (appManager) { super(profile) - this.event = new EventEmitter() this._components = {} this._components.registry = globalRegistry this._deps = { diff --git a/apps/remix-ide/src/app/tabs/test-tab.js b/apps/remix-ide/src/app/tabs/test-tab.js index eb6edd4efb..652be0b9c9 100644 --- a/apps/remix-ide/src/app/tabs/test-tab.js +++ b/apps/remix-ide/src/app/tabs/test-tab.js @@ -52,7 +52,7 @@ module.exports = class TestTab extends ViewPlugin { } listenToEvents () { - this.filePanel.event.register('newTestFileCreated', file => { + this.on('filePanel', 'newTestFileCreated', file => { var testList = this._view.el.querySelector("[class^='testList']") var test = this.createSingleTest(file) testList.appendChild(test) diff --git a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts index 8e3bc9f1c4..8a397cfd91 100644 --- a/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts +++ b/libs/remix-ui/file-explorer/src/lib/actions/fileSystem.ts @@ -181,35 +181,35 @@ export const fileRenamedSuccess = (path: string, removePath: string, files) => { export const init = (provider, workspaceName: string, plugin, registry) => (dispatch: React.Dispatch) => { if (provider) { - provider.event.register('fileAdded', async (filePath) => { + provider.event.on('fileAdded', async (filePath) => { if (extractParentFromKey(filePath) === '/.workspaces') return const path = extractParentFromKey(filePath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(fileAddedSuccess(path, data)) if (filePath.includes('_test.sol')) { - plugin.event.trigger('newTestFileCreated', [filePath]) + plugin.emit('newTestFileCreated', filePath) } }) - provider.event.register('folderAdded', async (folderPath) => { + provider.event.on('folderAdded', async (folderPath) => { if (extractParentFromKey(folderPath) === '/.workspaces') return const path = extractParentFromKey(folderPath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(folderAddedSuccess(path, data)) }) - provider.event.register('fileRemoved', async (removePath) => { + provider.event.on('fileRemoved', async (removePath) => { const path = extractParentFromKey(removePath) || provider.workspace || provider.type || '' dispatch(fileRemovedSuccess(path, removePath)) }) - provider.event.register('fileRenamed', async (oldPath) => { + provider.event.on('fileRenamed', async (oldPath) => { const path = extractParentFromKey(oldPath) || provider.workspace || provider.type || '' const data = await fetchDirectoryContent(provider, path) dispatch(fileRenamedSuccess(path, oldPath, data)) }) - provider.event.register('fileExternallyChanged', async (path: string, file: { content: string }) => { + provider.event.on('fileExternallyChanged', async (path: string, file: { content: string }) => { const config = registry.get('config').api const editor = registry.get('editor').api @@ -225,10 +225,10 @@ export const init = (provider, workspaceName: string, plugin, registry) => (disp )) } }) - provider.event.register('fileRenamedError', async () => { + provider.event.on('fileRenamedError', async () => { dispatch(displayNotification('File Renamed Failed', '', 'Ok', 'Cancel')) }) - provider.event.register('rootFolderChanged', async () => { + provider.event.on('rootFolderChanged', async () => { workspaceName = provider.workspace || provider.type || '' fetchDirectory(provider, workspaceName)(dispatch) }) From 072c5763a5aaad8ccef70c34bfb9b14ee736abb3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 12:43:57 +0200 Subject: [PATCH 193/199] remove promise --- libs/remix-lib/src/execution/txRunnerWeb3.ts | 31 +++++++------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index 4554c396e8..ddef31cb50 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -128,29 +128,20 @@ export class TxRunnerWeb3 { } async function tryTillReceiptAvailable (txhash, web3) { - return new Promise((resolve, reject) => { - web3.eth.getTransactionReceipt(txhash, async (err, receipt) => { - if (err || !receipt) { - // Try again with a bit of delay if error or if result still null - await pause() - return resolve(await tryTillReceiptAvailable(txhash, web3)) - } - return resolve(receipt) - }) - }) + try { + const receipt = await web3.eth.getTransactionReceipt(txhash) + if (receipt) return receipt + } catch (e) {} + await pause() + return await tryTillReceiptAvailable(txhash, web3) } async function tryTillTxAvailable (txhash, web3) { - return new Promise((resolve, reject) => { - web3.eth.getTransaction(txhash, async (err, tx) => { - if (err || !tx) { - // Try again with a bit of delay if error or if result still null - await pause() - return resolve(await tryTillTxAvailable(txhash, web3)) - } - return resolve(tx) - }) - }) + try { + const tx = await web3.eth.getTransaction(txhash) + if (tx) return tx + } catch (e) {} + return await tryTillTxAvailable(txhash, web3) } async function pause () { return new Promise((resolve, reject) => { setTimeout(resolve, 500) }) } From ffbf9e1a55e1ac47ec65ebf26f555a4e2ca0b36b Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 12:44:10 +0200 Subject: [PATCH 194/199] fix directory name --- libs/remix-tests/tsconfig.lib.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-tests/tsconfig.lib.json b/libs/remix-tests/tsconfig.lib.json index aec3a4c785..7b4b23c716 100644 --- a/libs/remix-tests/tsconfig.lib.json +++ b/libs/remix-tests/tsconfig.lib.json @@ -9,7 +9,7 @@ }, "exclude": [ "**/*.spec.ts", - "test/" + "tests/" ], "include": ["**/*.ts"] } From bcc4e0f099e3fa198737d4f3fc7a26ce037a138d Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 12:44:20 +0200 Subject: [PATCH 195/199] remove log --- libs/remix-tests/tests/testRunner.cli.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index 21ce34afdb..91174355af 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -17,7 +17,6 @@ describe('testRunner: remix-tests CLI', () => { describe('test various CLI options', () => { test('remix-tests version', () => { const res = spawnSync(executablePath, ['-V']) - console.log(res.stdout.toString()) expect(res.stdout.toString().trim()).toBe(require('../package.json').version) }) From 39d08d2c1f44ef226030e20e882e8c9b928e72ac Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 12:46:18 +0200 Subject: [PATCH 196/199] remove uneeded CI config --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 49aada7eb0..ab5e15436f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,6 @@ jobs: - checkout - run: npm install - run: npm run build:libs - - run: export NODE_OPTIONS="--max_old_space_size=8192" - run: npm run test:libs remix-ide-chrome-1: From b5f821e5fe42dccab38b58b9f269958a6d1d8536 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 19 May 2021 13:53:43 +0200 Subject: [PATCH 197/199] linting --- libs/remix-lib/src/execution/txRunnerWeb3.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index ddef31cb50..650593dfbc 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -141,7 +141,7 @@ async function tryTillTxAvailable (txhash, web3) { const tx = await web3.eth.getTransaction(txhash) if (tx) return tx } catch (e) {} - return await tryTillTxAvailable(txhash, web3) + return await tryTillTxAvailable(txhash, web3) } async function pause () { return new Promise((resolve, reject) => { setTimeout(resolve, 500) }) } From a5277560e91e85b667886ee0f27b973685ab8d62 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 12 May 2021 18:25:06 +0200 Subject: [PATCH 198/199] reset results for compiler tab for change workspace --- apps/remix-ide/src/app/tabs/compile-tab.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 400ef25d76..6475bd0bae 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -80,6 +80,15 @@ class CompileTab extends ViewPlugin { ) } + resetResults () { + if (this._view.errorContainer) { + this._view.errorContainer.innerHTML = '' + } + this.compilerContainer.currentFile = '' + this.data.contractsDetails = {} + yo.update(this._view.contractSelection, this.contractSelection()) + } + /************ * EVENTS */ @@ -115,6 +124,9 @@ class CompileTab extends ViewPlugin { } this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' }) } + + this.on('filePanel', 'setWorkspace', () => this.resetResults()) + this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation) this.data.eventHandlers.onCurrentFileChanged = (name) => { From d0f0b7fe3ac3918146e770eda75c293ea171b02c Mon Sep 17 00:00:00 2001 From: lianahus Date: Mon, 17 May 2021 09:37:19 +0200 Subject: [PATCH 199/199] removed the status badge on workspace change --- apps/remix-ide/src/app/tabs/compile-tab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 6475bd0bae..8bb5b48575 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -87,6 +87,7 @@ class CompileTab extends ViewPlugin { this.compilerContainer.currentFile = '' this.data.contractsDetails = {} yo.update(this._view.contractSelection, this.contractSelection()) + this.emit('statusChanged', { key: 'none' }) } /************