diff --git a/libs/remix-ui/solidity-unit-testing/.eslintrc.json b/libs/remix-ui/solidity-unit-testing/.eslintrc.json index 5e100bf955..50e59482cf 100644 --- a/libs/remix-ui/solidity-unit-testing/.eslintrc.json +++ b/libs/remix-ui/solidity-unit-testing/.eslintrc.json @@ -1,9 +1,6 @@ { "extends": ["plugin:@nrwl/nx/react", "../../../.eslintrc.json"], "ignorePatterns": ["!**/*"], - "rules": { - "@typescript-eslint/no-explicit-any": "off" - }, "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts b/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts index 6b42bc128a..6e1af409a4 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts +++ b/libs/remix-ui/solidity-unit-testing/src/lib/logic/testTabLogic.ts @@ -5,6 +5,7 @@ export class TestTabLogic { fileManager currentPath helper + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor (fileManager: any, helper: any) { this.fileManager = fileManager this.helper = helper @@ -26,7 +27,7 @@ export class TestTabLogic { if (!path || !(/\S/.test(path))) return path = this.helper.removeMultipleSlashes(path) const fileProvider = this.fileManager.fileProviderOf(path.split('/')[0]) - fileProvider.exists(path).then((res: any) => { + fileProvider.exists(path).then((res: boolean) => { if (!res) fileProvider.createDir(path) }) } @@ -35,11 +36,12 @@ export 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]) - const res = await fileProvider.exists(path, (e: any, res: any) => { return res }) + const res = await fileProvider.exists(path, (e: Error, res: boolean) => { return res }) return res } - generateTestFile (errorCb: any) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + generateTestFile (errorCb:any) { let fileName = this.fileManager.currentFile() const hasCurrent = !!fileName && this.fileManager.currentFile().split('.').pop().toLowerCase() === 'sol' if (!hasCurrent) fileName = this.currentPath + '/newFile.sol' @@ -47,7 +49,7 @@ export class TestTabLogic { if (!fileProvider) return const splittedFileName = fileName.split('/') const fileNameToImport = (!hasCurrent) ? fileName : this.currentPath + '/' + splittedFileName[splittedFileName.length - 1] - this.helper.createNonClashingNameWithPrefix(fileNameToImport, fileProvider, '_test', (error: any, newFile: any) => { + this.helper.createNonClashingNameWithPrefix(fileNameToImport, fileProvider, '_test', (error: Error, newFile: string) => { if (error) return errorCb('Failed to create file. ' + newFile + ' ' + error) const isFileCreated = fileProvider.set(newFile, this.generateTestContractSample(hasCurrent, fileName)) if (!isFileCreated) return errorCb('Failed to create test file ' + newFile) @@ -72,7 +74,7 @@ export class TestTabLogic { let files = [] try { if (await this.fileManager.exists(this.currentPath)) files = await this.fileManager.readdir(this.currentPath) - } catch (e: any) { + } catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any throw e.message } for (const file in files) { @@ -84,7 +86,7 @@ export class TestTabLogic { // @todo(#2758): If currently selected file is compiled and compilation result is available, // 'contractName' should be + '_testSuite' - generateTestContractSample (hasCurrent: any, fileToImport: any, contractName = 'testSuite') { + generateTestContractSample (hasCurrent: boolean, fileToImport: string, contractName = 'testSuite') { let relative = remixPath.relative(this.currentPath, remixPath.dirname(fileToImport)) if (relative === '') relative = '.' const comment = hasCurrent ? `import "${relative}/${remixPath.basename(fileToImport)}";` : '// ' diff --git a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx index 0e791fd0ec..6cb5bc3820 100644 --- a/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx +++ b/libs/remix-ui/solidity-unit-testing/src/lib/solidity-unit-testing.tsx @@ -1,62 +1,84 @@ -import React, { useState, useRef, useEffect } from 'react' // eslint-disable-line +import React, { useState, useRef, useEffect, ReactElement } from 'react' // eslint-disable-line import { eachOfSeries } from 'async' // eslint-disable-line +import type Web3 from 'web3' import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity' import { Renderer } from '@remix-ui/renderer' // eslint-disable-line import { Toaster } from '@remix-ui/toaster' // eslint-disable-line import { format } from 'util' import './css/style.css' -const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line - -/* eslint-disable-next-line */ -export interface SolidityUnitTestingProps { } +const _paq = (window as any)._paq = (window as any)._paq || [] // eslint-disable-line @typescript-eslint/no-explicit-any interface TestObject { fileName: string checked: boolean } -export const SolidityUnitTesting = (props: Record) => { +interface TestResultInterface { + type: string + value: any // eslint-disable-line @typescript-eslint/no-explicit-any + time?: number + context?: string + errMsg?: string + filename: string + assertMethod?: string + returned?: string | number + expected?: string | number + location?: string + hhLogs?: [] + web3?: Web3 + debugTxHash?: string + rendered?: boolean +} + +interface FinalResult { + totalPassing: number, + totalFailing: number, + totalTime: any, // eslint-disable-line @typescript-eslint/no-explicit-any + errors: any[], // eslint-disable-line @typescript-eslint/no-explicit-any +} + +export const SolidityUnitTesting = (props: Record) => { // eslint-disable-line @typescript-eslint/no-explicit-any const { helper, testTab, initialPath } = props const { testTabLogic } = testTab - const [toasterMsg, setToasterMsg] = useState('') + const [toasterMsg, setToasterMsg] = useState('') - const [disableCreateButton, setDisableCreateButton] = useState(true) - const [disableGenerateButton, setDisableGenerateButton] = useState(false) - const [disableStopButton, setDisableStopButton] = useState(true) - const [disableRunButton, setDisableRunButton] = useState(false) - const [runButtonTitle, setRunButtonTitle] = useState('Run tests') - const [stopButtonLabel, setStopButtonLabel] = useState('Stop') + const [disableCreateButton, setDisableCreateButton] = useState(true) + const [disableGenerateButton, setDisableGenerateButton] = useState(false) + const [disableStopButton, setDisableStopButton] = useState(true) + const [disableRunButton, setDisableRunButton] = useState(false) + const [runButtonTitle, setRunButtonTitle] = useState('Run tests') + const [stopButtonLabel, setStopButtonLabel] = useState('Stop') - const [checkSelectAll, setCheckSelectAll] = useState(true) - const [testsOutput, setTestsOutput] = useState([]) + const [checkSelectAll, setCheckSelectAll] = useState(true) + const [testsOutput, setTestsOutput] = useState([]) - const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) - const [progressBarHidden, setProgressBarHidden] = useState(true) - const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true) + const [testsExecutionStoppedHidden, setTestsExecutionStoppedHidden] = useState(true) + const [progressBarHidden, setProgressBarHidden] = useState(true) + const [testsExecutionStoppedErrorHidden, setTestsExecutionStoppedErrorHidden] = useState(true) let [testFiles, setTestFiles] = useState([]) // eslint-disable-line - const [pathOptions, setPathOptions] = useState(['']) + const [pathOptions, setPathOptions] = useState(['']) - const [inputPathValue, setInputPathValue] = useState('tests') + const [inputPathValue, setInputPathValue] = useState('tests') - let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line - let [runningTestsNumber, setRunningTestsNumber] = useState(0) // eslint-disable-line + let [readyTestsNumber, setReadyTestsNumber] = useState(0) // eslint-disable-line + let [runningTestsNumber, setRunningTestsNumber] = useState(0) // eslint-disable-line - const hasBeenStopped = useRef(false) - const isDebugging = useRef(false) - const allTests: any = useRef([]) - const selectedTests: any = useRef([]) - const currentErrors: any = useRef([]) + const hasBeenStopped = useRef(false) + const isDebugging = useRef(false) + const allTests = useRef([]) + const selectedTests = useRef([]) + const currentErrors:any = useRef([]) // eslint-disable-line @typescript-eslint/no-explicit-any const defaultPath = 'tests' let areTestsRunning = false - let runningTestFileName: any - const filesContent: any = {} - const testsResultByFilename: Record = {} + let runningTestFileName: string + const filesContent: Record> = {} + const testsResultByFilename: Record>> = {} // eslint-disable-line @typescript-eslint/no-explicit-any const trimTestDirInput = (input: string) => { if (input.includes('/')) return input.split('/').map(e => e.trim()).join('/') @@ -71,7 +93,7 @@ export const SolidityUnitTesting = (props: Record) => { setTestsExecutionStoppedErrorHidden(true) } - const updateForNewCurrent = async (file = null) => { + const updateForNewCurrent = async (file: string | null = null) => { // Ensure that when someone clicks on compilation error and that opens a new file // Test result, which is compilation error in this case, is not cleared if (currentErrors.current) { @@ -92,7 +114,7 @@ export const SolidityUnitTesting = (props: Record) => { selectedTests.current = [...allTests.current] updateTestFileList() if (!areTestsRunning) await updateRunAction(file) - } catch (e: any) { + } catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any console.log(e) setToasterMsg(e) } @@ -132,17 +154,17 @@ export const SolidityUnitTesting = (props: Record) => { }) testTab.fileManager.events.on('noFileSelected', () => { }) // eslint-disable-line - testTab.fileManager.events.on('currentFileChanged', async (file: any, provider: any) => await updateForNewCurrent(file)) + testTab.fileManager.events.on('currentFileChanged', async (file: string) => await updateForNewCurrent(file)) }, []) // eslint-disable-line const updateDirList = (path: string) => { - testTabLogic.dirList(path).then((options: any) => { + testTabLogic.dirList(path).then((options: string[]) => { setPathOptions(options) }) } - const handleTestDirInput = async (e: any) => { + const handleTestDirInput = async (e: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any let testDirInput = trimTestDirInput(e.target.value) testDirInput = helper.removeMultipleSlashes(testDirInput) if (testDirInput !== '/') testDirInput = helper.removeTrailingSlashes(testDirInput) @@ -183,7 +205,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const handleEnter = async (e: any) => { + const handleEnter = async (e: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any let inputPath = e.target.value inputPath = helper.removeMultipleSlashes(trimTestDirInput(inputPath)) setInputPathValue(inputPath) @@ -210,18 +232,18 @@ export const SolidityUnitTesting = (props: Record) => { setPathOptions(pathOptions) } - const cleanFileName = (fileName: any, testSuite: any) => { + const cleanFileName = (fileName: string, testSuite: string) => { return fileName ? fileName.replace(/\//g, '_').replace(/\./g, '_') + testSuite : fileName } - const startDebug = async (txHash: any, web3: any) => { + const startDebug = async (txHash: string, web3: Web3) => { isDebugging.current = true if (!await testTab.appManager.isActive('debugger')) await testTab.appManager.activatePlugin('debugger') testTab.call('menuicons', 'select', 'debugger') testTab.call('debugger', 'debug', txHash, web3) } - const printHHLogs = (logsArr: any, testName: any) => { + const printHHLogs = (logsArr: Record[], testName: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any let finalLogs = `${testName}:\n` for (const log of logsArr) { let formattedLog @@ -262,9 +284,9 @@ export const SolidityUnitTesting = (props: Record) => { } } - const renderContract = (filename: any, contract: any, index: number, withoutLabel = false) => { + const renderContract = (filename: string, contract: string|null, index: number, withoutLabel = false) => { if (withoutLabel) { - const contractCard: any = ( + const contractCard: ReactElement = (
{contract ? contract : ''} ({filename})
@@ -291,20 +313,20 @@ export const SolidityUnitTesting = (props: Record) => { ) } // show contract and file name with label - const ContractCard: any = ( + const ContractCard: ReactElement = (
{label}{contract} ({filename})
) setTestsOutput(prevCards => { - const index = prevCards.findIndex((card: any) => card.props.id === runningTestFileName) + const index = prevCards.findIndex((card: ReactElement) => card.props.id === runningTestFileName) prevCards[index] = ContractCard return prevCards }) } - const renderTests = (tests: any, contract: any, filename: any) => { - const index = tests.findIndex((test: any) => test.type === 'testFailure') + const renderTests = (tests: TestResultInterface[], contract: string, filename: string) => { + const index = tests.findIndex((test: TestResultInterface) => test.type === 'testFailure') // show filename and contract renderContract(filename, contract, index) // show tests @@ -321,7 +343,7 @@ export const SolidityUnitTesting = (props: Record) => { } if (test.type === 'testPass') { if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) - const testPassCard: any = ( + const testPassCard: ReactElement = (
) => { } else if (test.type === 'testFailure') { if (test.hhLogs && test.hhLogs.length) printHHLogs(test.hhLogs, test.value) if (!test.assertMethod) { - const testFailCard1: any = (
highlightLocation(test.location, test.filename)} + onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}} >
✘ {test.value} @@ -356,10 +378,10 @@ export const SolidityUnitTesting = (props: Record) => { const preposition = test.assertMethod === 'equal' || test.assertMethod === 'notEqual' ? 'to' : '' const method = test.assertMethod === 'ok' ? '' : test.assertMethod const expected = test.assertMethod === 'ok' ? '\'true\'' : test.expected - const testFailCard2: any = (
highlightLocation(test.location, test.filename)} + onClick={() => { if(test.location) highlightLocation(test.location, test.filename)}} >
✘ {test.value} @@ -396,7 +418,7 @@ export const SolidityUnitTesting = (props: Record) => { for (const contract of contracts) { if (contract && contract !== 'summary' && contract !== 'errors') { runningTestFileName = cleanFileName(filename, contract) - const tests = fileTestsResult[contract] + const tests = fileTestsResult[contract] as TestResultInterface[] if (tests?.length) { renderTests(tests, contract, filename) } else { @@ -406,18 +428,18 @@ export const SolidityUnitTesting = (props: Record) => { } else if (contract === 'errors' && fileTestsResult['errors']) { const errors = fileTestsResult['errors'] if (errors && errors.errors) { - errors.errors.forEach((err: any) => { - const errorCard: any = + errors.errors.forEach((err: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) }) } else if (errors && Array.isArray(errors) && (errors[0].message || errors[0].formattedMessage)) { errors.forEach((err) => { - const errorCard: any = + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) }) } else if (errors && !errors.errors && !Array.isArray(errors)) { // To track error like this: https://github.com/ethereum/remix/pull/1438 - const errorCard: any = + const errorCard: ReactElement = setTestsOutput(prevCards => ([...prevCards, errorCard])) } } @@ -425,7 +447,7 @@ export const SolidityUnitTesting = (props: Record) => { // show summary const testSummary = fileTestsResult['summary'] if (testSummary && testSummary.filename && !testSummary.rendered) { - const summaryCard: any = (
+ const summaryCard: ReactElement = (
Result for {testSummary.filename} Passed: {testSummary.passed} Failed: {testSummary.failed} @@ -437,7 +459,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const testCallback = (result: any) => { + const testCallback = (result: Record) => { // eslint-disable-line @typescript-eslint/no-explicit-any if (result.filename) { if (!testsResultByFilename[result.filename]) { testsResultByFilename[result.filename] = {} @@ -455,7 +477,7 @@ export const SolidityUnitTesting = (props: Record) => { } } - const resultsCallback = (_err: any, result: any, cb: any) => { + const resultsCallback = (_err: any, result: any, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any // total stats for the test // result.passingNum // result.failureNum @@ -463,7 +485,7 @@ export const SolidityUnitTesting = (props: Record) => { cb() } - const updateFinalResult = (_errors: any, result: any, filename: any) => { + const updateFinalResult = (_errors: any, result: FinalResult|null, filename: string) => { // eslint-disable-line @typescript-eslint/no-explicit-any ++readyTestsNumber setReadyTestsNumber(readyTestsNumber) if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) { @@ -500,14 +522,14 @@ export const SolidityUnitTesting = (props: Record) => { } } - const runTest = (testFilePath: any, callback: any) => { + const runTest = (testFilePath: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any isDebugging.current = false if (hasBeenStopped.current) { - updateFinalResult(null, null, null) + updateFinalResult(null, null, testFilePath) return } - testTab.fileManager.readFile(testFilePath).then((content: any) => { - const runningTests: any = {} + testTab.fileManager.readFile(testFilePath).then((content: string) => { + const runningTests: Record> = {} runningTests[testFilePath] = { content } filesContent[testFilePath] = { content } const { currentVersion, evmVersion, optimize, runs, isUrl } = testTab.compileTab.getCurrentCompilerConfig() @@ -519,24 +541,24 @@ export const SolidityUnitTesting = (props: Record) => { usingWorker: canUseWorker(currentVersion), runs } - const deployCb = async (file: any, contractAddress: any) => { + const deployCb = async (file: string, contractAddress: string) => { const compilerData = await testTab.call('compilerArtefacts', 'getCompilerAbstract', file) await testTab.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilerData) } testTab.testRunner.runTestSources( runningTests, compilerConfig, - (result: any) => testCallback(result), - (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), + (result: Record) => testCallback(result), // eslint-disable-line @typescript-eslint/no-explicit-any + (_err: any, result: any, cb: any) => resultsCallback(_err, result, cb), // eslint-disable-line @typescript-eslint/no-explicit-any deployCb, - (error: any, result: any) => { + (error: any, result: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any updateFinalResult(error, result, testFilePath) callback(error) - }, (url: any, cb: any) => { - return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: any) => cb(error.message)) + }, (url: string, cb: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any + return testTab.contentImport.resolveAndSave(url).then((result: any) => cb(null, result)).catch((error: Error) => cb(error.message)) // eslint-disable-line @typescript-eslint/no-explicit-any }, { testFilePath } ) - }).catch((error: any) => { + }).catch((error: Error) => { console.log(error) if (error) return // eslint-disable-line }) @@ -552,17 +574,17 @@ export const SolidityUnitTesting = (props: Record) => { setDisableStopButton(false) clearResults() setProgressBarHidden(false) - const tests = selectedTests.current + const tests: string[] = selectedTests.current if (!tests || !tests.length) return else setProgressBarHidden(false) _paq.push(['trackEvent', 'solidityUnitTesting', 'runTests']) - eachOfSeries(tests, (value: any, key: any, callback: any) => { + eachOfSeries(tests, (value: string, key: string, callback: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any if (hasBeenStopped.current) return runTest(value, callback) }) } - const updateRunAction = async (currentFile: any = null) => { + const updateRunAction = async (currentFile: any = null) => { // eslint-disable-line @typescript-eslint/no-explicit-any const isSolidityActive = await testTab.appManager.isActive('solidity') if (!isSolidityActive || !selectedTests.current?.length) { // setDisableRunButton(true) @@ -586,7 +608,7 @@ export const SolidityUnitTesting = (props: Record) => { return selectedTestsList.map(testFileObj => testFileObj.fileName) } - const toggleCheckbox = (eChecked: any, index: any) => { + const toggleCheckbox = (eChecked: boolean, index: number) => { testFiles[index].checked = eChecked setTestFiles(testFiles) selectedTests.current = getCurrentSelectedTests() @@ -603,7 +625,7 @@ export const SolidityUnitTesting = (props: Record) => { } else setCheckSelectAll(false) } - const checkAll = (event: any) => { + const checkAll = (event: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any testFiles.forEach((testFileObj) => testFileObj.checked = event.target.checked) setTestFiles(testFiles) setCheckSelectAll(event.target.checked) @@ -618,7 +640,7 @@ export const SolidityUnitTesting = (props: Record) => { const updateTestFileList = () => { if (allTests.current?.length) { - testFiles = allTests.current.map((testFile: any) => { return { 'fileName': testFile, 'checked': true } }) + testFiles = allTests.current.map((testFile: string) => { return { 'fileName': testFile, 'checked': true } }) setCheckSelectAll(true) } else @@ -674,7 +696,7 @@ export const SolidityUnitTesting = (props: Record) => { title="Generate sample test file." disabled={disableGenerateButton} onClick={async () => { - testTabLogic.generateTestFile((err:any) => { if (err) setToasterMsg(err)}) + testTabLogic.generateTestFile((err:any) => { if (err) setToasterMsg(err)}) // eslint-disable-line @typescript-eslint/no-explicit-any await updateForNewCurrent() }} > @@ -704,7 +726,7 @@ export const SolidityUnitTesting = (props: Record) => { />
-
{testFiles?.length ? testFiles.map((testFileObj: any, index) => { +
{testFiles?.length ? testFiles.map((testFileObj: TestObject, index) => { const elemId = `singleTest${testFileObj.fileName}` return (
diff --git a/package.json b/package.json index a32a38bdb3..03e89015e9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,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-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs", + "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-helper,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,solidity-unit-testing,remix-ui-plugin-manager,remix-ui-terminal,remix-ui-editor,remix-ui-app,remix-ui-tabs", "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",