Moved existing code to new branch

pull/1339/head
ioedeveloper 4 years ago
parent 6aad3b74ce
commit 8ae133e442
  1. 2
      libs/remix-ui/modal-dialog/src/lib/types/index.ts
  2. 4
      libs/remix-ui/publish-to-storage/.babelrc
  3. 16
      libs/remix-ui/publish-to-storage/.eslintrc
  4. 7
      libs/remix-ui/publish-to-storage/README.md
  5. 1
      libs/remix-ui/publish-to-storage/src/index.ts
  6. 0
      libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.css
  7. 138
      libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx
  8. 102
      libs/remix-ui/publish-to-storage/src/lib/publishOnSwarm.tsx
  9. 110
      libs/remix-ui/publish-to-storage/src/lib/publishToIPFS.tsx
  10. 6
      libs/remix-ui/publish-to-storage/src/lib/types/index.ts
  11. 16
      libs/remix-ui/publish-to-storage/tsconfig.json
  12. 13
      libs/remix-ui/publish-to-storage/tsconfig.lib.json
  13. 4
      libs/remix-ui/solidity-compiler/.babelrc
  14. 16
      libs/remix-ui/solidity-compiler/.eslintrc
  15. 7
      libs/remix-ui/solidity-compiler/README.md
  16. 1
      libs/remix-ui/solidity-compiler/src/index.ts
  17. 90
      libs/remix-ui/solidity-compiler/src/lib/compileTabLogic.ts
  18. 521
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  19. 159
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  20. 234
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  21. 0
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.css
  22. 97
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  23. 24
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  24. 16
      libs/remix-ui/solidity-compiler/tsconfig.json
  25. 13
      libs/remix-ui/solidity-compiler/tsconfig.lib.json
  26. 6
      nx.json
  27. 6
      tsconfig.json
  28. 38
      workspace.json

@ -1,7 +1,7 @@
export interface ModalDialogProps {
id?: string
title?: string,
message?: string,
message?: string | JSX.Element,
okLabel?: string,
okFn?: () => void,
cancelLabel?: string,

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

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,7 @@
# remix-ui-publish-to-storage
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-publish-to-storage` to execute the unit tests via [Jest](https://jestjs.io).

@ -0,0 +1 @@
export * from './lib/remix-ui-publish-to-storage';

@ -0,0 +1,138 @@
import React, { useEffect, useState } from 'react' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { RemixUiPublishToStorageProps } from './types'
import { publishToIPFS } from './publishToIPFS'
import { publishToSwarm } from './publishOnSwarm'
import './css/publish-to-storage.css'
export const PublishToStorage = (props: RemixUiPublishToStorageProps) => {
const { storage, fileProvider, fileManager, contract } = props
const [state, setState] = useState({
modal: {
title: '',
message: null,
hide: true,
ok: {
label: '',
fn: null
},
cancel: {
label: '',
fn: null
}
}
})
useEffect(() => {
const storageService = async () => {
if ((contract.metadata === undefined || contract.metadata.length === 0)) {
modal('Publish To Storage', 'This contract may be abstract, may not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.', {
label: 'OK',
fn: () => {}
}, null)
} else {
if (storage === 'swarm') {
try {
const result = await publishToSwarm(contract, fileManager)
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded), {
label: 'OK',
fn: () => {}
}, null)
// triggered each time there's a new verified publish (means hash correspond)
fileProvider.addExternal('swarm/' + result.item.hash, result.item.content)
} catch (err) {
try {
err = JSON.stringify(err)
} catch (e) {}
modal(`Swarm Publish Failed`, publishMessageFailed(storage, err), {
label: 'OK',
fn: () => {}
}, null)
}
} else {
try {
const result = await publishToIPFS(contract, fileManager)
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded), {
label: 'OK',
fn: () => {}
}, null)
// triggered each time there's a new verified publish (means hash correspond)
fileProvider.addExternal('swarm/' + result.item.hash, result.item.content)
} catch (err) {
modal(`Swarm Publish Failed`, publishMessageFailed(storage, err), {
label: 'OK',
fn: () => {}
}, null)
}
}
}
}
if (contract) {
storageService()
}
}, [contract])
const publishMessage = (uploaded) => {
return (
<span> Metadata of {contract.name.toLowerCase()} was published successfully. <br />
<pre>
<div>
{ uploaded.map((value) => {
<div><b>{ value.filename }</b> : <pre>{ value.output.url }</pre></div>
}) }
</div>
</pre>
</span>
)
}
const publishMessageFailed = (storage, err) => {
return (
<span>Failed to publish metadata file to { storage }, please check the { storage } gateways is available. <br />
{err}
</span>
)
}
const handleHideModal = () => {
setState(prevState => {
return { ...prevState, modal: { ...prevState.modal, hide: true, message: null } }
})
}
const modal = async (title: string, message: string | JSX.Element, ok: { label: string, fn: () => void }, cancel: { label: string, fn: () => void }) => {
await setState(prevState => {
return {
...prevState,
modal: {
...prevState.modal,
hide: false,
message,
title,
ok,
cancel,
handleHide: handleHideModal
}
}
})
}
return (
<ModalDialog
id='publishToStorageModalDialog'
title={ state.modal.title }
message={ state.modal.message }
hide={ state.modal.hide }
ok={ state.modal.ok }
cancel={ state.modal.cancel }
handleHide={ handleHideModal }>
{ (typeof state.modal.message !== 'string') && state.modal.message }
</ModalDialog>
)
}
export default PublishToStorage

@ -0,0 +1,102 @@
import swarm from 'swarmgw'
const swarmgw = swarm()
export const publishToSwarm = async (contract, fileManager) => {
// gather list of files to publish
const sources = []
let metadata
let item = null
const uploaded = []
try {
metadata = JSON.parse(contract.metadata)
} catch (e) {
throw new Error(e)
}
if (metadata === undefined) {
throw new Error('No metadata')
}
await Promise.all(Object.keys(metadata.sources).map(fileName => {
// find hash
let hash = null
try {
// we try extract the hash defined in the metadata.json
// in order to check if the hash that we get after publishing is the same as the one located in metadata.json
// if it's not the same, we throw "hash mismatch between solidity bytecode and uploaded content"
// if we don't find the hash in the metadata.json, the check is not done.
//
// TODO: refactor this with publishOnIpfs
if (metadata.sources[fileName].urls) {
metadata.sources[fileName].urls.forEach(url => {
if (url.includes('bzz')) hash = url.match('(bzzr|bzz-raw)://(.+)')[1]
})
}
} catch (e) {
throw new Error('Error while extracting the hash from metadata.json')
}
fileManager.fileProviderOf(fileName).get(fileName, (error, content) => {
if (error) {
console.log(error)
} else {
sources.push({
content: content,
hash: hash,
filename: fileName
})
}
})
}))
// publish the list of sources in order, fail if any failed
await Promise.all(sources.map((item) => {
swarmVerifiedPublish(item.content, item.hash, (error, result) => {
try {
item.hash = result.url.match('bzz-raw://(.+)')[1]
} catch (e) {
item.hash = '<Metadata inconsistency> - ' + item.fileName
}
item.output = result
uploaded.push(item)
// TODO this is a fix cause Solidity metadata does not contain the right swarm hash (poc 0.3)
metadata.sources[item.filename].urls[0] = result.url
})
}))
const metadataContent = JSON.stringify(metadata)
swarmVerifiedPublish(metadataContent, '', (error, result) => {
try {
contract.metadataHash = result.url.match('bzz-raw://(.+)')[1]
} catch (e) {
contract.metadataHash = '<Metadata inconsistency> - metadata.json'
}
if (!error) {
item.content = metadataContent
item.hash = contract.metadataHash
}
uploaded.push({
content: contract.metadata,
hash: contract.metadataHash,
filename: 'metadata.json',
output: result
})
})
return { uploaded, item }
}
const swarmVerifiedPublish = (content, expectedHash, cb) => {
swarmgw.put(content, function (err, ret) {
if (err) {
cb(err)
} else if (expectedHash && ret !== expectedHash) {
cb(null, { message: 'hash mismatch between solidity bytecode and uploaded content.', url: 'bzz-raw://' + ret, hash: ret })
} else {
cb(null, { message: 'ok', url: 'bzz-raw://' + ret, hash: ret })
}
})
}

@ -0,0 +1,110 @@
import IpfsClient from 'ipfs-mini'
const ipfsNodes = [
new IpfsClient({ host: 'ipfs.komputing.org', port: 443, protocol: 'https' }),
new IpfsClient({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' }),
new IpfsClient({ host: '127.0.0.1', port: 5001, protocol: 'http' })
]
export const publishToIPFS = async (contract, fileManager) => {
// gather list of files to publish
const sources = []
let metadata
let item = null
const uploaded = []
try {
metadata = JSON.parse(contract.metadata)
} catch (e) {
throw new Error(e)
}
if (metadata === undefined) {
throw new Error('No metadata')
}
await Promise.all(Object.keys(metadata.sources).map(fileName => {
// find hash
let hash = null
try {
// we try extract the hash defined in the metadata.json
// in order to check if the hash that we get after publishing is the same as the one located in metadata.json
// if it's not the same, we throw "hash mismatch between solidity bytecode and uploaded content"
// if we don't find the hash in the metadata.json, the check is not done.
//
// TODO: refactor this with publishOnSwarm
if (metadata.sources[fileName].urls) {
metadata.sources[fileName].urls.forEach(url => {
if (url.includes('ipfs')) hash = url.match('dweb:/ipfs/(.+)')[1]
})
}
} catch (e) {
throw new Error('Error while extracting the hash from metadata.json')
}
fileManager.fileProviderOf(fileName).get(fileName, (error, content) => {
if (error) {
console.log(error)
} else {
sources.push({
content: content,
hash: hash,
filename: fileName
})
}
})
}))
// publish the list of sources in order, fail if any failed
await Promise.all(sources.map(item => {
ipfsVerifiedPublish(item.content, item.hash, (error, result) => {
try {
item.hash = result.url.match('dweb:/ipfs/(.+)')[1]
} catch (e) {
item.hash = '<Metadata inconsistency> - ' + item.fileName
}
item.output = result
uploaded.push(item)
})
}))
const metadataContent = JSON.stringify(metadata)
ipfsVerifiedPublish(metadataContent, '', (error, result) => {
try {
contract.metadataHash = result.url.match('dweb:/ipfs/(.+)')[1]
} catch (e) {
contract.metadataHash = '<Metadata inconsistency> - metadata.json'
}
if (!error) {
item.content = metadataContent
item.hash = contract.metadataHash
}
uploaded.push({
content: contract.metadata,
hash: contract.metadataHash,
filename: 'metadata.json',
output: result
})
})
return { uploaded, item }
}
const ipfsVerifiedPublish = async (content, expectedHash, cb) => {
try {
const results = await severalGatewaysPush(content)
if (expectedHash && results !== expectedHash) {
cb(null, { message: 'hash mismatch between solidity bytecode and uploaded content.', url: 'dweb:/ipfs/' + results, hash: results })
} else {
cb(null, { message: 'ok', url: 'dweb:/ipfs/' + results, hash: results })
}
} catch (error) {
cb(error)
}
}
const severalGatewaysPush = (content) => {
const invert = p => new Promise((resolve, reject) => p.then(reject).catch(resolve)) // Invert res and rej
const promises = ipfsNodes.map((node) => invert(node.add(content)))
return invert(Promise.all(promises))
}

@ -0,0 +1,6 @@
export interface RemixUiPublishToStorageProps {
storage: string,
fileProvider: any,
fileManager: any,
contract: any
}

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,13 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

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

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,7 @@
# remix-ui-solidity-compiler
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test remix-ui-solidity-compiler` to execute the unit tests via [Jest](https://jestjs.io).

@ -0,0 +1 @@
export * from './lib/remix-ui-solidity-compiler';

@ -0,0 +1,90 @@
var Compiler = require('@remix-project/remix-solidity').Compiler
export default class CompileTab {
public compiler
public optimize
public runs: number
public evmVersion: string
public compilerImport
constructor (public queryParams, public fileManager, public editor, public config, public fileProvider, public contentImport, public miscApi) {
// this.event = new EventEmitter()
this.compiler = new Compiler((url, cb) => this.compilerImport.resolveAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
}
init () {
this.optimize = this.queryParams.get().optimize
this.optimize = this.optimize === 'true'
this.queryParams.update({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
this.runs = this.queryParams.get().runs
this.runs = this.runs || 200
this.queryParams.update({ runs: this.runs })
this.compiler.set('runs', this.runs)
this.evmVersion = this.queryParams.get().evmVersion
if (this.evmVersion === 'undefined' || this.evmVersion === 'null' || !this.evmVersion) {
this.evmVersion = null
}
this.queryParams.update({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
setOptimize (newOptimizeValue) {
this.optimize = newOptimizeValue
this.queryParams.update({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
}
setRuns (runs) {
this.runs = runs
this.queryParams.update({ runs: this.runs })
this.compiler.set('runs', this.runs)
}
setEvmVersion (newEvmVersion) {
this.evmVersion = newEvmVersion
this.queryParams.update({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
/**
* Set the compiler to using Solidity or Yul (default to Solidity)
* @params lang {'Solidity' | 'Yul'} ...
*/
setLanguage (lang) {
this.compiler.set('language', lang)
}
/**
* Compile a specific file of the file manager
* @param {string} target the path to the file to compile
*/
compileFile (target) {
if (!target) throw new Error('No target provided for compiliation')
const provider = this.fileManager.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)
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)
})
})
}
runCompiler () {
try {
this.fileManager.saveCurrentFile()
this.miscApi.clearAnnotations()
var currentFile = this.config.get('currentFile')
return this.compileFile(currentFile)
} catch (err) {
console.error(err)
}
}
}

@ -0,0 +1,521 @@
import React, { useEffect, useState, useRef } from 'react' // eslint-disable-line
import semver from 'semver'
import { CompilerContainerProps } from './types'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '../../../../../apps/remix-ide/src/app/compiler/compiler-utils' // eslint-disable-line
import './css/style.css'
export const CompilerContainer = (props: CompilerContainerProps) => {
const { editor, config, queryParams, compileTabLogic, tooltip, modal } = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,
optimise: false,
compileTimeout: null,
timeout: 300,
allversions: [],
selectedVersion: null,
defaultVersion: 'soljson-v0.7.4+commit.3f05b770.js', // this default version is defined: in makeMockCompiler (for browser test)
selectedLanguage: '',
runs: '',
compiledFileName: '',
includeNightlies: false,
language: '',
evmVersion: ''
})
const compileIcon = useRef(null)
const warningIcon = useRef(null)
const promptMessageInput = useRef(null)
useEffect(() => {
fetchAllVersion((allversions, selectedVersion, isURL) => {
setState(prevState => {
return { ...prevState, allversions }
})
if (isURL) _updateVersionSelector(selectedVersion)
else {
setState(prevState => {
return { ...prevState, selectedVersion }
})
// if (this._view.versionSelector) this._updateVersionSelector()
}
})
}, [])
useEffect(() => {
if (compileTabLogic && compileTabLogic.compiler) {
compileTabLogic.compiler.event.register('compilerLoaded', compilerLoaded)
setState(prevState => {
return { ...prevState, hideWarnings: config.get('hideWarnings'), autoCompile: config.get('autoCompile'), optimise: config.get('optimise') }
})
}
}, [compileTabLogic])
const compilerLoaded = (version: string) => {
setVersionText(version)
}
const setVersionText = (text) => {
// if (this._view.version) this._view.version.innerText = text
}
// fetching both normal and wasm builds and creating a [version, baseUrl] map
const fetchAllVersion = async (callback) => {
let selectedVersion, allVersionsWasm, isURL
let allVersions = [{ path: 'builtin', longVersion: 'latest local version - 0.7.4' }]
// fetch normal builds
const binRes = await promisedMiniXhr(`${baseURLBin}/list.json`)
// fetch wasm builds
const wasmRes = await promisedMiniXhr(`${baseURLWasm}/list.json`)
if (binRes.event.type === 'error' && wasmRes.event.type === 'error') {
selectedVersion = 'builtin'
return callback(allVersions, selectedVersion)
}
try {
const versions = JSON.parse(binRes.json).builds.slice().reverse()
allVersions = [...allVersions, ...versions]
selectedVersion = state.defaultVersion
if (queryParams.get().version) selectedVersion = queryParams.get().version
// Check if version is a URL and corresponding filename starts with 'soljson'
if (selectedVersion.startsWith('https://')) {
const urlArr = selectedVersion.split('/')
if (urlArr[urlArr.length - 1].startsWith('soljson')) isURL = true
}
if (wasmRes.event.type !== 'error') {
allVersionsWasm = JSON.parse(wasmRes.json).builds.slice().reverse()
}
} catch (e) {
tooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload. Error: ' + e)
}
// replace in allVersions those compiler builds which exist in allVersionsWasm with new once
if (allVersionsWasm && allVersions) {
allVersions.forEach((compiler, index) => {
const wasmIndex = allVersionsWasm.findIndex(wasmCompiler => { return wasmCompiler.longVersion === compiler.longVersion })
if (wasmIndex !== -1) {
allVersions[index] = allVersionsWasm[wasmIndex]
pathToURL[compiler.path] = baseURLWasm
} else {
pathToURL[compiler.path] = baseURLBin
}
})
}
callback(allVersions, selectedVersion, isURL)
}
/**
* Update the compilation button with the name of the current file
*/
const currentFile = (name = '') => {
if (name && name !== '') {
_setCompilerVersionFromPragma(name)
}
const compiledFileName = name.split('/').pop()
setState(prevState => {
return { ...prevState, compiledFileName }
})
}
// Load solc compiler version according to pragma in contract file
const _setCompilerVersionFromPragma = (filename: string) => {
if (!state.allversions) return
compileTabLogic.fileManager.readFile(filename).then(data => {
const pragmaArr = data.match(/(pragma solidity (.+?);)/g)
if (pragmaArr && pragmaArr.length === 1) {
const pragmaStr = pragmaArr[0].replace('pragma solidity', '').trim()
const pragma = pragmaStr.substring(0, pragmaStr.length - 1)
const releasedVersions = state.allversions.filter(obj => !obj.prerelease).map(obj => obj.version)
const allVersions = state.allversions.map(obj => _retrieveVersion(obj.version))
const currentCompilerName = _retrieveVersion(/** this._view.versionSelector.selectedOptions[0].label **/)
// contains only numbers part, for example '0.4.22'
const pureVersion = _retrieveVersion()
// is nightly build newer than the last release
const isNewestNightly = currentCompilerName.includes('nightly') && semver.gt(pureVersion, releasedVersions[0])
// checking if the selected version is in the pragma range
const isInRange = semver.satisfies(pureVersion, pragma)
// checking if the selected version is from official compilers list(excluding custom versions) and in range or greater
const isOfficial = allVersions.includes(currentCompilerName)
if (isOfficial && (!isInRange && !isNewestNightly)) {
const compilerToLoad = semver.maxSatisfying(releasedVersions, pragma)
const compilerPath = state.allversions.filter(obj => !obj.prerelease && obj.version === compilerToLoad)[0].path
if (state.selectedVersion !== compilerPath) {
state.selectedVersion = compilerPath
_updateVersionSelector()
}
}
}
})
}
const isSolFileSelected = (currentFile = '') => {
if (!currentFile) currentFile = config.get('currentFile')
if (!currentFile) return false
const extention = currentFile.substr(currentFile.length - 3, currentFile.length)
return extention.toLowerCase() === 'sol' || extention.toLowerCase() === 'yul'
}
const deactivate = () => {
// deactivate editor listeners
editor.event.unregister('contentChanged')
editor.event.unregister('sessionSwitched')
}
const activate = () => {
const currentFileName = config.get('currentFile')
currentFile(currentFileName)
listenToEvents()
}
const listenToEvents = () => {
editor.event.register('sessionSwitched', () => {
if (!compileIcon.current) return
scheduleCompilation()
})
compileTabLogic.event.on('startingCompilation', () => {
if (!compileIcon.current) return
compileIcon.current.setAttribute('title', 'compiling...')
compileIcon.current.classList.remove('remixui_bouncingIcon')
compileIcon.current.classList.add('remixui_spinningIcon')
})
compileTabLogic.compiler.event.register('compilationDuration', (speed) => {
if (!warningIcon.current) return
if (speed > 1000) {
const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.`
warningIcon.current.setAttribute('title', msg)
warningIcon.current.style.visibility = 'visible'
} else {
warningIcon.current.style.visibility = 'hidden'
}
})
editor.event.register('contentChanged', () => {
if (!compileIcon.current) return
scheduleCompilation()
compileIcon.current.classList.add('remixui_bouncingIcon') // @TODO: compileView tab
})
compileTabLogic.compiler.event.register('loadingCompiler', () => {
if (!compileIcon.current) return
// _disableCompileBtn(true)
compileIcon.current.setAttribute('title', 'compiler is loading, please wait a few moments.')
compileIcon.current.classList.add('remixui_spinningIcon')
warningIcon.current.style.visibility = 'hidden'
_updateLanguageSelector()
})
compileTabLogic.compiler.event.register('compilerLoaded', () => {
if (!compileIcon.current) return
// _disableCompileBtn(false)
compileIcon.current.setAttribute('title', '')
compileIcon.current.classList.remove('remixui_spinningIcon')
if (state.autoCompile) compileIfAutoCompileOn()
})
compileTabLogic.compiler.event.register('compilationFinished', (success, data, source) => {
if (!compileIcon.current) return
compileIcon.current.setAttribute('title', 'idle')
compileIcon.current.classList.remove('remixui_spinningIcon')
compileIcon.current.classList.remove('remixui_bouncingIcon')
})
}
const scheduleCompilation = () => {
if (!state.autoCompile) return
if (state.compileTimeout) window.clearTimeout(state.compileTimeout)
const compileTimeout = window.setTimeout(() => compileIfAutoCompileOn(), state.timeout)
setState(prevState => {
return { ...prevState, compileTimeout }
})
}
const compileIfAutoCompileOn = () => {
if (config.get('autoCompile')) {
compile()
}
}
const compile = () => {
const currentFile = config.get('currentFile')
if (!isSolFileSelected()) return
_setCompilerVersionFromPragma(currentFile)
compileTabLogic.runCompiler()
}
const _retrieveVersion = (version?) => {
// if (!version) version = this._view.versionSelector.value
return semver.coerce(version) ? semver.coerce(version).version : ''
}
const _updateVersionSelector = (customUrl = '') => {
// update selectedversion of previous one got filtered out
let selectedVersion = state.selectedVersion
if (!selectedVersion || !_shouldBeAdded(selectedVersion)) {
selectedVersion = state.defaultVersion
setState(prevState => {
return { ...prevState, selectedVersion }
})
}
queryParams.update({ version: selectedVersion })
let url
if (customUrl !== '') {
selectedVersion = customUrl
setState(prevState => {
return { ...prevState, selectedVersion }
})
// this._view.versionSelector.appendChild(yo`<option value="${customUrl}" selected>custom</option>`)
url = customUrl
queryParams.update({ version: selectedVersion })
} else if (selectedVersion === 'builtin') {
let location: string | Location = window.document.location
let path = location.pathname
if (!path.startsWith('/')) path = '/' + path
location = `${location.protocol}//${location.host}${path}assets/js`
if (location.endsWith('index.html')) location = location.substring(0, location.length - 10)
if (!location.endsWith('/')) location += '/'
url = location + 'soljson.js'
} else {
console.log('selectedVersion: ', selectedVersion)
if (selectedVersion.indexOf('soljson') !== 0 || helper.checkSpecialChars(selectedVersion)) {
return console.log('loading ' + selectedVersion + ' not allowed')
}
url = `${urlFromVersion(selectedVersion)}`
}
// Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case.
if (selectedVersion !== 'builtin' && canUseWorker(selectedVersion)) {
compileTabLogic.compiler.loadVersion(true, url)
// setVersionText('(loading using worker)')
} else {
compileTabLogic.compiler.loadVersion(false, url)
// setVersionText('(loading)')
}
}
const _shouldBeAdded = (version) => {
return !version.includes('nightly') ||
(version.includes('nightly') && state.includeNightlies)
}
// const setVersionText = (text) => {
// if (this._view.version) this._view.version.innerText = text
// }
const promtCompiler = () => {
modal('Add a custom compiler', promptMessage('URL'), 'OK', addCustomCompiler, 'Cancel', () => {})
// modalDialogCustom.prompt(
// 'Add a custom compiler',
// 'URL',
// '',
// (url) => this.addCustomCompiler(url)
// )
}
const promptMessage = (message) => {
return (
<>
<span>{ message }</span>
<input type="text" data-id="modalDialogCustomPromptCompiler" className="form-control" ref={promptMessageInput} />
</>
)
}
const addCustomCompiler = () => {
const url = promptMessageInput.current.value
setState(prevState => {
return { ...prevState, selectedVersion: url }
})
_updateVersionSelector(url)
}
const handleLoadVersion = (value) => {
setState(prevState => {
return { ...prevState, selectedVersion: value }
})
_updateVersionSelector()
_updateLanguageSelector()
}
const _updateLanguageSelector = () => {
// This is the first version when Yul is available
if (!semver.valid(_retrieveVersion()) || semver.lt(_retrieveVersion(), 'v0.5.7+commit.6da8b019.js')) {
// this._view.languageSelector.setAttribute('disabled', '')
// this._view.languageSelector.value = 'Solidity'
// this.compileTabLogic.setLanguage('Solidity')
} else {
// this._view.languageSelector.removeAttribute('disabled')
}
}
const handleAutoCompile = (e) => {
const checked = e.target.checked
config.set('autoCompile', checked)
setState(prevState => {
return { ...prevState, autoCompile: checked }
})
}
const handleOptimizeChange = (e) => {
const checked = !!e.target.checked
config.set('optimise', checked)
compileTabLogic.setOptimize(checked)
if (compileTabLogic.optimize) {
compileTabLogic.setRuns(parseInt(state.runs))
} else {
compileTabLogic.setRuns(200)
}
compileIfAutoCompileOn()
setState(prevState => {
return { ...prevState, optimise: checked }
})
}
const onChangeRuns = (e) => {
const runs = e.target.value
compileTabLogic.setRuns(parseInt(runs))
compileIfAutoCompileOn()
setState(prevState => {
return { ...prevState, runs }
})
}
const handleHideWarningsChange = (e) => {
const checked = e.target.checked
config.set('hideWarnings', checked)
compileIfAutoCompileOn()
setState(prevState => {
return { ...prevState, hideWarnings: checked }
})
}
const handleNightliesChange = () => {
setState(prevState => {
return { ...prevState, includeNightlies: !prevState.includeNightlies }
})
}
const handleLanguageChange = (value) => {
compileTabLogic.setLanguage(value)
compileIfAutoCompileOn()
setState(prevState => {
return { ...prevState, language: value }
})
}
const handleEvmVersionChange = (value) => {
let v = value
if (v === 'default') {
v = null
}
compileTabLogic.setEvmVersion(v)
compileIfAutoCompileOn()
setState(prevState => {
return { ...prevState, evmVersion: value }
})
}
return (
<section>
<article>
<header className='remixui_compilerSection border-bottom'>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="versionSelector">
Compiler
<button className="far fa-plus-square border-0 p-0 mx-2 btn-sm" onClick={promtCompiler} title="Add a custom compiler with URL"></button>
</label>
<select onChange={(e) => handleLoadVersion(e.target.value) } className="custom-select" id="versionSelector" disabled={state.allversions.length <= 0}>
{ state.allversions.length <= 0 && <option disabled selected>{ state.defaultVersion }</option> }
{ state.allversions.length <= 0 && <option disabled>builtin</option> }
{ state.allversions.map((build, i) => {
return _shouldBeAdded(build.longVersion)
? <option key={i} value={build.path} selected={build.path === state.selectedVersion}>{build.longVersion}</option>
: null
})
}
</select>
</div>
<div className="mb-2 remixui_nightlyBuilds custom-control custom-checkbox">
<input className="mr-2 custom-control-input" id="nightlies" type="checkbox" onChange={handleNightliesChange} />
<label htmlFor="nightlies" className="form-check-label custom-control-label">Include nightly builds</label>
</div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="compilierLanguageSelector">Language</label>
<select onChange={(e) => handleLanguageChange(e.target.value)} className="custom-select" id="compilierLanguageSelector" title="Available since v0.5.7">
<option>Solidity</option>
<option>Yul</option>
</select>
</div>
<div className="mb-2">
<label className="remixui_compilerLabel form-check-label" htmlFor="evmVersionSelector">EVM Version</label>
<select onChange={(e) => handleEvmVersionChange(e.target.value)} className="custom-select" id="evmVersionSelector">
<option value="default">compiler default</option>
<option value="muirGlacier">muirGlacier</option>
<option value="istanbul">istanbul</option>
<option value="petersburg">petersburg</option>
<option value="constantinople">constantinople</option>
<option value="byzantium">byzantium</option>
<option value="spuriousDragon">spuriousDragon</option>
<option value="tangerineWhistle">tangerineWhistle</option>
<option value="homestead">homestead</option>
</select>
</div>
<div className="mt-3">
<p className="mt-2 remixui_compilerLabel">Compiler Configuration</p>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={handleAutoCompile} data-id="compilerContainerAutoCompile" id="autoCompile" type="checkbox" title="Auto compile" checked={state.autoCompile} />
<label className="form-check-label custom-control-label" htmlFor="autoCompile">Auto compile</label>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={handleOptimizeChange} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimise} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
className="custom-select ml-2 remixui_runs"
id="runs"
placeholder="200"
value="200"
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={onChangeRuns}
disabled={!state.optimise}
/>
</div>
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={handleHideWarningsChange} id="hideWarningsBox" type="checkbox" title="Hide warnings" checked={state.hideWarnings} />
<label className="form-check-label custom-control-label" htmlFor="hideWarningsBox">Hide warnings</label>
</div>
</div>
<button id="compileBtn" data-id="compilerContainerCompileBtn" className="btn btn-primary btn-block remixui_disabled mt-3" title="Compile" onClick={compile} disabled={!state.compiledFileName || (state.compiledFileName && !isSolFileSelected(state.compiledFileName))}>
<span>
<i ref={warningIcon} title="Compilation Slow" style={{ visibility: 'hidden' }} className="remixui_warnCompilationSlow fas fa-exclamation-triangle" aria-hidden="true"></i>
<i ref={compileIcon} className="fas fa-sync remixui_icon" aria-hidden="true"></i>
Compile { state.compiledFileName || '<no file selected>' }
</span>
</button>
</header>
</article>
</section>
)
}
export default CompilerContainer

@ -0,0 +1,159 @@
import React, { useState, useEffect } from 'react' // eslint-disable-line
import { ContractSelectionProps } from './types'
import { PublishToStorage } from '@remix-ui/publish-to-storage'
import './css/style.css'
export const ContractSelection = (props: ContractSelectionProps) => {
const { contractMap, fileManager, fileProvider } = props
const [state, setState] = useState({
contractList: null,
selectedContract: ''
})
useEffect(() => {
const contractList = contractMap ? Object.keys(contractMap).map((key) => ({
name: key,
file: getFileName(contractMap[key].file)
})) : []
setState(prevState => {
return { ...prevState, contractList }
})
}, [])
// Return the file name of a path: ex "browser/ballot.sol" -> "ballot.sol"
const getFileName = (path) => {
const part = path.split('/')
return part[part.length - 1]
}
const selectContract = (contractName: string) => {
setState(prevState => {
return { ...prevState, selectedContract: contractName }
})
}
const handlePublishToStorage = (type) => {
}
const copyABI = () => {
copyContractProperty('abi')
}
const copyContractProperty = (property) => {
let content = getContractProperty(property)
// if (!content) {
// addTooltip('No content available for ' + property)
// return
// }
// try {
// if (typeof content !== 'string') {
// content = JSON.stringify(content, null, '\t')
// }
// } catch (e) {}
// copy(content)
// addTooltip('Copied value to clipboard')
}
const getContractProperty = (property) => {
// if (!this.selectedContract) throw new Error('No contract compiled yet')
// const contractProperties = this.data.contractsDetails[this.selectedContract]
// return contractProperties[property] || null
}
const details = () => {
const help = {
Assembly: 'Assembly opcodes describing the contract including corresponding solidity source code',
Opcodes: 'Assembly opcodes describing the contract',
'Runtime Bytecode': 'Bytecode storing the state and being executed during normal contract call',
bytecode: 'Bytecode being executed during contract creation',
functionHashes: 'List of declared function and their corresponding hash',
gasEstimates: 'Gas estimation for each function call',
metadata: 'Contains all informations related to the compilation',
metadataHash: 'Hash representing all metadata information',
abi: 'ABI: describing all the functions (input/output params, scope, ...)',
name: 'Name of the compiled contract',
swarmLocation: 'Swarm url where all metadata information can be found (contract needs to be published first)',
web3Deploy: 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
}
if (!this.selectedContract) throw new Error('No contract compiled yet')
const contractProperties = this.data.contractsDetails[this.selectedContract]
const log = yo`<div class="${css.detailsJSON}"></div>`
Object.keys(contractProperties).map(propertyName => {
const copyDetails = yo`<span class="${css.copyDetails}">${copyToClipboard(() => contractProperties[propertyName])}</span>`
const questionMark = yo`<span class="${css.questionMark}"><i title="${help[propertyName]}" class="fas fa-question-circle" aria-hidden="true"></i></span>`
log.appendChild(yo`<div class=${css.log}>
<div class="${css.key}">${propertyName} ${copyDetails} ${questionMark}</div>
${this.insertValue(contractProperties, propertyName)}
</div>`)
})
modalDialog(this.selectedContract, log, { label: '' }, { label: 'Close' })
}
const copyBytecode = () => {
copyContractProperty('bytecode')
}
return (
// define swarm logo
<>
{ state.contractList.length ?
<section className="remixui_compilerSection pt-3">
{/* Select Compiler Version */}
<div className="mb-3">
<label className="remixui_compilerLabel form-check-label" htmlFor="compiledContracts">Contract</label>
<select onChange={(e) => selectContract(e.target.value)} data-id="compiledContracts" id="compiledContracts" className="custom-select">
{state.contractList.map(({ name, file }) => <option value={name}>{name} ({file})</option>)}
</select>
</div>
<article className="mt-2 pb-0">
<button id="publishOnSwarm" className="btn btn-secondary btn-block" title="Publish on Swarm" onClick={() => { handlePublishToStorage('swarm')}}>
<span>Publish on Swarm</span>
<img id="swarmLogo" className="remixui_storageLogo ml-2" src="assets/img/swarm.webp" />
</button>
<button id="publishOnIpfs" className="btn btn-secondary btn-block" title="Publish on Ipfs" onClick={() => { handlePublishToStorage('ipfs') }}>
<span>Publish on Ipfs</span>
<img id="ipfsLogo" className="remixui_storageLogo} ml-2" src="assets/img/ipfs.webp" />
</button>
<button data-id="compilation-details" className="btn btn-secondary btn-block" title="Display Contract Details" onClick={() => { details() }}>
Compilation Details
</button>
{/* Copy to Clipboard */}
<div className="remixui_contractHelperButtons">
<div className="input-group">
<div className="btn-group" role="group" aria-label="Copy to Clipboard">
<button className="btn copyButton" title="Copy ABI to clipboard" onClick={() => { copyABI() }}>
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>ABI</span>
</button>
<button className="btn remixui_copyButton" title="Copy Bytecode to clipboard" onClick={() => { copyBytecode() }}>
<i className="remixui_copyIcon far fa-copy" aria-hidden="true"></i>
<span>Bytecode</span>
</button>
</div>
</div>
</div>
</article>
</section> : <section className="remixui_container clearfix"><article className="px-2 mt-2 pb-0 d-flex">
<span className="mt-2 mx-3 w-100 alert alert-warning" role="alert">No Contract Compiled Yet</span>
</article></section>
}
<PublishToStorage />
</>
)
// if (contractList.length) {
// this.selectedContract = selectEl.value
// } else {
// delete this.selectedContract
// }
// return result
// return ()
}
export default ContractSelection

@ -0,0 +1,234 @@
.remixui_title {
font-size: 1.1em;
font-weight: bold;
margin-bottom: 1em;
}
.remixui_panicError {
color: red;
font-size: 20px;
}
.remixui_crow {
display: flex;
overflow: auto;
clear: both;
padding: .2em;
}
.remixui_checkboxText {
font-weight: normal;
}
.remixui_crow label {
cursor:pointer;
}
.remixui_crowNoFlex {
overflow: auto;
clear: both;
}
.remixui_info {
padding: 10px;
word-break: break-word;
}
.remixui_contract {
display: block;
margin: 3% 0;
}
.remixui_nightlyBuilds {
display: flex;
flex-direction: row;
align-items: center;
}
.remixui_autocompileContainer {
display: flex;
align-items: center;
}
.remixui_runs {
width: 40%;
}
.remixui_hideWarningsContainer {
display: flex;
align-items: center;
}
.remixui_autocompile {}
.remixui_autocompileTitle {
font-weight: bold;
margin: 1% 0;
}
.remixui_autocompileText {
margin: 1% 0;
font-size: 12px;
overflow: hidden;
word-break: normal;
line-height: initial;
}
.remixui_warnCompilationSlow {
margin-left: 1%;
}
.remixui_compilerConfig {
display: flex;
align-items: center;
}
.remixui_compilerConfig label {
margin: 0;
}
.remixui_compilerSection {
padding: 12px 24px 16px;
}
.remixui_compilerLabel {
margin-bottom: 2px;
font-size: 11px;
line-height: 12px;
text-transform: uppercase;
}
.remixui_copyButton {
padding: 6px;
font-weight: bold;
font-size: 11px;
line-height: 15px;
}
.remixui_name {
display: flex;
}
.remixui_size {
display: flex;
}
.remixui_checkboxes {
display: flex;
width: 100%;
justify-content: space-between;
flex-wrap: wrap;
}
.remixui_compileButton {
width: 100%;
margin: 15px 0 10px 0;
font-size: 12px;
}
.remixui_container {
margin: 0;
margin-bottom: 2%;
}
.remixui_optimizeContainer {
display: flex;
}
.remixui_noContractAlert {
display: flex;
justify-content: center;
align-items: center;
}
.remixui_contractHelperButtons {
margin-top: 6px;
display: flex;
align-items: center;
justify-content: space-between;
float: right;
}
.remixui_copyToClipboard {
font-size: 1rem;
}
.remixui_copyIcon {
margin-right: 5px;
}
.remixui_log {
display: flex;
flex-direction: column;
margin-bottom: 5%;
overflow: visible;
}
.remixui_key {
margin-right: 5px;
text-transform: uppercase;
width: 100%;
}
.remixui_value {
display: flex;
width: 100%;
margin-top: 1.5%;
}
.remixui_questionMark {
margin-left: 2%;
cursor: pointer;
}
.remixui_questionMark:hover {
}
.remixui_detailsJSON {
padding: 8px 0;
border: none;
}
.remixui_icon {
margin-right: 0.3em;
}
.remixui_errorBlobs {
padding-left: 5px;
padding-right: 5px;
word-break: break-word;
}
.remixui_storageLogo {
width: 20px;
height: 20px;
}
.remixui_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); }
}
.remixui_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; }
}

@ -0,0 +1,97 @@
import React, { useState, useEffect } from 'react' // eslint-disable-line
import { SolidityCompilerProps } from './types'
import { CompilerContainer } from './compiler-container' // eslint-disable-line
import CompileTabLogic from './compileTabLogic'
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import './css/style.css'
export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { editor, config, fileProvider, fileManager, contentImport, queryParams, plugin } = props
const [state, setState] = useState({
contractsDetails: {},
eventHandlers: {},
loading: false,
compileTabLogic: null,
compiler: null,
toasterMsg: '',
modal: {
hide: true,
title: '',
message: null,
okLabel: '',
okFn: () => {},
cancelLabel: '',
cancelFn: () => {},
handleHide: null
}
})
useEffect(() => {
const miscApi = { clearAnnotations }
const compileTabLogic = new CompileTabLogic(queryParams, fileManager, editor, config, fileProvider, contentImport, miscApi)
const compiler = compileTabLogic.compiler
compileTabLogic.init()
setState(prevState => {
return { ...prevState, compileTabLogic, compiler }
})
}, [])
const toast = (message: string) => {
setState(prevState => {
return { ...prevState, toasterMsg: message }
})
}
const clearAnnotations = () => {
plugin.call('editor', 'clearAnnotations')
}
const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
await setState(prevState => {
return {
...prevState,
modal: {
...prevState.modal,
message,
title,
okLabel,
okFn,
cancelLabel,
cancelFn
}
}
})
}
const handleHideModal = () => {
setState(prevState => {
return { ...prevState, modal: { ...state.modal, hide: true, message: null } }
})
}
// this.onActivationInternal()
return (
<>
<div id="compileTabView">
<CompilerContainer editor={editor} config={config} queryParams={queryParams} compileTabLogic={state.compileTabLogic} tooltip={toast} modal={modal} />
{/* ${this._view.contractSelection} */}
<div className="remixui_errorBlobs p-4" data-id="compiledErrors"></div>
</div>
<Toaster message={state.toasterMsg} />
<ModalDialog
id='workspacesModalDialog'
title={ state.modal.title }
message={ state.modal.message }
hide={ state.modal.hide }
okLabel={ state.modal.okLabel }
cancelLabel={ state.modal.cancelLabel }
handleHide={ handleHideModal }>
{ (typeof state.modal.message !== 'string') && state.modal.message }
</ModalDialog>
</>
)
}
export default SolidityCompiler

@ -0,0 +1,24 @@
export interface SolidityCompilerProps {
editor: any,
config: any,
fileProvider: any,
fileManager: any,
contentImport: any,
plugin: any,
queryParams: any
}
export interface CompilerContainerProps {
editor: any,
config: any,
queryParams: any,
compileTabLogic: any,
tooltip: (message: string) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void
}
export interface ContractSelectionProps {
contractMap: {
file: string
}
}

@ -0,0 +1,16 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,13 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -107,6 +107,12 @@
},
"remix-core-plugin": {
"tags": []
},
"remix-ui-solidity-compiler": {
"tags": []
},
"remix-ui-publish-to-storage": {
"tags": []
}
}
}

@ -42,9 +42,9 @@
"@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"],
"@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"],
"@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"],
"@remix-project/core-plugin": [
"libs/remix-core-plugin/src/index.ts"
]
"@remix-project/core-plugin": ["libs/remix-core-plugin/src/index.ts"],
"@remix-ui/solidity-compiler": ["libs/remix-ui/solidity-compiler/src/index.ts"],
"@remix-project/publish-to-storage": ["libs/remix-ui/publish-to-storage/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]

@ -808,6 +808,44 @@
}
}
},
"remix-ui-solidity-compiler": {
"root": "libs/remix-ui/solidity-compiler",
"sourceRoot": "libs/remix-ui/solidity-compiler/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/solidity-compiler/tsconfig.lib.json"],
"exclude": [
"**/node_modules/**",
"!libs/remix-ui/solidity-compiler/**/*"
]
}
}
}
},
"remix-ui-publish-to-storage": {
"root": "libs/remix-ui/publish-to-storage",
"sourceRoot": "libs/remix-ui/publish-to-storage/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["libs/remix-ui/publish-to-storage/tsconfig.lib.json"],
"exclude": [
"**/node_modules/**",
"!libs/remix-ui/publish-to-storage/**/*"
]
}
}
}
},
"cli": {
"defaultCollection": "@nrwl/react"
},

Loading…
Cancel
Save