Merge branch 'master' into remixd_terminal

pull/1342/head
David Zagi 3 years ago committed by GitHub
commit 70f4cb16f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      apps/remix-ide/ci/publishIpfs
  2. 18
      apps/remix-ide/src/app.js
  3. 46
      apps/remix-ide/src/app/compiler/compiler-abstract.js
  4. 169
      apps/remix-ide/src/app/compiler/compiler-imports.js
  5. 21
      apps/remix-ide/src/app/compiler/compiler-input.js
  6. 148
      apps/remix-ide/src/app/files/compiler-metadata.js
  7. 4
      apps/remix-ide/src/app/files/dgitProvider.js
  8. 28
      apps/remix-ide/src/app/files/fileManager.js
  9. 4
      apps/remix-ide/src/app/files/fileProvider.js
  10. 2
      apps/remix-ide/src/app/tabs/compile-tab.js
  11. 2
      apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js
  12. 2
      apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js
  13. 6
      apps/remix-ide/src/app/tabs/settings-tab.js
  14. 3
      apps/remix-ide/src/app/tabs/test-tab.js
  15. 4
      apps/remix-ide/src/app/ui/landing-page/landing-page.js
  16. 4
      apps/remix-ide/src/lib/cmdInterpreterAPI.js
  17. 2
      apps/remix-ide/src/lib/publishOnIpfs.js
  18. 1
      libs/remix-core-plugin/.eslintrc
  19. 3
      libs/remix-core-plugin/README.md
  20. 12
      libs/remix-core-plugin/package.json
  21. 5
      libs/remix-core-plugin/src/index.ts
  22. 11
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  23. 175
      libs/remix-core-plugin/src/lib/compiler-content-imports.ts
  24. 28
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  25. 145
      libs/remix-core-plugin/src/lib/compiler-metadata.ts
  26. 77
      libs/remix-core-plugin/src/lib/offset-line-to-column-converter.ts
  27. 10
      libs/remix-core-plugin/tsconfig.json
  28. 12
      libs/remix-core-plugin/tsconfig.lib.json
  29. 2
      libs/remix-debug/src/eventManager.ts
  30. 2
      libs/remix-debug/src/solidity-decoder/types/util.ts
  31. 2
      libs/remix-debug/src/trace/traceManager.ts
  32. 2
      libs/remix-lib/src/eventManager.ts
  33. 17
      libs/remix-lib/src/init.ts
  34. 48
      libs/remix-solidity/src/compiler/compiler-abstract.ts
  35. 4
      libs/remix-solidity/src/compiler/compiler-helpers.ts
  36. 0
      libs/remix-solidity/src/compiler/compiler-utils.ts
  37. 3
      libs/remix-solidity/src/index.ts
  38. 2
      libs/remix-solidity/src/lib/eventManager.ts
  39. 6
      libs/remix-url-resolver/src/resolve.ts
  40. 3
      libs/remixd/src/origins.json
  41. 5
      nx.json
  42. 12
      package-lock.json
  43. 4
      package.json
  44. 7
      tsconfig.json
  45. 30
      workspace.json

@ -6,13 +6,13 @@ console.log('current folder', process.cwd())
const folder = process.cwd() + '/temp_publish_docker';
(async () => {
const host = 'ipfs.komputing.org' // ethdev berlin ipfs node
const host = 'ipfs.remixproject.org'
const ipfs = IpfsHttpClient({ host, port: 443, protocol: 'https' })
try {
let result = await ipfs.add(globSource(folder, { recursive: true}), { pin: false })
const hash = result.cid.toString()
console.log('ipfs://' + hash)
console.log('https://ipfsgw.komputing.org/ipfs/' + hash)
console.log('https://ipfs.remixproject.org/ipfs/' + hash)
console.log('https://gateway.ipfs.io/ipfs/' + hash)
} catch (e) {
console.log(e)

@ -16,7 +16,8 @@ import { HiddenPanel } from './app/components/hidden-panel'
import { VerticalIcons } from './app/components/vertical-icons'
import { LandingPage } from './app/ui/landing-page/landing-page'
import { MainPanel } from './app/components/main-panel'
import FetchAndCompile from './app/compiler/compiler-sourceVerifier-fetchAndCompile'
import { OffsetToLineColumnConverter, CompilerMetadata, CompilerArtefacts, FetchAndCompile, CompilerImports } from '@remix-project/core-plugin'
import migrateFileSystem from './migrateFileSystem'
@ -25,7 +26,7 @@ const csjs = require('csjs-inject')
const yo = require('yo-yo')
const remixLib = require('@remix-project/remix-lib')
const registry = require('./global/registry')
const { OffsetToLineColumnConverter } = require('./lib/offsetToLineColumnConverter')
const QueryParams = require('./lib/query-params')
const Storage = remixLib.Storage
const RemixDProvider = require('./app/files/remixDProvider')
@ -38,13 +39,10 @@ const FileProvider = require('./app/files/fileProvider')
const DGitProvider = require('./app/files/dgitProvider')
const WorkspaceFileProvider = require('./app/files/workspaceFileProvider')
const toolTip = require('./app/ui/tooltip')
const CompilerMetadata = require('./app/files/compiler-metadata')
const CompilerImport = require('./app/compiler/compiler-imports')
const Blockchain = require('./blockchain/blockchain.js')
const PluginManagerComponent = require('./app/components/plugin-manager-component')
const CompilersArtefacts = require('./app/compiler/compiler-artefacts')
const CompileTab = require('./app/tabs/compile-tab')
const SettingsTab = require('./app/tabs/settings-tab')
@ -262,14 +260,14 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
const dGitProvider = new DGitProvider()
// ----------------- import content service ------------------------
const contentImport = new CompilerImport(fileManager)
const contentImport = new CompilerImports()
const blockchain = new Blockchain(registry.get('config').api)
// ----------------- compilation metadata generation service ---------
const compilerMetadataGenerator = new CompilerMetadata(blockchain, fileManager, registry.get('config').api)
const compilerMetadataGenerator = new CompilerMetadata()
// ----------------- compilation result service (can keep track of compilation results) ----------------------------
const compilersArtefacts = new CompilersArtefacts() // store all the compilation results (key represent a compiler name)
const compilersArtefacts = new CompilerArtefacts() // store all the compilation results (key represent a compiler name)
registry.put({ api: compilersArtefacts, name: 'compilersartefacts' })
// service which fetch contract artifacts from sourve-verify, put artifacts in remix and compile it
@ -458,11 +456,11 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
console.log('couldn\'t register iframe plugins', e.message)
}
await appManager.activatePlugin(['contentImport', 'theme', 'editor', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await appManager.activatePlugin(['theme', 'editor', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs'])
await appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await appManager.activatePlugin(['home'])
await appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'filePanel', 'settings', 'contextualListener', 'terminal', 'fetchAndCompile'])
await appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'filePanel', 'settings', 'contextualListener', 'terminal', 'fetchAndCompile', 'contentImport'])
const queryParams = new QueryParams()
const params = queryParams.get()

@ -1,46 +0,0 @@
'use strict'
var remixLib = require('@remix-project/remix-lib')
var txHelper = remixLib.execution.txHelper
module.exports = class CompilerAbstract {
constructor (languageversion, data, source) {
this.languageversion = languageversion
this.data = data
this.source = source // source code
}
getContracts () {
return this.data.contracts
}
getContract (name) {
return txHelper.getContract(name, this.data.contracts)
}
visitContracts (calllback) {
return txHelper.visitContracts(this.data.contracts, calllback)
}
getData () {
return this.data
}
getAsts () {
return this.data.sources // ast
}
getSourceName (fileIndex) {
if (this.data && this.data.sources) {
return Object.keys(this.data.sources)[fileIndex]
} else if (Object.keys(this.source.sources).length === 1) {
// if we don't have ast, we return the only one filename present.
const sourcesArray = Object.keys(this.source.sources)
return sourcesArray[0]
}
return null
}
getSourceCode () {
return this.source
}
}

@ -1,169 +0,0 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json'
import { RemixURLResolver } from '@remix-project/remix-url-resolver'
const remixTests = require('@remix-project/remix-tests')
const globalRegistry = require('../../global/registry')
const addTooltip = require('../ui/tooltip')
const async = require('async')
const profile = {
name: 'contentImport',
displayName: 'content import',
version: packageJson.version,
methods: ['resolve', 'resolveAndSave', 'isExternalUrl']
}
module.exports = class CompilerImports extends Plugin {
constructor (fileManager) {
super(profile)
this.fileManager = fileManager
// const token = await this.call('settings', 'getGithubAccessToken')
const token = globalRegistry.get('config').api.get('settings/gist-access-token') // TODO replace with the plugin call above https://github.com/ethereum/remix-ide/issues/2288
const protocol = window.location.protocol
this.urlResolver = new RemixURLResolver(token, protocol)
this.previouslyHandled = {} // cache import so we don't make the request at each compilation.
}
isRelativeImport (url) {
return /^([^/]+)/.exec(url)
}
isExternalUrl (url) {
const handlers = this.urlResolver.getHandlers()
return handlers.some(handler => handler.match(url))
}
/**
* resolve the content of @arg url. This only resolves external URLs.
*
* @param {String} url - external URL of the content. can be basically anything like raw HTTP, ipfs URL, github address etc...
* @returns {Promise} - { content, cleanUrl, type, url }
*/
resolve (url) {
return new Promise((resolve, reject) => {
this.import(url, null, (error, content, cleanUrl, type, url) => {
if (error) return reject(error)
resolve({ content, cleanUrl, type, url })
})
})
}
async import (url, force, loadingCb, cb) {
if (typeof force !== 'boolean') {
const temp = loadingCb
loadingCb = force
cb = temp
force = false
}
if (!loadingCb) loadingCb = () => {}
if (!cb) cb = () => {}
var self = this
if (force) delete this.previouslyHandled[url]
var imported = this.previouslyHandled[url]
if (imported) {
return cb(null, imported.content, imported.cleanUrl, imported.type, url)
}
let resolved
try {
resolved = await this.urlResolver.resolve(url)
const { content, cleanUrl, type } = resolved
self.previouslyHandled[url] = {
content,
cleanUrl,
type
}
cb(null, content, cleanUrl, type, url)
} catch (e) {
return cb(new Error('not found ' + url))
}
}
importExternal (url, targetPath, cb) {
this.import(url,
// TODO: move to an event that is generated, the UI shouldn't be here
(loadingMsg) => { addTooltip(loadingMsg) },
(error, content, cleanUrl, type, url) => {
if (error) return cb(error)
if (this.fileManager) {
const provider = this.fileManager.currentFileProvider()
const path = targetPath || type + '/' + cleanUrl
if (provider) provider.addExternal('.deps/' + path, content, url)
}
cb(null, content)
})
}
/**
* import the content of @arg url.
* first look in the browser localstorage (browser explorer) or locahost explorer. if the url start with `browser/*` or `localhost/*`
* then check if the @arg url is located in the localhost, in the node_modules or installed_contracts folder
* then check if the @arg url match any external url
*
* @param {String} url - URL of the content. can be basically anything like file located in the browser explorer, in the localhost explorer, raw HTTP, github address etc...
* @param {String} targetPath - (optional) internal path where the content should be saved to
* @returns {Promise} - string content
*/
resolveAndSave (url, targetPath) {
return new Promise((resolve, reject) => {
if (url.indexOf('remix_tests.sol') !== -1) resolve(remixTests.assertLibCode)
if (!this.fileManager) {
// fallback to just resolving the file, it won't be saved in file manager
return this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}
var provider = this.fileManager.fileProviderOf(url)
if (provider) {
if (provider.type === 'localhost' && !provider.isConnected()) {
return reject(new Error(`file provider ${provider.type} not available while trying to resolve ${url}`))
}
provider.exists(url).then(exist => {
/*
if the path is absolute and the file does not exist, we can stop here
Doesn't make sense to try to resolve "localhost/node_modules/localhost/node_modules/<path>" and we'll end in an infinite loop.
*/
if (!exist && url.startsWith('browser/')) return reject(new Error(`not found ${url}`))
if (!exist && url.startsWith('localhost/')) return reject(new Error(`not found ${url}`))
if (exist) {
return provider.get(url, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}
// try to resolve localhost modules (aka truffle imports) - e.g from the node_modules folder
const localhostProvider = this.fileManager.getProvider('localhost')
if (localhostProvider.isConnected()) {
var splitted = /([^/]+)\/(.*)$/g.exec(url)
return async.tryEach([
(cb) => { this.resolveAndSave('localhost/installed_contracts/' + url).then((result) => cb(null, result)).catch((error) => cb(error.message)) },
(cb) => { if (!splitted) { cb('URL not parseable: ' + url) } else { this.resolveAndSave('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2]).then((result) => cb(null, result)).catch((error) => cb(error.message)) } },
(cb) => { this.resolveAndSave('localhost/node_modules/' + url).then((result) => cb(null, result)).catch((error) => cb(error.message)) },
(cb) => { if (!splitted) { cb('URL not parseable: ' + url) } else { this.resolveAndSave('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2]).then((result) => cb(null, result)).catch((error) => cb(error.message)) } }],
(error, result) => {
if (error) {
return this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}
resolve(result)
})
}
this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}).catch(error => {
return reject(error)
})
}
})
}
}

@ -1,21 +0,0 @@
'use strict'
module.exports = (sources, opts) => {
return JSON.stringify({
language: 'Solidity',
sources: sources,
settings: {
optimizer: {
enabled: opts.optimize === true || opts.optimize === 1,
runs: 200
},
libraries: opts.libraries,
outputSelection: {
'*': {
'': ['ast'],
'*': ['abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates']
}
}
}
})
}

@ -1,148 +0,0 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json'
import { joinPath } from '../../lib/helper'
var CompilerAbstract = require('../compiler/compiler-abstract')
const profile = {
name: 'compilerMetadata',
methods: ['deployMetadataOf'],
events: [],
version: packageJson.version
}
class CompilerMetadata extends Plugin {
constructor (blockchain, fileManager, config) {
super(profile)
this.blockchain = blockchain
this.fileManager = fileManager
this.config = config
this.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
this.innerPath = 'artifacts'
}
_JSONFileName (path, contractName) {
return joinPath(path, this.innerPath, contractName + '.json')
}
_MetadataFileName (path, contractName) {
return joinPath(path, this.innerPath, contractName + '_metadata.json')
}
onActivation () {
var self = this
this.on('solidity', 'compilationFinished', (file, source, languageVersion, data) => {
if (!self.config.get('settings/generate-contract-metadata')) return
const compiler = new CompilerAbstract(languageVersion, data, source)
var provider = self.fileManager.fileProviderOf(source.target)
var path = self.fileManager.extractPathOf(source.target)
if (provider) {
compiler.visitContracts((contract) => {
if (contract.file !== source.target) return
var fileName = self._JSONFileName(path, contract.name)
var metadataFileName = self._MetadataFileName(path, contract.name)
provider.get(fileName, (error, content) => {
if (!error) {
content = content || '{}'
var metadata
try {
metadata = JSON.parse(content)
} catch (e) {
console.log(e)
}
var deploy = metadata.deploy || {}
self.networks.forEach((network) => {
deploy[network] = self._syncContext(contract, deploy[network] || {})
})
let parsedMetadata
try {
parsedMetadata = JSON.parse(contract.object.metadata)
} catch (e) {
console.log(e)
}
if (parsedMetadata) provider.set(metadataFileName, JSON.stringify(parsedMetadata, null, '\t'))
var data = {
deploy,
data: {
bytecode: contract.object.evm.bytecode,
deployedBytecode: contract.object.evm.deployedBytecode,
gasEstimates: contract.object.evm.gasEstimates,
methodIdentifiers: contract.object.evm.methodIdentifiers
},
abi: contract.object.abi
}
provider.set(fileName, JSON.stringify(data, null, '\t'))
}
})
})
}
})
}
_syncContext (contract, metadata) {
var linkReferences = metadata.linkReferences
var autoDeployLib = metadata.autoDeployLib
if (!linkReferences) linkReferences = {}
if (autoDeployLib === undefined) autoDeployLib = true
for (var libFile in contract.object.evm.bytecode.linkReferences) {
if (!linkReferences[libFile]) linkReferences[libFile] = {}
for (var lib in contract.object.evm.bytecode.linkReferences[libFile]) {
if (!linkReferences[libFile][lib]) {
linkReferences[libFile][lib] = '<address>'
}
}
}
metadata.linkReferences = linkReferences
metadata.autoDeployLib = autoDeployLib
return metadata
}
// TODO: is only called by dropdownLogic and can be moved there
deployMetadataOf (contractName, fileLocation) {
return new Promise((resolve, reject) => {
var provider
let path
if (fileLocation) {
provider = this.fileManager.fileProviderOf(fileLocation)
path = fileLocation.split('/')
path.pop()
path = path.join('/')
} else {
provider = this.fileManager.currentFileProvider()
path = this.fileManager.currentPath()
}
if (provider) {
this.blockchain.detectNetwork((err, { id, name } = {}) => {
if (err) {
console.log(err)
reject(err)
} else {
var fileName = this._JSONFileName(path, contractName)
provider.get(fileName, (error, content) => {
if (error) return reject(error)
if (!content) return resolve()
try {
var metadata = JSON.parse(content)
metadata = metadata.deploy || {}
return resolve(metadata[name + ':' + id] || metadata[name] || metadata[id] || metadata[name.toLowerCase() + ':' + id] || metadata[name.toLowerCase()])
} catch (e) {
reject(e.message)
}
})
}
})
} else {
reject(new Error(`Please select the folder in the file explorer where the metadata of ${contractName} can be found`))
}
})
}
}
module.exports = CompilerMetadata

@ -27,10 +27,10 @@ class DGitProvider extends Plugin {
constructor () {
super(profile)
this.ipfsconfig = {
host: 'ipfs.komputing.org',
host: 'ipfs.remixproject.org',
port: 443,
protocol: 'https',
ipfsurl: 'https://ipfsgw.komputing.org/ipfs/'
ipfsurl: 'https://ipfs.remixproject.org/ipfs/'
}
this.globalIPFSConfig = {
host: 'ipfs.io',

@ -22,7 +22,7 @@ const profile = {
icon: 'assets/img/fileManager.webp',
permission: true,
version: packageJson.version,
methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh'],
methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName'],
kind: 'file-system'
}
const errorMsg = {
@ -597,6 +597,32 @@ class FileManager extends Plugin {
}
}
/**
* Async API method getProviderOf
* @param {string} file
*
*/
async getProviderOf (file) {
const cancall = await this.askUserPermission('getProviderByName')
if (cancall) {
return file ? this.fileProviderOf(file) : this.currentFileProvider()
}
}
/**
* Async API method getProviderByName
* @param {string} name
*
*/
async getProviderByName (name) {
const cancall = await this.askUserPermission('getProviderByName')
if (cancall) {
return this.getProvider(name)
}
}
getProvider (name) {
return this._deps.filesProviders[name]
}

@ -1,6 +1,6 @@
'use strict'
const CompilerImport = require('../compiler/compiler-imports')
import { CompilerImports } from '@remix-project/core-plugin'
const EventManager = require('events')
const modalDialogCustom = require('../ui/modal-dialog-custom')
const tooltip = require('../ui/tooltip')
@ -44,7 +44,7 @@ class FileProvider {
discardChanges (path) {
this.remove(path)
const compilerImport = new CompilerImport()
const compilerImport = new CompilerImports()
this.providerExternalsStorage.keys().map(value => {
if (value.indexOf(path) === 0) {
compilerImport.import(

@ -2,7 +2,7 @@
import { ViewPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json'
import publishToStorage from '../../publishToStorage'
import { compile } from '../compiler/compiler-helpers'
import { compile } from '@remix-project/remix-solidity'
const EventEmitter = require('events')
const $ = require('jquery')

@ -1,6 +1,6 @@
import toaster from '../../ui/tooltip'
import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '../../compiler/compiler-utils'
import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '@remix-project/remix-solidity'
const yo = require('yo-yo')
const helper = require('../../../lib/helper')
const addTooltip = require('../../ui/tooltip')

@ -1,6 +1,6 @@
import { CompilerAbstract } from '@remix-project/remix-solidity'
const remixLib = require('@remix-project/remix-lib')
const txHelper = remixLib.execution.txHelper
const CompilerAbstract = require('../../../compiler/compiler-abstract')
const EventManager = remixLib.EventManager
const _paq = window._paq = window._paq || []

@ -8,7 +8,7 @@ const globalRegistry = require('../../global/registry')
const profile = {
name: 'settings',
displayName: 'Settings',
methods: ['getGithubAccessToken'],
methods: ['get'],
events: [],
icon: 'assets/img/settings.webp',
description: 'Remix-IDE settings',
@ -52,8 +52,8 @@ module.exports = class SettingsTab extends ViewPlugin {
)
}
getGithubAccessToken () {
return this.config.get('settings/gist-access-token')
get (key) {
return this.config.get(key)
}
updateMatomoAnalyticsChoice (isChecked) {

@ -1,7 +1,6 @@
import { ViewPlugin } from '@remixproject/engine-web'
import { canUseWorker, urlFromVersion } from '../compiler/compiler-utils'
import { removeMultipleSlashes, removeTrailingSlashes } from '../../lib/helper'
import { canUseWorker, urlFromVersion } from '@remix-project/remix-solidity'
var yo = require('yo-yo')
var async = require('async')
var tooltip = require('../ui/tooltip')

@ -1,12 +1,12 @@
import * as packageJson from '../../../../../../package.json'
import { ViewPlugin } from '@remixproject/engine-web'
import { migrateToWorkspace } from '../../../migrateFileSystem'
import { CompilerImports } from '@remix-project/core-plugin'
import JSZip from 'jszip'
const yo = require('yo-yo')
const csjs = require('csjs-inject')
const globalRegistry = require('../../../global/registry')
const CompilerImport = require('../../compiler/compiler-imports')
const modalDialogCustom = require('../modal-dialog-custom')
const modalDialog = require('../modaldialog')
const tooltip = require('../tooltip')
@ -240,7 +240,7 @@ export class LandingPage extends ViewPlugin {
render () {
const load = (service, item, examples, info) => {
const compilerImport = new CompilerImport()
const compilerImport = new CompilerImports()
const fileProviders = globalRegistry.get('fileproviders').api
const msg = yo`
<div class="p-2">

@ -1,9 +1,9 @@
'use strict'
import { CompilerImports } from '@remix-project/core-plugin'
var yo = require('yo-yo')
var async = require('async')
var EventManager = require('../lib/events')
var CompilerImport = require('../app/compiler/compiler-imports')
var toolTip = require('../app/ui/tooltip')
var globalRegistry = require('../global/registry')
var SourceHighlighter = require('../app/editor/sourceHighlighter')
@ -18,7 +18,7 @@ class CmdInterpreterAPI {
self._components.registry = localRegistry || globalRegistry
self._components.terminal = terminal
self._components.sourceHighlighter = new SourceHighlighter()
self._components.fileImport = new CompilerImport()
self._components.fileImport = new CompilerImports()
self._components.gistHandler = new GistHandler()
self._deps = {
fileManager: self._components.registry.get('filemanager').api,

@ -4,7 +4,7 @@ const async = require('async')
const IpfsClient = require('ipfs-mini')
const ipfsNodes = [
new IpfsClient({ host: 'ipfs.komputing.org', port: 443, protocol: 'https' }),
new IpfsClient({ host: 'ipfs.remixproject.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' })
]

@ -0,0 +1 @@
{ "extends": "../../.eslintrc", "rules": {}, "ignorePatterns": ["!**/*"] }

@ -0,0 +1,3 @@
# remix-core-plugin-core-plugin
This library was generated with [Nx](https://nx.dev).

@ -0,0 +1,12 @@
{
"name": "@remix-project/core-plugin",
"version": "0.0.1",
"description": "This library was generated with [Nx](https://nx.dev).",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Remix Team",
"license": "ISC"
}

@ -0,0 +1,5 @@
export { OffsetToLineColumnConverter } from './lib/offset-line-to-column-converter'
export { CompilerMetadata } from './lib/compiler-metadata'
export { FetchAndCompile } from './lib/compiler-fetch-and-compile'
export { CompilerImports } from './lib/compiler-content-imports'
export { CompilerArtefacts } from './lib/compiler-artefacts'

@ -1,16 +1,17 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json'
import CompilerAbstract from './compiler-abstract'
import { CompilerAbstract } from '@remix-project/remix-solidity'
const profile = {
name: 'compilerArtefacts',
methods: [],
methods: ['get', 'addResolvedContract'],
events: [],
version: packageJson.version
version: '0.0.1'
}
module.exports = class CompilerArtefacts extends Plugin {
export class CompilerArtefacts extends Plugin {
compilersArtefactsPerFile: any
compilersArtefacts: any
constructor () {
super(profile)
this.compilersArtefacts = {}

@ -0,0 +1,175 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import { RemixURLResolver } from '@remix-project/remix-url-resolver'
const remixTests = require('@remix-project/remix-tests')
const async = require('async')
const profile = {
name: 'contentImport',
displayName: 'content import',
version: '0.0.1',
methods: ['resolve', 'resolveAndSave', 'isExternalUrl']
}
export class CompilerImports extends Plugin {
previouslyHandled: {}
urlResolver: any
constructor () {
super(profile)
this.urlResolver = new RemixURLResolver()
this.previouslyHandled = {} // cache import so we don't make the request at each compilation.
}
async setToken () {
const protocol = typeof window !== 'undefined' && window.location.protocol
const token = await this.call('settings', 'get', 'settings/gist-access-token')
this.urlResolver.setGistToken(token, protocol)
}
isRelativeImport (url) {
return /^([^/]+)/.exec(url)
}
isExternalUrl (url) {
const handlers = this.urlResolver.getHandlers()
return handlers.some(handler => handler.match(url))
}
/**
* resolve the content of @arg url. This only resolves external URLs.
*
* @param {String} url - external URL of the content. can be basically anything like raw HTTP, ipfs URL, github address etc...
* @returns {Promise} - { content, cleanUrl, type, url }
*/
resolve (url) {
return new Promise((resolve, reject) => {
this.import(url, null, (error, content, cleanUrl, type, url) => {
if (error) return reject(error)
resolve({ content, cleanUrl, type, url })
}, null)
})
}
async import (url, force, loadingCb, cb) {
if (typeof force !== 'boolean') {
const temp = loadingCb
loadingCb = force
cb = temp
force = false
}
if (!loadingCb) loadingCb = () => {}
if (!cb) cb = () => {}
var self = this
if (force) delete this.previouslyHandled[url]
var imported = this.previouslyHandled[url]
if (imported) {
return cb(null, imported.content, imported.cleanUrl, imported.type, url)
}
let resolved
try {
await this.setToken()
resolved = await this.urlResolver.resolve(url)
const { content, cleanUrl, type } = resolved
self.previouslyHandled[url] = {
content,
cleanUrl,
type
}
cb(null, content, cleanUrl, type, url)
} catch (e) {
return cb(new Error('not found ' + url))
}
}
importExternal (url, targetPath, cb) {
this.import(url,
// TODO: handle this event
(loadingMsg) => { this.emit('message', loadingMsg) },
async (error, content, cleanUrl, type, url) => {
if (error) return cb(error)
try {
const provider = await this.call('fileManager', 'getProviderOf', null)
const path = targetPath || type + '/' + cleanUrl
if (provider) provider.addExternal('.deps/' + path, content, url)
} catch (err) {
}
cb(null, content)
}, null)
}
/**
* import the content of @arg url.
* first look in the browser localstorage (browser explorer) or locahost explorer. if the url start with `browser/*` or `localhost/*`
* then check if the @arg url is located in the localhost, in the node_modules or installed_contracts folder
* then check if the @arg url match any external url
*
* @param {String} url - URL of the content. can be basically anything like file located in the browser explorer, in the localhost explorer, raw HTTP, github address etc...
* @param {String} targetPath - (optional) internal path where the content should be saved to
* @returns {Promise} - string content
*/
resolveAndSave (url, targetPath) {
return new Promise((resolve, reject) => {
if (url.indexOf('remix_tests.sol') !== -1) resolve(remixTests.assertLibCode)
this.call('fileManager', 'getProviderOf', url).then((provider) => {
if (provider) {
if (provider.type === 'localhost' && !provider.isConnected()) {
return reject(new Error(`file provider ${provider.type} not available while trying to resolve ${url}`))
}
provider.exists(url).then(exist => {
/*
if the path is absolute and the file does not exist, we can stop here
Doesn't make sense to try to resolve "localhost/node_modules/localhost/node_modules/<path>" and we'll end in an infinite loop.
*/
if (!exist && url.startsWith('browser/')) return reject(new Error(`not found ${url}`))
if (!exist && url.startsWith('localhost/')) return reject(new Error(`not found ${url}`))
if (exist) {
return provider.get(url, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}
// try to resolve localhost modules (aka truffle imports) - e.g from the node_modules folder
this.call('fileManager', 'getProviderByName', 'localhost').then((localhostProvider) => {
if (localhostProvider.isConnected()) {
var splitted = /([^/]+)\/(.*)$/g.exec(url)
return async.tryEach([
(cb) => { this.resolveAndSave('localhost/installed_contracts/' + url, null).then((result) => cb(null, result)).catch((error) => cb(error.message)) },
// eslint-disable-next-line standard/no-callback-literal
(cb) => { if (!splitted) { cb('URL not parseable: ' + url) } else { this.resolveAndSave('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2], null).then((result) => cb(null, result)).catch((error) => cb(error.message)) } },
(cb) => { this.resolveAndSave('localhost/node_modules/' + url, null).then((result) => cb(null, result)).catch((error) => cb(error.message)) },
// eslint-disable-next-line standard/no-callback-literal
(cb) => { if (!splitted) { cb('URL not parseable: ' + url) } else { this.resolveAndSave('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2], null).then((result) => cb(null, result)).catch((error) => cb(error.message)) } }],
(error, result) => {
if (error) {
return this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
}
resolve(result)
})
}
this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
})
}).catch(error => {
return reject(error)
})
}
}).catch(() => {
// fallback to just resolving the file, it won't be saved in file manager
return this.importExternal(url, targetPath, (error, content) => {
if (error) return reject(error)
resolve(content)
})
})
})
}
}

@ -1,18 +1,19 @@
import * as packageJson from '../../../../../package.json'
import { Plugin } from '@remixproject/engine'
import { compile } from './compiler-helpers'
import globalRegistry from '../../global/registry'
import { compile } from '@remix-project/remix-solidity'
import { util } from '@remix-project/remix-lib'
import remixLib from '@remix-project/remix-lib'
const ethutil = require('ethereumjs-util')
const profile = {
name: 'fetchAndCompile',
methods: ['resolve'],
version: packageJson.version
version: '0.0.1'
}
export default class FetchAndCompile extends Plugin {
export class FetchAndCompile extends Plugin {
unresolvedAddresses: any[]
sourceVerifierNetWork: string[]
constructor () {
super(profile)
this.unresolvedAddresses = []
@ -32,11 +33,10 @@ export default class FetchAndCompile extends Plugin {
*/
async resolve (contractAddress, codeAtAddress, targetPath) {
contractAddress = ethutil.toChecksumAddress(contractAddress)
const compilersartefacts = globalRegistry.get('compilersartefacts').api
const localCompilation = () => compilersartefacts.get(contractAddress) ? compilersartefacts.get(contractAddress) : compilersartefacts.get('__last') ? compilersartefacts.get('__last') : null
const localCompilation = async () => await this.call('compilerArtefacts', 'get', contractAddress) ? await this.call('compilerArtefacts', 'get', contractAddress) : await this.call('compilerArtefacts', 'get', '__last') ? await this.call('compilerArtefacts', 'get', '__last') : null
const resolved = compilersartefacts.get(contractAddress)
const resolved = await this.call('compilerArtefacts', 'get', contractAddress)
if (resolved) return resolved
if (this.unresolvedAddresses.includes(contractAddress)) return localCompilation()
@ -53,15 +53,15 @@ export default class FetchAndCompile extends Plugin {
if (!this.sourceVerifierNetWork.includes(network.name)) return localCompilation()
// check if the contract if part of the local compilation result
const compilation = localCompilation()
const compilation = await localCompilation()
if (compilation) {
let found = false
compilation.visitContracts((contract) => {
found = remixLib.util.compareByteCode('0x' + contract.object.evm.deployedBytecode.object, codeAtAddress)
found = util.compareByteCode('0x' + contract.object.evm.deployedBytecode.object, codeAtAddress)
return found
})
if (found) {
compilersartefacts.addResolvedContract(contractAddress, compilation)
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilation)
setTimeout(_ => this.emit('usingLocalCompilation', contractAddress), 0)
return compilation
}
@ -118,8 +118,8 @@ export default class FetchAndCompile extends Plugin {
const compData = await compile(
compilationTargets,
settings,
(url, cb) => this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
compilersartefacts.addResolvedContract(contractAddress, compData)
async (url, cb) => await this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compData)
return compData
} catch (e) {
this.unresolvedAddresses.push(contractAddress)

@ -0,0 +1,145 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import { CompilerAbstract } from '@remix-project/remix-solidity'
const profile = {
name: 'compilerMetadata',
methods: ['deployMetadataOf'],
events: [],
version: '0.0.1'
}
export class CompilerMetadata extends Plugin {
networks: string[]
innerPath: string
constructor () {
super(profile)
this.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
this.innerPath = 'artifacts'
}
_JSONFileName (path, contractName) {
return this.joinPath(path, this.innerPath, contractName + '.json')
}
_MetadataFileName (path, contractName) {
return this.joinPath(path, this.innerPath, contractName + '_metadata.json')
}
onActivation () {
var self = this
this.on('solidity', 'compilationFinished', async (file, source, languageVersion, data) => {
if (!await this.call('settings', 'get', 'settings/generate-contract-metadata')) return
const compiler = new CompilerAbstract(languageVersion, data, source)
var path = self._extractPathOf(source.target)
compiler.visitContracts((contract) => {
if (contract.file !== source.target) return
(async () => {
const fileName = self._JSONFileName(path, contract.name)
const content = await this.call('fileManager', 'exists', fileName) ? await this.call('fileManager', 'readFile', fileName) : null
await this._setArtefacts(content, contract, path)
})()
})
})
}
_extractPathOf (file) {
var reg = /(.*)(\/).*/
var path = reg.exec(file)
return path ? path[1] : '/'
}
async _setArtefacts (content, contract, path) {
content = content || '{}'
var metadata
try {
metadata = JSON.parse(content)
} catch (e) {
console.log(e)
}
var fileName = this._JSONFileName(path, contract.name)
var metadataFileName = this._MetadataFileName(path, contract.name)
var deploy = metadata.deploy || {}
this.networks.forEach((network) => {
deploy[network] = this._syncContext(contract, deploy[network] || {})
})
let parsedMetadata
try {
parsedMetadata = JSON.parse(contract.object.metadata)
} catch (e) {
console.log(e)
}
if (parsedMetadata) await this.call('fileManager', 'writeFile', metadataFileName, JSON.stringify(parsedMetadata, null, '\t'))
var data = {
deploy,
data: {
bytecode: contract.object.evm.bytecode,
deployedBytecode: contract.object.evm.deployedBytecode,
gasEstimates: contract.object.evm.gasEstimates,
methodIdentifiers: contract.object.evm.methodIdentifiers
},
abi: contract.object.abi
}
await this.call('fileManager', 'writeFile', fileName, JSON.stringify(data, null, '\t'))
}
_syncContext (contract, metadata) {
var linkReferences = metadata.linkReferences
var autoDeployLib = metadata.autoDeployLib
if (!linkReferences) linkReferences = {}
if (autoDeployLib === undefined) autoDeployLib = true
for (var libFile in contract.object.evm.bytecode.linkReferences) {
if (!linkReferences[libFile]) linkReferences[libFile] = {}
for (var lib in contract.object.evm.bytecode.linkReferences[libFile]) {
if (!linkReferences[libFile][lib]) {
linkReferences[libFile][lib] = '<address>'
}
}
}
metadata.linkReferences = linkReferences
metadata.autoDeployLib = autoDeployLib
return metadata
}
async deployMetadataOf (contractName, fileLocation) {
let path
if (fileLocation) {
path = fileLocation.split('/')
path.pop()
path = path.join('/')
} else {
try {
path = this._extractPathOf(await this.call('fileManager', 'getCurrentFile'))
} catch (err) {
console.log(err)
throw new Error(err)
}
}
try {
const { id, name } = await this.call('network', 'detectNetwork')
const fileName = this._JSONFileName(path, contractName)
try {
const content = await this.call('fileManager', 'readFile', fileName)
if (!content) return null
let metadata = JSON.parse(content)
metadata = metadata.deploy || {}
return metadata[name + ':' + id] || metadata[name] || metadata[id] || metadata[name.toLowerCase() + ':' + id] || metadata[name.toLowerCase()]
} catch (err) {
return null
}
} catch (err) {
console.log(err)
throw new Error(err)
}
}
joinPath (...paths) {
paths = paths.filter((value) => value !== '').map((path) => path.replace(/^\/|\/$/g, '')) // remove first and last slash)
if (paths.length === 1) return paths[0]
return paths.join('/')
}
}

@ -0,0 +1,77 @@
'use strict'
import { Plugin } from '@remixproject/engine'
import { sourceMappingDecoder } from '@remix-project/remix-debug'
const profile = {
name: 'offsetToLineColumnConverter',
methods: ['offsetToLineColumn'],
events: [],
version: '0.0.1'
}
export class OffsetToLineColumnConverter extends Plugin {
lineBreakPositionsByContent: {}
sourceMappingDecoder: any
constructor () {
super(profile)
this.lineBreakPositionsByContent = {}
this.sourceMappingDecoder = sourceMappingDecoder
}
/**
* Convert offset representation with line/column representation.
* This is also used to resolve the content:
* @arg file is the index of the file in the content sources array and content sources array does have filename as key and not index.
* So we use the asts (which references both index and filename) to look up the actual content targeted by the @arg file index.
* @param {{start, length}} rawLocation - offset location
* @param {number} file - The index where to find the source in the sources parameters
* @param {Object.<string, {content}>} sources - Map of content sources
* @param {Object.<string, {ast, id}>} asts - Map of content sources
*/
offsetToLineColumn (rawLocation, file, sources, asts) {
if (!this.lineBreakPositionsByContent[file]) {
const sourcesArray = Object.keys(sources)
if (!asts || (file === 0 && sourcesArray.length === 1)) {
// if we don't have ast, we process the only one available content (applicable also for compiler older than 0.4.12)
this.lineBreakPositionsByContent[file] = this.sourceMappingDecoder.getLinebreakPositions(sources[sourcesArray[0]].content)
} else {
for (var filename in asts) {
const source = asts[filename]
if (source.id === file) {
this.lineBreakPositionsByContent[file] = this.sourceMappingDecoder.getLinebreakPositions(sources[filename].content)
break
}
}
}
}
return this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
}
/**
* Convert offset representation with line/column representation.
* @param {{start, length}} rawLocation - offset location
* @param {number} file - The index where to find the source in the sources parameters
* @param {string} content - source
*/
offsetToLineColumnWithContent (rawLocation, file, content) {
this.lineBreakPositionsByContent[file] = this.sourceMappingDecoder.getLinebreakPositions(content)
return this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file])
}
/**
* Clear the cache
*/
clear () {
this.lineBreakPositionsByContent = {}
}
/**
* called by plugin API
*/
activate () {
this.on('solidity', 'compilationFinished', () => {
this.clear()
})
}
}

@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"declaration": true,
"rootDir": "./src",
"types": ["node"]
},
"exclude": ["**/*.spec.ts"],
"include": ["**/*.ts"]
}

@ -67,7 +67,7 @@ export class EventManager {
}
for (const listener in this.registered[eventName]) {
const l = this.registered[eventName][listener]
l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
if (l.func) l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
}
}
}

@ -48,7 +48,7 @@ export async function extractHexValue (location, storageResolver, byteLength) {
try {
slotvalue = await readFromStorage(location.slot, storageResolver)
} catch (e) {
return '0x'
return ''
}
return extractHexByteSlice(slotvalue, byteLength, location.offset)
}

@ -151,7 +151,7 @@ export class TraceManager {
if (this.trace[stepIndex] && this.trace[stepIndex].stack) { // there's always a stack
const stack = this.trace[stepIndex].stack.slice(0)
stack.reverse()
return stack
return stack.map(el => el.startsWith('0x') ? el : '0x' + el)
} else {
throw new Error('no stack found')
}

@ -64,7 +64,7 @@ export class EventManager {
}
for (const listener in this.registered[eventName]) {
const l = this.registered[eventName][listener]
l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
if (l.func) l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
}
}
}

@ -12,23 +12,6 @@ export function extendWeb3 (web3) {
this.extend(web3)
}
export function setProvider (web3, url) {
web3.setProvider(new web3.providers.HttpProvider(url))
}
export function web3DebugNode (network) {
const web3DebugNodes = {
Main: 'https://gethmainnet.komputing.org',
Rinkeby: 'https://remix-rinkeby.ethdevops.io',
Ropsten: 'https://remix-ropsten.ethdevops.io',
Goerli: 'https://remix-goerli.ethdevops.io'
}
if (web3DebugNodes[network]) {
return this.loadWeb3(web3DebugNodes[network])
}
return null
}
export function extend (web3) {
if (!web3.extend) {
return

@ -0,0 +1,48 @@
'use strict'
import txHelper from './txHelper'
export class CompilerAbstract {
languageversion: any
data: any
source: any
constructor (languageversion, data, source) {
this.languageversion = languageversion
this.data = data
this.source = source // source code
}
getContracts () {
return this.data.contracts
}
getContract (name) {
return txHelper.getContract(name, this.data.contracts)
}
visitContracts (calllback) {
return txHelper.visitContracts(this.data.contracts, calllback)
}
getData () {
return this.data
}
getAsts () {
return this.data.sources // ast
}
getSourceName (fileIndex) {
if (this.data && this.data.sources) {
return Object.keys(this.data.sources)[fileIndex]
} else if (Object.keys(this.source.sources).length === 1) {
// if we don't have ast, we return the only one filename present.
const sourcesArray = Object.keys(this.source.sources)
return sourcesArray[0]
}
return null
}
getSourceCode () {
return this.source
}
}

@ -1,7 +1,7 @@
'use strict'
import { canUseWorker, urlFromVersion } from './compiler-utils'
import { Compiler } from '@remix-project/remix-solidity'
import CompilerAbstract from './compiler-abstract'
import { CompilerAbstract } from './compiler-abstract'
import { Compiler } from './compiler'
export const compile = async (compilationTargets, settings, contentResolverCallback) => {
const res = await (() => {

@ -1,3 +1,6 @@
export { Compiler } from './compiler/compiler'
export { compile } from './compiler/compiler-helpers'
export { default as CompilerInput } from './compiler/compiler-input'
export { CompilerAbstract } from './compiler/compiler-abstract'
export * from './compiler/types'
export * from './compiler/compiler-utils'

@ -62,7 +62,7 @@ export default class EventManager {
}
for (const listener in this.registered[eventName]) {
const l = this.registered[eventName][listener]
l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
if (l.func) l.func.apply(l.obj === this.anonymous ? {} : l.obj, args)
}
}
}

@ -30,6 +30,10 @@ export class RemixURLResolver {
constructor (gistToken?: string, protocol = 'http:') {
this.previouslyHandled = {}
this.setGistToken(gistToken, protocol)
}
async setGistToken (gistToken?: string, protocol = 'http:') {
this.gistAccessToken = gistToken || ''
this.protocol = protocol
}
@ -109,7 +113,7 @@ export class RemixURLResolver {
url = url.replace(/^ipfs:\/\/?/, 'ipfs/')
// eslint-disable-next-line no-useless-catch
try {
const req = 'https://ipfsgw.komputing.org/' + url
const req = 'https://ipfs.remixproject.org/' + url
// If you don't find greeter.sol on ipfs gateway use local
// const req = 'http://localhost:8080/' + url
const response: AxiosResponse = await axios.get(req)

@ -6,6 +6,7 @@
"https://remix.ethereum.org",
"package://a7df6d3c223593f3550b35e90d7b0b1f.mod",
"package://6fd22d6fe5549ad4c4d8fd3ca0b7816b.mod",
"https://ipfsgw.komputing.org"
"https://ipfsgw.komputing.org",
"https://ipfs.remixproject.org"
]
}

@ -105,7 +105,10 @@
"remix-ui-checkbox": {
"tags": []
},
"remix-ui-terminal": {
"remix-ui-terminal": {
},
"remix-core-plugin": {
"tags": []
}
}
}

12
package-lock.json generated

@ -17562,12 +17562,6 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"optional": true
},
"fstream": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
@ -21935,6 +21929,12 @@
"which": "^2.0.2"
},
"dependencies": {
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",

@ -41,8 +41,8 @@
"workspace-schematic": "nx workspace-schematic",
"dep-graph": "nx dep-graph",
"help": "nx help",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-core-plugin",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs",
"build:e2e": "tsc -p apps/remix-ide-e2e/tsconfig.e2e.json",

@ -39,10 +39,13 @@
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],
"@remix-ui/workspace": ["libs/remix-ui/workspace/src/index.ts"],
"@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"],
"@remix-ui/static-analyser": ["libs/remix-ui/static-analyser/src/index.ts"],
"@remix-ui/checkbox": ["libs/remix-ui/checkbox/src/index.ts"],
"@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"]
"@remix-ui/terminal": ["libs/remix-ui/terminal/src/index.ts"],
"@remix-ui/settings": ["libs/remix-ui/settings/src/index.ts"],
"@remix-project/core-plugin": [
"libs/remix-core-plugin/src/index.ts"
]
}
},
"exclude": ["node_modules", "tmp"]

@ -811,6 +811,36 @@
}
}
}
},
"remix-core-plugin": {
"root": "libs/remix-core-plugin",
"sourceRoot": "libs/remix-core-plugin/src",
"projectType": "library",
"schematics": {},
"architect": {
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": [
"libs/remix-core-plugin/tsconfig.lib.json"
],
"exclude": [
"**/node_modules/**",
"!libs/remix-core-plugin/**/*"
]
}
},
"build": {
"builder": "@nrwl/node:package",
"options": {
"outputPath": "dist/libs/core-plugin",
"tsConfig": "libs/remix-core-plugin/tsconfig.lib.json",
"packageJson": "libs/remix-core-plugin/package.json",
"main": "libs/remix-core-plugin/src/index.ts"
}
}
}
}
},
"cli": {

Loading…
Cancel
Save