pull/1585/head
bunsenstraat 3 years ago
commit 067837b018
  1. 9
      apps/remix-ide/src/app.js
  2. 4
      apps/remix-ide/src/app/files/fileManager.js
  3. 334
      apps/remix-ide/src/app/tabs/compile-tab.js
  4. 235
      apps/remix-ide/src/app/tabs/styles/compile-tab-styles.js
  5. 4
      apps/solidity-compiler/.babelrc
  6. 16
      apps/solidity-compiler/.browserslistrc
  7. 17
      apps/solidity-compiler/src/app/app.tsx
  8. 294
      apps/solidity-compiler/src/app/compiler-api.ts
  9. 75
      apps/solidity-compiler/src/app/compiler.ts
  10. 0
      apps/solidity-compiler/src/assets/.gitkeep
  11. BIN
      apps/solidity-compiler/src/assets/img/ipfs.webp
  12. 4
      apps/solidity-compiler/src/assets/js/.gitignore
  13. 3
      apps/solidity-compiler/src/environments/environment.prod.ts
  14. 6
      apps/solidity-compiler/src/environments/environment.ts
  15. BIN
      apps/solidity-compiler/src/favicon.ico
  16. 15
      apps/solidity-compiler/src/index.html
  17. 1
      apps/solidity-compiler/src/index.ts
  18. 11
      apps/solidity-compiler/src/main.tsx
  19. 7
      apps/solidity-compiler/src/polyfills.ts
  20. 1
      apps/solidity-compiler/src/styles.css
  21. 9
      apps/solidity-compiler/tsconfig.app.json
  22. 16
      apps/solidity-compiler/tsconfig.json
  23. 15
      apps/solidity-compiler/tsconfig.spec.json
  24. 17
      apps/solidity-compiler/webpack.config.js
  25. 21
      libs/remix-lib/src/index.ts
  26. 53
      libs/remix-lib/src/types/ICompilerApi.ts
  27. 5
      libs/remix-lib/src/web3Provider/web3VmProvider.ts
  28. 4
      libs/remix-simulator/src/methods/transactions.ts
  29. 1
      libs/remix-solidity/src/compiler/compiler-utils.ts
  30. 1
      libs/remix-ui/debugger-ui/src/index.ts
  31. 7
      libs/remix-ui/plugin-manager/src/lib/components/LocalPluginForm.tsx
  32. 4
      libs/remix-ui/plugin-manager/src/types.d.ts
  33. 4
      libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx
  34. 13
      libs/remix-ui/renderer/src/lib/renderer.tsx
  35. 12
      libs/remix-ui/solidity-compiler/src/lib/actions/compiler.ts
  36. 59
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  37. 2
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  38. 52
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  39. 4
      libs/remix-ui/solidity-compiler/src/lib/logic/contract-parser.ts
  40. 52
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  41. 35
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  42. 7
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  43. 3
      nx.json
  44. 2
      package.json
  45. 1
      release-management.md
  46. 2
      tsconfig.base.json
  47. 70
      workspace.json

@ -425,13 +425,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
}
// CONTENT VIEWS & DEFAULT PLUGINS
const compileTab = new CompileTab(
editor,
registry.get('config').api,
registry.get('fileproviders/browser').api,
registry.get('filemanager').api,
contentImport
)
const compileTab = new CompileTab(registry.get('config').api, registry.get('filemanager').api)
const run = new RunTab(
blockchain,
registry.get('config').api,
@ -456,7 +450,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
engine.register([
compileTab,
compileTab.compileTabLogic,
run,
debug,
analysis,

@ -22,7 +22,7 @@ const profile = {
icon: 'assets/img/fileManager.webp',
permission: true,
version: packageJson.version,
methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath'],
methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile'],
kind: 'file-system'
}
const errorMsg = {
@ -398,7 +398,7 @@ class FileManager extends Plugin {
}
fileChangedEvent (path) {
this.emit('currentFileChanged', path)
this.emit('fileChanged', path)
}
fileRenamedEvent (oldName, newName, isFolder) {

@ -1,17 +1,18 @@
/* global */
import React from 'react' // eslint-disable-line
import ReactDOM from 'react-dom'
import { SolidityCompiler, CompileTab as CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { compile } from '@remix-project/remix-solidity'
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompilerApiMixin } from '@remixproject/solidity-compiler-plugin'
import { ViewPlugin } from '@remixproject/engine-web'
import QueryParams from '../../lib/query-params'
// import { ICompilerApi } from '@remix-project/remix-lib-ts'
import * as packageJson from '../../../../../package.json'
const EventEmitter = require('events')
const $ = require('jquery')
const yo = require('yo-yo')
var QueryParams = require('../../lib/query-params')
const addTooltip = require('../ui/tooltip')
const globalRegistry = require('../../global/registry')
const css = require('./styles/compile-tab-styles')
const profile = {
name: 'solidity',
@ -23,222 +24,72 @@ const profile = {
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: packageJson.version,
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile']
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState']
}
// EditorApi:
// - events: ['compilationFinished'],
// - methods: ['getCompilationResult']
class CompileTab extends ViewPlugin {
constructor (editor, config, fileProvider, fileManager, contentImport) {
class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerApi
constructor (config, fileManager) {
super(profile)
this.events = new EventEmitter()
this._view = {
el: null,
warnCompilationSlow: null,
errorContainer: null,
contractEl: null
}
this.contentImport = contentImport
this.queryParams = new QueryParams()
this.fileProvider = fileProvider
// dependencies
this.editor = editor
this.config = config
this.fileManager = fileManager
this.contractsDetails = {}
this.data = {
eventHandlers: {},
loading: false
}
this.config = config
this.queryParams = new QueryParams()
this.compileTabLogic = new CompileTabLogic(this, this.contentImport)
this.compiler = this.compileTabLogic.compiler
this.compileTabLogic.init()
this.contractMap = {}
this.isHardHatProject = false
this.compileErrors = {}
this.compiledFileName = ''
this.selectedVersion = ''
this.configurationSettings = null
this.el = document.createElement('div')
this.el.setAttribute('id', 'compileTabView')
this.initCompilerApi()
}
resetResults () {
this.currentFile = ''
this.contractsDetails = {}
this.emit('statusChanged', { key: 'none' })
this.renderComponent()
renderComponent () {
ReactDOM.render(
<SolidityCompiler api={this}/>
, this.el)
}
setCompileErrors (data) {
this.compileErrors = data
onCurrentFileChanged () {
this.renderComponent()
}
/************
* EVENTS
*/
listenToEvents () {
this.data.eventHandlers.onContentChanged = () => {
this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' })
}
this.editor.event.register('contentChanged', this.data.eventHandlers.onContentChanged)
this.data.eventHandlers.onLoadingCompiler = () => {
this.data.loading = true
this.emit('statusChanged', { key: 'loading', title: 'loading compiler...', type: 'info' })
}
this.compiler.event.register('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
this.data.eventHandlers.onCompilerLoaded = () => {
this.data.loading = false
this.emit('statusChanged', { key: 'none' })
}
this.compiler.event.register('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
this.data.eventHandlers.onStartingCompilation = () => {
this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' })
}
this.data.eventHandlers.onRemoveAnnotations = () => {
this.call('editor', 'clearAnnotations')
}
const resetView = (isLocalhost) => {
this.compileTabLogic.isHardhatProject().then((result) => {
if (result && isLocalhost) this.isHardHatProject = true
else this.isHardHatProject = false
onResetResults () {
this.renderComponent()
})
this.resetResults()
}
this.on('filePanel', 'setWorkspace', (workspace) => {
resetView(workspace.isLocalhost)
})
this.on('remixd', 'rootFolderChanged', () => {
resetView(true)
})
this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.compileTabLogic.event.on('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
this.data.eventHandlers.onCurrentFileChanged = (name) => {
this.currentFile = name
onSetWorkspace () {
this.renderComponent()
}
this.fileManager.events.on('currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.data.eventHandlers.onNoFileSelected = () => {
this.currentFile = ''
onNoFileSelected () {
this.renderComponent()
}
this.fileManager.events.on('noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.data.eventHandlers.onCompilationFinished = (success, data, source) => {
this.setCompileErrors(data)
if (success) {
// forwarding the event to the appManager infra
this.emit('compilationFinished', source.target, source, 'soljson', data)
if (data.errors && data.errors.length > 0) {
this.emit('statusChanged', {
key: data.errors.length,
title: `compilation finished successful with warning${data.errors.length > 1 ? 's' : ''}`,
type: 'warning'
})
} else this.emit('statusChanged', { key: 'succeed', title: 'compilation successful', type: 'success' })
// Store the contracts
this.contractsDetails = {}
this.compiler.visitContracts((contract) => {
this.contractsDetails[contract.name] = parseContracts(
contract.name,
contract.object,
this.compiler.getSource(contract.file)
)
})
} else {
const count = (data.errors ? data.errors.filter(error => error.severity === 'error').length : 0) + data.error ? 1 : 0
this.emit('statusChanged', { key: count, title: `compilation failed with ${count} error${count.length > 1 ? 's' : ''}`, type: 'error' })
}
// Update contract Selection
this.contractMap = {}
if (success) this.compiler.visitContracts((contract) => { this.contractMap[contract.name] = contract })
onCompilationFinished () {
this.renderComponent()
}
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished)
this.data.eventHandlers.onThemeChanged = (theme) => {
const invert = theme.quality === 'dark' ? 1 : 0
const img = document.getElementById('swarmLogo')
if (img) {
img.style.filter = `invert(${invert})`
}
}
globalRegistry.get('themeModule').api.events.on('themeChanged', this.data.eventHandlers.onThemeChanged)
// Run the compiler instead of trying to save the website
$(window).keydown((e) => {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
this.compileTabLogic.runCompiler(this.hhCompilation)
}
})
}
render () {
if (this.el) return this.el
this.el = yo`
<div class="${css.debuggerTabView}" id="compileTabView">
<div id="compiler" class="${css.compiler}"></div>
</div>`
this.renderComponent()
setHardHatCompilation (value) {
this.hhCompilation = value
return this.el
}
setSelectedVersion (version) {
this.selectedVersion = version
async compileWithParameters (compilationTargets, settings) {
return await super.compileWithParameters(compilationTargets, settings)
}
getCompilationResult () {
return this.compileTabLogic.compiler.state.lastCompilationResult
}
addExternalFile (fileName, content) {
this.fileProvider.addExternal(fileName, content)
}
/**
* compile using @arg fileName.
* The module UI will be updated accordingly to the new compilation result.
* This function is used by remix-plugin compiler API.
* @param {string} fileName to compile
*/
compile (fileName) {
addTooltip(yo`<div><b>${this.currentRequest.from}</b> is requiring to compile <b>${fileName}</b></div>`)
return this.compileTabLogic.compileFile(fileName)
}
/**
* compile using @arg compilationTargets and @arg settings
* The module UI will *not* be updated, the compilation result is returned
* This function is used by remix-plugin compiler API.
* @param {object} map of source files.
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
async compileWithParameters (compilationTargets, settings) {
settings.version = settings.version || this.selectedVersion
const res = await compile(compilationTargets, settings)
return res
return super.getCompilationResult()
}
// This function is used for passing the compiler configuration to 'remix-tests'
getCurrentCompilerConfig () {
return {
currentVersion: this.selectedVersion,
evmVersion: this.compileTabLogic.evmVersion,
optimize: this.compileTabLogic.optimize,
runs: this.compileTabLogic.runs
}
getFileManagerMode () {
return this.fileManager.mode
}
/**
@ -247,88 +98,23 @@ class CompileTab extends ViewPlugin {
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
setCompilerConfig (settings) {
this.configurationSettings = settings
super.setCompilerConfig(settings)
this.renderComponent()
// @todo(#2875) should use loading compiler return value to check whether the compiler is loaded instead of "setInterval"
addTooltip(yo`<div><b>${this.currentRequest.from}</b> is updating the <b>Solidity compiler configuration</b>.<pre class="text-left">${JSON.stringify(settings, null, '\t')}</pre></div>`)
}
// TODO : Add success alert when compilation succeed
contractCompiledSuccess () {
return yo`<div></div>`
}
// TODO : Add error alert when compilation failed
contractCompiledError () {
return yo`<div></div>`
}
/************
* METHODS
*/
selectContract (contractName) {
this.selectedContract = contractName
}
render () {
this.renderComponent()
return this.el
}
renderComponent () {
ReactDOM.render(
<SolidityCompiler plugin={this}/>
, this.el)
}
getParameters () {
return this.queryParams.get()
}
setParameters (params) {
this.queryParams.update(params)
}
getConfiguration (name) {
return this.config.get(name)
}
setConfiguration (name, value) {
this.config.set(name, value)
}
fileProviderOf (fileName) {
return this.fileManager.fileProviderOf(fileName)
}
getFileManagerMode () {
return this.fileManager.mode
}
fileExists (fileName) {
return this.call('fileManager', 'exists', fileName)
}
writeFile (fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
saveCurrentFile () {
return this.fileManager.saveCurrentFile()
compile (fileName) {
addTooltip(yo`<div><b>${this.currentRequest.from}</b> is requiring to compile <b>${fileName}</b></div>`)
super.compile(fileName)
}
open (fileName) {
return this.call('fileManager', 'open', fileName)
compileFile (event) {
return super.compileFile(event)
}
onActivation () {
this.call('manager', 'activatePlugin', 'solidity-logic')
this.listenToEvents()
super.onActivation()
this.call('filePanel', 'registerContextMenuItem', {
id: 'solidity',
name: 'compileFile',
@ -340,30 +126,26 @@ class CompileTab extends ViewPlugin {
})
}
// Returns if the compilation was successfull
async compileFile (event) {
if (event.path.length > 0) {
try {
return await this.compileTabLogic.compileFile(event.path[0])
} catch (error) {
return false
getCompilerParameters () {
const params = this.queryParams.get()
params.optimize = (params.optimize === 'false' || params.optimize === null || params.optimize === undefined) ? false : params.optimize
params.optimize = params.optimize === 'true' ? true : params.optimize
return params
}
setCompilerParameters (params) {
this.queryParams.update(params)
}
return false
getAppParameter (name) {
const param = this.config.get(name)
if (param === 'true') return true
if (param === 'false') return false
return param
}
onDeactivation () {
this.editor.event.unregister('contentChanged')
this.editor.event.unregister('sessionSwitched')
this.editor.event.unregister('contentChanged', this.data.eventHandlers.onContentChanged)
this.compiler.event.unregister('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
this.compiler.event.unregister('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
this.compileTabLogic.event.removeListener('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.fileManager.events.removeListener('currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.fileManager.events.removeListener('noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished)
globalRegistry.get('themeModule').api.events.removeListener('themeChanged', this.data.eventHandlers.onThemeChanged)
this.call('manager', 'deactivatePlugin', 'solidity-logic')
setAppParameter (name, value) {
this.config.set(name, value)
}
}

@ -1,239 +1,8 @@
const csjs = require('csjs-inject')
const css = csjs`
.title {
font-size: 1.1em;
font-weight: bold;
margin-bottom: 1em;
}
.panicError {
color: red;
font-size: 20px;
}
.crow {
display: flex;
overflow: auto;
clear: both;
padding: .2em;
}
.checkboxText {
font-weight: normal;
}
.crow label {
cursor:pointer;
}
.crowNoFlex {
overflow: auto;
clear: both;
}
.info {
padding: 10px;
word-break: break-word;
}
.contract {
display: block;
margin: 3% 0;
}
.nightlyBuilds {
display: flex;
flex-direction: row;
align-items: center;
}
.autocompileContainer {
display: flex;
align-items: center;
}
.runs {
width: 40%;
}
.hideWarningsContainer {
display: flex;
align-items: center;
}
.autocompile {}
.autocompileTitle {
font-weight: bold;
margin: 1% 0;
}
.autocompileText {
margin: 1% 0;
font-size: 12px;
overflow: hidden;
word-break: normal;
line-height: initial;
}
.warnCompilationSlow {
margin-left: 1%;
}
.compilerConfig {
display: flex;
align-items: center;
}
.compilerConfig label {
margin: 0;
}
.compilerSection {
padding: 12px 24px 16px;
}
.compilerLabel {
margin-bottom: 2px;
font-size: 11px;
line-height: 12px;
text-transform: uppercase;
}
.copyButton {
padding: 6px;
font-weight: bold;
font-size: 11px;
line-height: 15px;
}
.name {
display: flex;
}
.size {
display: flex;
}
.checkboxes {
display: flex;
width: 100%;
justify-content: space-between;
flex-wrap: wrap;
}
.compileButton {
width: 100%;
margin: 15px 0 10px 0;
font-size: 12px;
}
.container {
margin: 0;
margin-bottom: 2%;
}
.optimizeContainer {
display: flex;
}
.noContractAlert {
display: flex;
justify-content: center;
align-items: center;
}
.contractHelperButtons {
margin-top: 6px;
display: flex;
align-items: center;
justify-content: space-between;
float: right;
}
.copyToClipboard {
font-size: 1rem;
}
.copyIcon {
margin-right: 5px;
}
.log {
display: flex;
flex-direction: column;
margin-bottom: 5%;
overflow: visible;
}
.key {
margin-right: 5px;
text-transform: uppercase;
width: 100%;
}
.value {
display: flex;
width: 100%;
margin-top: 1.5%;
}
.questionMark {
margin-left: 2%;
cursor: pointer;
}
.questionMark:hover {
}
.detailsJSON {
padding: 8px 0;
border: none;
}
.icon {
margin-right: 0.3em;
}
.errorBlobs {
padding-left: 5px;
padding-right: 5px;
word-break: break-word;
}
.storageLogo {
width: 20px;
height: 20px;
}
.spinningIcon {
display: inline-block;
position: relative;
animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-webkit-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-moz-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-o-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-ms-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.bouncingIcon {
display: inline-block;
position: relative;
-moz-animation: bounce 2s infinite linear;
-o-animation: bounce 2s infinite linear;
-webkit-animation: bounce 2s infinite linear;
animation: bounce 2s infinite linear;
}
@-webkit-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-moz-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-o-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-ms-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
.compilerTabView {
padding: 2%;
}
`

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

@ -0,0 +1,16 @@
# This file is used by:
# 1. autoprefixer to adjust CSS to support the below specified browsers
# 2. babel preset-env to adjust included polyfills
#
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
#
# If you need to support different browsers in production, you may tweak the list below.
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR
not IE 9-11 # For IE 9-11 support, remove 'not'.

@ -0,0 +1,17 @@
import React, { useState, useEffect } from 'react';
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompilerClientApi } from './compiler'
const remix = new CompilerClientApi()
export const App = () => {
return (
<div>
<SolidityCompiler api={remix} />
</div>
);
};
export default App;

@ -0,0 +1,294 @@
import { compile } from '@remix-project/remix-solidity'
import { CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import type { ConfigurationSettings } from '@remix-project/remix-lib-ts'
export const CompilerApiMixin = (Base) => class extends Base {
currentFile: string
contractMap: {
file: string
} | Record<string, any>
compileErrors: any
compileTabLogic: CompileTabLogic
contractsDetails: Record<string, any>
configurationSettings: ConfigurationSettings
onCurrentFileChanged: (fileName: string) => void
onResetResults: () => void
onSetWorkspace: (workspace: any) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void
onContentChanged: () => void
initCompilerApi () {
this.configurationSettings = null
this._view = {
warnCompilationSlow: null,
errorContainer: null,
contractEl: null
}
this.contractsDetails = {}
this.data = {
eventHandlers: {},
loading: false
}
this.contractMap = {}
this.contractsDetails = {}
this.compileErrors = {}
this.compiledFileName = ''
this.currentFile = ''
}
onActivation () {
this.listenToEvents()
}
onDeactivation () {
this.off('editor', 'contentChanged')
if (this.data.eventHandlers.onLoadingCompiler) {
this.compiler.event.unregister('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
}
if (this.data.eventHandlers.onCompilerLoaded) {
this.compiler.event.unregister('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
}
if (this.data.eventHandlers.onCompilationFinished) {
this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished)
}
this.off('filePanel', 'setWorkspace')
this.off('remixd', 'rootFolderChanged')
this.off('editor', 'sessionSwitched')
if (this.data.eventHandlers.onStartingCompilation) {
this.compileTabLogic.event.off('startingCompilation', this.data.eventHandlers.onStartingCompilation)
}
if (this.data.eventHandlers.onRemoveAnnotations) {
this.compileTabLogic.event.off('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
}
this.off('fileManager', 'currentFileChanged')
this.off('fileManager', 'noFileSelected')
this.off('themeModule', 'themeChanged')
if (this.data.eventHandlers.onKeyDown) {
window.document.removeEventListener('keydown', this.data.eventHandlers.onKeyDown)
}
}
resolveContentAndSave (url) {
return this.call('contentImport', 'resolveAndSave', url)
}
compileWithHardhat (configFile) {
return this.call('hardhat', 'compile', configFile)
}
logToTerminal (content) {
return this.call('terminal', 'log', content)
}
getCompilationResult () {
return this.compileTabLogic.compiler.state.lastCompilationResult
}
getCompilerState () {
return this.compileTabLogic.getCompilerState()
}
/**
* compile using @arg fileName.
* The module UI will be updated accordingly to the new compilation result.
* This function is used by remix-plugin compiler API.
* @param {string} fileName to compile
*/
compile (fileName) {
return this.compileTabLogic.compileFile(fileName)
}
compileFile (event) {
if (event.path.length > 0) {
this.compileTabLogic.compileFile(event.path[0])
}
}
/**
* compile using @arg compilationTargets and @arg settings
* The module UI will *not* be updated, the compilation result is returned
* This function is used by remix-plugin compiler API.
* @param {object} map of source files.
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
async compileWithParameters (compilationTargets, settings) {
const compilerState = this.getCompilerState()
settings.version = settings.version || compilerState.currentVersion
const res = await compile(compilationTargets, settings, (url, cb) => this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
return res
}
// This function is used for passing the compiler configuration to 'remix-tests'
getCurrentCompilerConfig () {
const compilerState = this.getCompilerState()
return {
currentVersion: compilerState.currentVersion,
evmVersion: compilerState.evmVersion,
optimize: compilerState.optimize,
runs: compilerState.runs
}
}
/**
* set the compiler configuration
* This function is used by remix-plugin compiler API.
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
setCompilerConfig (settings) {
this.configurationSettings = settings
}
fileExists (fileName) {
return this.call('fileManager', 'exists', fileName)
}
writeFile (fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
open (fileName) {
return this.call('fileManager', 'open', fileName)
}
saveCurrentFile () {
return this.call('fileManager', 'saveCurrentFile')
}
resetResults () {
this.currentFile = ''
this.contractsDetails = {}
this.emit('statusChanged', { key: 'none' })
if (this.onResetResults) this.onResetResults()
}
listenToEvents () {
this.on('editor', 'contentChanged', () => {
this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' })
if (this.onContentChanged) this.onContentChanged()
})
this.data.eventHandlers.onLoadingCompiler = () => {
this.data.loading = true
this.emit('statusChanged', { key: 'loading', title: 'loading compiler...', type: 'info' })
}
this.compiler.event.register('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
this.data.eventHandlers.onCompilerLoaded = () => {
this.data.loading = false
this.emit('statusChanged', { key: 'none' })
}
this.compiler.event.register('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
this.data.eventHandlers.onStartingCompilation = () => {
this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' })
}
this.data.eventHandlers.onRemoveAnnotations = () => {
this.call('editor', 'clearAnnotations')
}
this.on('filePanel', 'setWorkspace', (workspace) => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost)
})
this.on('remixd', 'rootFolderChanged', () => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(true)
})
this.on('editor', 'sessionSwitched', () => {
if (this.onSessionSwitched) this.onSessionSwitched()
})
this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.compileTabLogic.event.on('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
this.data.eventHandlers.onCurrentFileChanged = (name) => {
this.currentFile = name
if (this.onCurrentFileChanged) this.onCurrentFileChanged(name)
}
this.on('fileManager', 'currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.data.eventHandlers.onNoFileSelected = () => {
this.currentFile = ''
if (this.onNoFileSelected) this.onNoFileSelected()
}
this.on('fileManager', 'noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.data.eventHandlers.onCompilationFinished = (success, data, source) => {
this.compileErrors = data
if (success) {
// forwarding the event to the appManager infra
this.emit('compilationFinished', source.target, source, 'soljson', data)
if (data.errors && data.errors.length > 0) {
this.emit('statusChanged', {
key: data.errors.length,
title: `compilation finished successful with warning${data.errors.length > 1 ? 's' : ''}`,
type: 'warning'
})
} else this.emit('statusChanged', { key: 'succeed', title: 'compilation successful', type: 'success' })
// Store the contracts
this.contractsDetails = {}
this.compiler.visitContracts((contract) => {
this.contractsDetails[contract.name] = parseContracts(
contract.name,
contract.object,
this.compiler.getSource(contract.file)
)
})
} else {
const count = (data.errors ? data.errors.filter(error => error.severity === 'error').length : 0) + data.error ? 1 : 0
this.emit('statusChanged', { key: count, title: `compilation failed with ${count} error${count > 1 ? 's' : ''}`, type: 'error' })
}
// Update contract Selection
this.contractMap = {}
if (success) this.compiler.visitContracts((contract) => { this.contractMap[contract.name] = contract })
if (this.onCompilationFinished) this.onCompilationFinished(this.contractsDetails, this.contractMap)
}
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished)
this.data.eventHandlers.onThemeChanged = (theme) => {
const invert = theme.quality === 'dark' ? 1 : 0
const img = document.getElementById('swarmLogo')
if (img) {
img.style.filter = `invert(${invert})`
}
}
this.on('themeModule', 'themeChanged', this.data.eventHandlers.onThemeChanged)
// Run the compiler instead of trying to save the website
this.data.eventHandlers.onKeyDown = (e) => {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
this.compileTabLogic.runCompiler(this.getAppParameter('hardhat-compilation'))
}
}
window.document.addEventListener('keydown', this.data.eventHandlers.onKeyDown)
}
}

@ -0,0 +1,75 @@
import { PluginClient } from "@remixproject/plugin";
import { createClient } from "@remixproject/plugin-webview";
import { CompilerApiMixin } from './compiler-api'
import { ICompilerApi } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '@remix-ui/solidity-compiler'
const profile = {
name: 'solidity',
displayName: 'Solidity compiler',
icon: 'assets/img/solidity.webp',
description: 'Compile solidity contracts',
kind: 'compiler',
permission: true,
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: '0.0.1',
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile' ,'getCompilerState']
}
const defaultAppParameters = {
hideWarnings: false,
autoCompile: false,
includeNightlies: false
}
const defaultCompilerParameters = {
runs: '200',
optimize: false,
version: 'soljson-v0.8.7+commit.e28d00a7',
evmVersion: null, // compiler default
language: 'Solidity'
}
export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi {
constructor () {
super()
createClient(this as any)
this.compileTabLogic = new CompileTabLogic(this, this.contentImport)
this.compiler = this.compileTabLogic.compiler
this.compileTabLogic.init()
this.initCompilerApi()
}
getCompilerParameters () {
const params = {
runs: localStorage.getItem('runs') || defaultCompilerParameters['runs'],
optimize: localStorage.getItem('optimize') === 'true' ? true : false,
version: localStorage.getItem('version') || defaultCompilerParameters['version'],
evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters['evmVersion'], // default
language: localStorage.getItem('language') || defaultCompilerParameters['language']
}
return params
}
setCompilerParameters (params) {
for (const key of Object.keys(params)) {
localStorage.setItem(key, params[key])
}
}
getAppParameter (name) {
const param = localStorage.getItem(name) || defaultAppParameters[name]
if (param === 'true') return true
if (param === 'false') return false
return param
}
setAppParameter (name, value) {
localStorage.setItem(name, value)
}
getFileManagerMode () {
return 'browser'
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

@ -0,0 +1,3 @@
export const environment = {
production: true
};

@ -0,0 +1,6 @@
// This file can be replaced during build by using the `fileReplacements` array.
// When building for production, this file is replaced with `environment.prod.ts`.
export const environment = {
production: false
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Solidity Compiler</title>
<base href="./" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"/>
</head>
<body>
<div id="root"></div>
</body>
</html>

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

@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/app';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

@ -0,0 +1,7 @@
/**
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
*
* See: https://github.com/zloirock/core-js#babel
*/
import 'core-js/stable';
import 'regenerator-runtime/runtime';

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"],
"resolveJsonModule": true
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

@ -0,0 +1,17 @@
const nxWebpack = require('@nrwl/react/plugins/webpack')
module.exports = config => {
const nxWebpackConfig = nxWebpack(config)
return {
...nxWebpackConfig,
node: {
fs: 'empty',
tls: 'empty',
readline: 'empty',
net: 'empty',
module: 'empty',
child_process: 'empty'
}
}
}

@ -18,25 +18,19 @@ import * as typeConversion from './execution/typeConversion'
import { TxRunnerVM } from './execution/txRunnerVM'
import { TxRunnerWeb3 } from './execution/txRunnerWeb3'
import * as txResultHelper from './helpers/txResultHelper'
export { ICompilerApi, ConfigurationSettings } from './types/ICompilerApi'
export = modules()
function modules () {
return {
EventManager: EventManager,
helpers: {
const helpers = {
ui: uiHelper,
compiler: compilerHelper,
txResultHelper
},
vm: {
}
const vm = {
Web3Providers: Web3Providers,
DummyProvider: DummyProvider,
Web3VMProvider: Web3VmProvider
},
Storage: Storage,
util: util,
execution: {
}
const execution = {
EventsDecoder: EventsDecoder,
txExecution: txExecution,
txHelper: txHelper,
@ -49,5 +43,4 @@ function modules () {
LogsManager,
forkAt
}
}
}
export { EventManager, helpers, vm, Storage, util, execution }

@ -0,0 +1,53 @@
export interface ICompilerApi {
currentFile: string
contractMap: {
file: string
} | Record<string, any>
compileErrors: any
compileTabLogic: any
contractsDetails: Record<string, any>
configurationSettings: ConfigurationSettings
getCompilerParameters: () => ConfigurationSettings
setCompilerParameters: (ConfigurationSettings?) => void
getAppParameter: (value: string) => string | boolean
setAppParameter: (name: string, value: string | boolean) => void
getFileManagerMode: () => string
setCompilerConfig: (settings: any) => void
getCompilationResult: () => any
onCurrentFileChanged: (fileName: string) => void
onResetResults: () => void,
onSetWorkspace: (workspace: any) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void
onContentChanged: () => void
resolveContentAndSave: (url: string) => Promise<string>
fileExists: (file: string) => Promise<boolean>
writeFile: (file: string, content: string) => Promise<void>
readFile: (file: string) => Promise<string>
open: (file: string) => void
saveCurrentFile: () => void
logToTerminal: (log: terminalLog) => {}
compileWithHardhat: (configPath: string) => Promise<string>
}
export type terminalLog = {
type: 'info' | 'error' | 'warning'
value: string
}
export interface ConfigurationSettings {
version: string,
evmVersion: string,
language: string,
optimize: boolean,
runs: string
}

@ -144,8 +144,9 @@ export class Web3VmProvider {
if (lastOp) {
lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT'
}
this.vmTraces[this.processingHash].gas = '0x' + data.gasUsed.toString(16)
const gasUsed = '0x' + data.gasUsed.toString(16)
this.vmTraces[this.processingHash].gas = gasUsed
this.txsReceipt[this.processingHash].gasUsed = gasUsed
const logs = []
for (const l in data.execResult.logs) {
const log = data.execResult.logs[l]

@ -102,8 +102,8 @@ export class Transactions {
transactionIndex: '0x00',
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
gasUsed: Web3.utils.toHex(receipt.gas),
cumulativeGasUsed: Web3.utils.toHex(receipt.gas),
gasUsed: receipt.gasUsed,
cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block
contractAddress: receipt.contractAddress,
logs: receipt.logs,
status: receipt.status,

@ -22,6 +22,7 @@ export function urlFromVersion (version) {
if (!location.endsWith('/')) location += '/'
url = `${location}soljson.js`
} else {
version = version.replace('.Emscripten.clang', '')
if (!version.startsWith('soljson-v')) version = 'soljson-v' + version
if (!version.endsWith('.js')) version = version + '.js'
url = `${pathToURL[version]}/${version}`

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

@ -20,7 +20,8 @@ const initialState: FormStateProps = {
type: 'iframe',
hash: '',
methods: [],
location: 'sidePanel'
location: 'sidePanel',
canActivate: []
}
const defaultProfile = {
@ -48,10 +49,10 @@ function LocalPluginForm ({ closeModal, visible, pluginManager }: LocalPluginFor
setName(storagePlugin.name)
setUrl(storagePlugin.url)
setLocation(storagePlugin.location as 'sidePanel' | 'mainPanel' | 'none')
setMethods(storagePlugin.methods)
setMethods(Array.isArray(storagePlugin.methods) ? storagePlugin.methods.join(',') : storagePlugin.methods)
setType(storagePlugin.type)
setDisplayName(storagePlugin.displayName)
setCanactivate(storagePlugin.canActivate)
setCanactivate(Array.isArray(storagePlugin.canActivate) ? storagePlugin.canActivate.join(',') : storagePlugin.canActivate)
}, [])
const handleModalOkClick = async () => {

@ -178,9 +178,9 @@ export interface FormStateProps {
url: string
type: 'iframe' | 'ws'
hash: string
methods: any
methods: string[]
location: string
canActivate?: any
canActivate: string[]
}
export type PluginManagerProfile = Profile & {

@ -29,7 +29,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => {
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded))
// triggered each time there's a new verified publish (means hash correspond)
api.addExternalFile('swarm/' + result.item.hash, result.item.content)
api.writeFile('swarm/' + result.item.hash, result.item.content)
} catch (err) {
let parseError = err
try {
@ -43,7 +43,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => {
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded))
// triggered each time there's a new verified publish (means hash correspond)
api.addExternalFile('ipfs/' + result.item.hash, result.item.content)
api.writeFile('ipfs/' + result.item.hash, result.item.content)
} catch (err) {
modal('IPFS Publish Failed', publishMessageFailed(storage, err))
}

@ -69,7 +69,7 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
}
const addAnnotation = (file, error) => {
if (file === plugin.getConfiguration('currentFile')) {
if (file === plugin.getAppParameter('currentFile')) {
plugin.call('editor', 'addAnnotation', error, file)
}
}
@ -86,17 +86,12 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
setClose(true)
}
const _errorClick = (errFile, errLine, errCol) => {
if (errFile !== plugin.getConfiguration('currentFile')) {
const _errorClick = async (errFile, errLine, errCol) => {
if (errFile !== plugin.getAppParameter('currentFile')) {
// TODO: refactor with this._components.contextView.jumpTo
const provider = plugin.fileProviderOf(errFile)
if (provider) {
provider.exists(errFile).then(() => {
if (await plugin.fileExists(errFile)) {
plugin.open(errFile)
plugin.call('editor', 'gotoLine', errLine, errCol)
}).catch(error => {
if (error) return console.log(error)
})
}
} else {
plugin.call('editor', 'gotoLine', errLine, errCol)

@ -1,5 +1,5 @@
import React from 'react'
import { CompileTabLogic } from '../logic/compileTabLogic'
export const setEditorMode = (mode: string) => {
return {
type: 'SET_EDITOR_MODE',
@ -26,10 +26,10 @@ export const resetCompilerMode = () => (dispatch: React.Dispatch<any>) => {
})
}
export const listenToEvents = (compileTabLogic, api) => (dispatch: React.Dispatch<any>) => {
api.on('editor', 'sessionSwitched', () => {
export const listenToEvents = (compileTabLogic: CompileTabLogic, api) => (dispatch: React.Dispatch<any>) => {
api.onSessionSwitched = () => {
dispatch(setEditorMode('sessionSwitched'))
})
}
compileTabLogic.event.on('startingCompilation', () => {
dispatch(setCompilerMode('startingCompilation'))
@ -39,9 +39,9 @@ export const listenToEvents = (compileTabLogic, api) => (dispatch: React.Dispatc
dispatch(setCompilerMode('compilationDuration', speed))
})
api.on('editor', 'contentChanged', () => {
api.onContentChanged = () => {
dispatch(setEditorMode('contentChanged'))
})
}
compileTabLogic.compiler.event.register('loadingCompiler', () => {
dispatch(setCompilerMode('loadingCompiler'))

@ -1,6 +1,7 @@
import React, { useEffect, useState, useRef, useReducer } from 'react' // eslint-disable-line
import semver from 'semver'
import { CompilerContainerProps, ConfigurationSettings } from './types'
import { CompilerContainerProps } from './types'
import { ConfigurationSettings } from '@remix-project/remix-lib-ts'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '@remix-project/remix-solidity'
import { compilerReducer, compilerInitialState } from './reducers/compiler'
@ -18,22 +19,21 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => {
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings } = props // eslint-disable-line
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject } = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,
optimise: false,
optimize: false,
compileTimeout: null,
timeout: 300,
allversions: [],
customVersions: [],
selectedVersion: null,
defaultVersion: 'soljson-v0.8.7+commit.e28d00a7.js', // this default version is defined: in makeMockCompiler (for browser test)
selectedLanguage: '',
runs: '',
compiledFileName: '',
includeNightlies: false,
language: '',
language: 'Solidity',
evmVersion: ''
})
const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false)
@ -56,7 +56,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
_updateVersionSelector(selectedVersion)
}
})
const currentFileName = api.getConfiguration('currentFile')
const currentFileName = api.currentFile
currentFile(currentFileName)
listenToEvents(compileTabLogic, api)(dispatch)
@ -65,19 +65,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
useEffect(() => {
if (compileTabLogic && compileTabLogic.compiler) {
setState(prevState => {
const params = api.getParameters()
const optimize = params.optimize === 'false' ? false : params.optimize === 'true' ? true : null
const runs = params.runs
const params = api.getCompilerParameters()
const optimize = params.optimize
const runs = params.runs as string
const evmVersion = params.evmVersion
const autoCompile = params.autoCompile === 'false' ? false : params.autoCompile === 'true' ? true : null
return {
...prevState,
hideWarnings: api.getConfiguration('hideWarnings') || false,
autoCompile: typeof autoCompile === 'boolean' ? autoCompile : api.getConfiguration('autoCompile') || false,
includeNightlies: api.getConfiguration('includeNightlies') || false,
optimise: typeof optimize === 'boolean' ? optimize : api.getConfiguration('optimise') || false,
runs: (runs !== null) && (runs !== 'null') && (runs !== undefined) && (runs !== 'undefined') ? runs : 200,
hideWarnings: api.getAppParameter('hideWarnings') as boolean || false,
autoCompile: api.getAppParameter('autoCompile') as boolean || false,
includeNightlies: api.getAppParameter('includeNightlies') as boolean || false,
optimize: optimize,
runs: runs,
evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default'
}
})
@ -153,7 +152,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
allVersions = [...allVersions, ...versions]
selectedVersion = state.defaultVersion
if (api.getParameters().version) selectedVersion = api.getParameters().version
if (api.getCompilerParameters().version) selectedVersion = api.getCompilerParameters().version
// Check if version is a URL and corresponding filename starts with 'soljson'
if (selectedVersion.startsWith('https://')) {
const urlArr = selectedVersion.split('/')
@ -228,8 +227,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
}
const isSolFileSelected = (currentFile = '') => {
if (!currentFile) currentFile = api.getConfiguration('currentFile')
const isSolFileSelected = (currentFile: string = '') => {
if (!currentFile) currentFile = api.currentFile
if (!currentFile) return false
const extention = currentFile.substr(currentFile.length - 3, currentFile.length)
return extention.toLowerCase() === 'sol' || extention.toLowerCase() === 'yul'
@ -298,7 +297,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
const compile = () => {
const currentFile = api.getConfiguration('currentFile')
const currentFile = api.currentFile
if (!isSolFileSelected()) return
@ -322,7 +321,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
}
updateCurrentVersion(selectedVersion)
api.setParameters({ version: selectedVersion })
api.setCompilerParameters({ version: selectedVersion })
let url
if (customUrl !== '') {
@ -332,7 +331,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
updateCurrentVersion(selectedVersion)
url = customUrl
api.setParameters({ version: selectedVersion })
api.setCompilerParameters({ version: selectedVersion })
} else {
if (helper.checkSpecialChars(selectedVersion)) {
return console.log('loading ' + selectedVersion + ' not allowed, special chars not allowed.')
@ -403,7 +402,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleAutoCompile = (e) => {
const checked = e.target.checked
api.setConfiguration('autoCompile', checked)
api.setAppParameter('autoCompile', checked)
checked && compile()
setState(prevState => {
return { ...prevState, autoCompile: checked }
@ -413,7 +412,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleOptimizeChange = (value) => {
const checked = !!value
api.setConfiguration('optimise', checked)
api.setAppParameter('optimize', checked)
compileTabLogic.setOptimize(checked)
if (compileTabLogic.optimize) {
compileTabLogic.setRuns(parseInt(state.runs))
@ -422,7 +421,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
state.autoCompile && compile()
setState(prevState => {
return { ...prevState, optimise: checked }
return { ...prevState, optimize: checked }
})
}
@ -439,7 +438,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleHideWarningsChange = (e) => {
const checked = e.target.checked
api.setConfiguration('hideWarnings', checked)
api.setAppParameter('hideWarnings', checked)
state.autoCompile && compile()
setState(prevState => {
return { ...prevState, hideWarnings: checked }
@ -450,7 +449,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const checked = e.target.checked
if (!checked) handleLoadVersion(state.defaultVersion)
api.setConfiguration('includeNightlies', checked)
api.setAppParameter('includeNightlies', checked)
setState(prevState => {
return { ...prevState, includeNightlies: checked }
})
@ -481,7 +480,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const checked = event.target.checked
sethhCompilation(checked)
api.setHardHatCompilation(checked)
api.setAppParameter('hardhat-compilation', checked)
}
/*
@ -552,7 +551,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimise} />
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
@ -563,7 +562,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimise}
disabled={!state.optimize}
/>
</div>
</div>
@ -573,7 +572,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</div>
</div>
{
api.isHardHatProject &&
isHardhatProject &&
<div className="mt-3 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={updatehhCompilation} id="enableHardhat" type="checkbox" title="Enable Hardhat Compilation" checked={hhCompilation} />
<label className="form-check-label custom-control-label" htmlFor="enableHardhat">Enable Hardhat Compilation</label>

@ -115,7 +115,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
let node
if (propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly') {
node = <pre>{ details[propertyName] }</pre>
} else if (propertyName === 'abi' || propertyName === 'metadata') {
} else if (details[propertyName] && (propertyName === 'abi' || propertyName === 'metadata')) {
if (details[propertyName] !== '') {
try {
node = <div>

@ -1,15 +1,7 @@
import { Plugin } from '@remixproject/engine'
import { ICompilerApi } from '@remix-project/remix-lib-ts'
const packageJson = require('../../../../../../package.json')
const Compiler = require('@remix-project/remix-solidity').Compiler
const EventEmitter = require('events')
const profile = {
name: 'solidity-logic',
displayName: 'Solidity compiler logic',
description: 'Compile solidity contracts - Logic',
methods: ['getCompilerState'],
version: packageJson.version
}
declare global {
interface Window {
@ -18,7 +10,7 @@ declare global {
}
const _paq = window._paq = window._paq || [] //eslint-disable-line
export class CompileTab extends Plugin {
export class CompileTabLogic {
public compiler
public optimize
public runs
@ -26,46 +18,44 @@ export class CompileTab extends Plugin {
public compilerImport
public event
constructor (public api, public contentImport) {
super(profile)
constructor (public api: ICompilerApi, public contentImport) {
this.event = new EventEmitter()
this.compiler = new Compiler((url, cb) => this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
this.compiler = new Compiler((url, cb) => api.resolveContentAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
}
init () {
this.optimize = this.api.getParameters().optimize
this.optimize = this.optimize === 'true'
this.api.setParameters({ optimize: this.optimize })
this.optimize = this.api.getCompilerParameters().optimize
this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
this.runs = this.api.getParameters().runs
this.runs = this.api.getCompilerParameters().runs
this.runs = this.runs && this.runs !== 'undefined' ? this.runs : 200
this.api.setParameters({ runs: this.runs })
this.api.setCompilerParameters({ runs: this.runs })
this.compiler.set('runs', this.runs)
this.evmVersion = this.api.getParameters().evmVersion
this.evmVersion = this.api.getCompilerParameters().evmVersion
if (this.evmVersion === 'undefined' || this.evmVersion === 'null' || !this.evmVersion) {
this.evmVersion = null
}
this.api.setParameters({ evmVersion: this.evmVersion })
this.api.setCompilerParameters({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
setOptimize (newOptimizeValue) {
this.optimize = newOptimizeValue
this.api.setParameters({ optimize: this.optimize })
this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
}
setRuns (runs) {
this.runs = runs
this.api.setParameters({ runs: this.runs })
this.api.setCompilerParameters({ runs: this.runs })
this.compiler.set('runs', this.runs)
}
setEvmVersion (newEvmVersion) {
this.evmVersion = newEvmVersion
this.api.setParameters({ evmVersion: this.evmVersion })
this.api.setCompilerParameters({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
@ -87,15 +77,14 @@ export class CompileTab extends Plugin {
*/
compileFile (target) {
if (!target) throw new Error('No target provided for compiliation')
const provider = this.api.fileProviderOf(target)
if (!provider) throw new Error(`cannot compile ${target}. Does not belong to any explorer`)
return new Promise((resolve, reject) => {
provider.get(target, (error, content) => {
if (error) return reject(error)
this.api.readFile(target).then((content) => {
const sources = { [target]: { content } }
this.event.emit('startingCompilation')
// setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation')
setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100)
}).catch((error) => {
reject(error)
})
})
}
@ -124,16 +113,17 @@ export class CompileTab extends Plugin {
const configFilePath = 'remix-compiler.config.js'
this.api.writeFile(configFilePath, fileContent)
_paq.push(['trackEvent', 'compiler', 'compileWithHardhat'])
this.call('hardhat', 'compile', configFilePath).then((result) => {
this.call('terminal', 'log', { type: 'info', value: result })
this.api.compileWithHardhat(configFilePath).then((result) => {
this.api.logToTerminal({ type: 'info', value: result })
}).catch((error) => {
this.call('terminal', 'log', { type: 'error', value: error })
this.api.logToTerminal({ type: 'error', value: error })
})
}
}
// TODO readd saving current file
this.api.saveCurrentFile()
this.event.emit('removeAnnotations')
var currentFile = this.api.getConfiguration('currentFile')
var currentFile = this.api.currentFile
return this.compileFile(currentFile)
} catch (err) {
console.error(err)

@ -1,8 +1,8 @@
'use strict'
import * as solcTranslate from 'solc/translate'
import * as remixLib from '@remix-project/remix-lib'
import { execution } from '@remix-project/remix-lib'
const txHelper = remixLib.execution.txHelper
const txHelper = execution.txHelper
export function parseContracts (contractName, contract, source) {
const detail: Record<string, any> = {}

@ -9,10 +9,12 @@ import { Renderer } from '@remix-ui/renderer' // eslint-disable-line
import './css/style.css'
export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { plugin, plugin: { compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props
const { api, api: { currentFile, compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props
const [state, setState] = useState({
isHardhatProject: false,
currentFile,
contractsDetails: {},
eventHandlers: {},
contractMap: {},
loading: false,
compileTabLogic: null,
compiler: null,
@ -30,6 +32,37 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
})
const [currentVersion, setCurrentVersion] = useState('')
api.onCurrentFileChanged = (currentFile: string) => {
setState(prevState => {
return { ...prevState, currentFile }
})
}
api.onResetResults = () => {
setState(prevState => {
return { ...prevState, currentFile: '', contractsDetails: {}, contractMap: {} }
})
}
api.onSetWorkspace = async (isLocalhost: boolean) => {
const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject()
setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat }
})
}
api.onNoFileSelected = () => {
setState(prevState => {
return { ...prevState, currentFile: '' }
})
}
api.onCompilationFinished = (contractsDetails: any, contractMap: any) => {
setState(prevState => {
return { ...prevState, contractsDetails, contractMap }
})
}
const toast = (message: string) => {
setState(prevState => {
return { ...prevState, toasterMsg: message }
@ -38,7 +71,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
const updateCurrentVersion = (value) => {
setCurrentVersion(value)
plugin.setSelectedVersion(value)
api.setCompilerParameters({ version: value })
}
const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
@ -75,23 +108,22 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
</div>
)
const currentFile = plugin.getConfiguration('currentFile')
return (
<>
<div id="compileTabView">
<CompilerContainer api={plugin} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<ContractSelection api={plugin} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} />
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<ContractSelection api={api} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} />
<div className="remixui_errorBlobs p-4" data-id="compiledErrors">
<span data-id={`compilationFinishedWith_${currentVersion}`}></span>
{ compileErrors.error && <Renderer message={compileErrors.error.formattedMessage || compileErrors.error} plugin={plugin} opt={{ type: compileErrors.error.severity || 'error', errorType: compileErrors.error.type }} /> }
{ compileErrors.error && <Renderer message={compileErrors.error.formattedMessage || compileErrors.error} plugin={api} opt={{ type: compileErrors.error.severity || 'error', errorType: compileErrors.error.type }} /> }
{ compileErrors.error && (compileErrors.error.mode === 'panic') && modal('Error', panicMessage(compileErrors.error.formattedMessage), 'Close', null) }
{ compileErrors.errors && compileErrors.errors.length && compileErrors.errors.map((err, index) => {
if (plugin.getConfiguration('hideWarnings')) {
if (api.getAppParameter('hideWarnings')) {
if (err.severity !== 'warning') {
return <Renderer key={index} message={err.formattedMessage} plugin={plugin} opt={{ type: err.severity, errorType: err.type }} />
return <Renderer key={index} message={err.formattedMessage} plugin={api} opt={{ type: err.severity, errorType: err.type }} />
}
} else {
return <Renderer key={index} message={err.formattedMessage} plugin={plugin} opt={{ type: err.severity, errorType: err.type }} />
return <Renderer key={index} message={err.formattedMessage} plugin={api} opt={{ type: err.severity, errorType: err.type }} />
}
}) }
</div>

@ -1,24 +1,15 @@
import { ICompilerApi, ConfigurationSettings } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '../logic/compileTabLogic'
export type onCurrentFileChanged = (fileName: string) => void
export interface SolidityCompilerProps {
plugin: {
contractMap: {
file: string
} | Record<string, any>
compileErrors: any,
compileTabLogic: any,
contractsDetails: Record<string, any>,
contentImport: any,
call: (...args) => void
on: (...args) => void,
setSelectedVersion: (value: string) => void,
configurationSettings: ConfigurationSettings,
getConfiguration: (value: string) => string,
setConfiguration: (name: string, value: string) => void
},
api: ICompilerApi
}
export interface CompilerContainerProps {
api: any,
compileTabLogic: any,
api: ICompilerApi,
compileTabLogic: CompileTabLogic,
isHardhatProject: boolean,
tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string,
@ -26,18 +17,10 @@ export interface CompilerContainerProps {
configurationSettings: ConfigurationSettings
}
export interface ContractSelectionProps {
api: any,
api: ICompilerApi,
contractMap: {
file: string
} | Record<string, any>,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
contractsDetails: Record<string, any>
}
export interface ConfigurationSettings {
version: string,
evmVersion: string,
language: string,
optimize: boolean,
runs: string
}

@ -1,6 +1,6 @@
import React, { useEffect, useState, useReducer } from 'react'
import Button from './Button/StaticAnalyserButton' // eslint-disable-line
import remixLib from '@remix-project/remix-lib'
import { util } 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
@ -9,7 +9,6 @@ import { compilation } from './actions/staticAnalysisActions'
import { initialState, analysisReducer } from './reducers/staticAnalysisReducer'
import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line
const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis
const utils = remixLib.util
declare global {
interface Window {
@ -38,7 +37,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
})
}
const groupedModules = utils.groupBy(
const groupedModules = util.groupBy(
preProcessModules(runner.modules()),
'categoryId'
)
@ -217,7 +216,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
})
// Slither Analysis
if (slitherEnabled) {
props.analysisModule.call('solidity-logic', 'getCompilerState').then(async (compilerState) => {
props.analysisModule.call('solidity', 'getCompilerState').then((compilerState) => {
const { currentVersion, optimize, evmVersion } = compilerState
props.analysisModule.call('terminal', 'log', { type: 'info', value: '[Slither Analysis]: Running...' })
_paq.push(['trackEvent', 'solidityStaticAnalyzer', 'analyzeWithSlither'])

@ -120,6 +120,9 @@
},
"remix-ui-renderer": {
"tags": []
},
"solidity-compiler": {
"tags": []
}
}
}

@ -50,7 +50,7 @@
"bumpVersion:libs": "gulp & gulp syncLibVersions;",
"browsertest": "sleep 5 && npm run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",
"build:production": "NODE_ENV=production npx nx build remix-ide --with-deps --skip-nx-cache",

@ -15,6 +15,7 @@ Release managers will oversee the various aspects of a project before it is due
## Quality checks:
The quality of the release needs to be reviewed before a project is officially launched.
The release manager is in charge of ensuring manual testing is properly planned and done.
During the feature freeze time, only the release manager has permission to merge pull requests. As staging should at this point be already deployed, this is to ensure that the release manager has enough visibility on the changes being applied.
Also that unit testing and e2e for new feaures have been included.
## Deployment:

@ -25,12 +25,14 @@
"@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"],
"@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"],
"@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"],
"@remixproject/solidity-compiler-plugin": ["apps/solidity-compiler/src/index.ts"],
"@remix-project/remixd": ["dist/libs/remixd/index.js"],
"@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"],
"@remix-ui/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"],
"@remix-ui/utils": ["libs/remix-ui/utils/src/index.ts"],
"@remix-ui/clipboard": ["libs/remix-ui/clipboard/src/index.ts"],
"@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"],
"@remix-project/remix-lib-ts": ["libs/remix-lib/src/index.ts"],
"@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"],

@ -875,6 +875,76 @@
}
}
}
},
"solidity-compiler": {
"root": "apps/solidity-compiler",
"sourceRoot": "apps/solidity-compiler/src",
"projectType": "application",
"schematics": {},
"architect": {
"build": {
"builder": "@nrwl/web:build",
"options": {
"outputPath": "dist/apps/solidity-compiler",
"index": "apps/solidity-compiler/src/index.html",
"main": "apps/solidity-compiler/src/main.tsx",
"polyfills": "apps/solidity-compiler/src/polyfills.ts",
"tsConfig": "apps/solidity-compiler/tsconfig.app.json",
"assets": [
"apps/solidity-compiler/src/favicon.ico",
"apps/solidity-compiler/src/assets",
"apps/solidity-compiler/src/index.html"
],
"styles": ["apps/solidity-compiler/src/styles.css"],
"scripts": [],
"webpackConfig": "apps/solidity-compiler/webpack.config.js",
"maxWorkers": 2
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/solidity-compiler/src/environments/environment.ts",
"with": "apps/solidity-compiler/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@nrwl/web:dev-server",
"options": {
"buildTarget": "solidity-compiler:build"
},
"configurations": {
"production": {
"buildTarget": "solidity-compiler:build:production"
}
}
},
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["apps/solidity-compiler/tsconfig.app.json"],
"exclude": ["**/node_modules/**", "!apps/solidity-compiler/**/*"]
}
}
}
}
},
"cli": {

Loading…
Cancel
Save