From 6e3d62442400ac5032ff49dd643d6bbfab3bf8c2 Mon Sep 17 00:00:00 2001 From: tizah Date: Sat, 10 Apr 2021 02:06:33 +0100 Subject: [PATCH 001/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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/133] 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:13:45 +0200 Subject: [PATCH 092/133] 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 093/133] 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 094/133] 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 095/133] 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 096/133] 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 097/133] 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 098/133] 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 099/133] 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 100/133] 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 101/133] 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 102/133] 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 103/133] 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 104/133] 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 105/133] 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 106/133] 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 107/133] 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 108/133] 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 109/133] 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 110/133] 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 111/133] 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 112/133] 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 113/133] 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 114/133] 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 115/133] 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 116/133] 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 117/133] 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 118/133] 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 119/133] 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 120/133] 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 121/133] 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 122/133] 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 123/133] 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 124/133] 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 125/133] 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 126/133] 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 127/133] 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 128/133] 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 129/133] 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 130/133] 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 131/133] 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 132/133] 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 133/133] 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