lint

update plugin version

update plugin
pull/1218/head
filip mertens 4 years ago
parent 9e83ecbc0f
commit 8f0e7a5b2b
  1. 6
      apps/remix-ide/src/app.js
  2. 400
      apps/remix-ide/src/app/files/dgitProvider.js
  3. 12
      apps/remix-ide/src/app/files/fileManager.js
  4. 22
      apps/remix-ide/src/app/panels/file-panel.js
  5. 2
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  6. 863
      package-lock.json
  7. 17
      package.json

@ -34,6 +34,7 @@ const modalDialogCustom = require('./app/ui/modal-dialog-custom')
const modalDialog = require('./app/ui/modaldialog')
const FileManager = require('./app/files/fileManager')
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')
@ -256,6 +257,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// ----------------- fileManager service ----------------------------
const fileManager = new FileManager(editor, appManager)
registry.put({ api: fileManager, name: 'filemanager' })
// ----------------- dGit provider ---------------------------------
const dGitProvider = new DGitProvider(fileManager)
// ----------------- import content service ------------------------
const contentImport = new CompilerImport(fileManager)
@ -309,7 +312,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
contextualListener,
terminal,
web3Provider,
fetchAndCompile
fetchAndCompile,
dGitProvider
])
// LAYOUT & SYSTEM VIEWS

@ -0,0 +1,400 @@
'use strict'
import {
Plugin
} from '@remixproject/engine'
import git from 'isomorphic-git'
import IpfsHttpClient from 'ipfs-http-client'
import {
saveAs
} from 'file-saver'
const JSZip = require('jszip')
const path = require('path')
const FormData = require('form-data')
const axios = require('axios')
const profile = {
name: 'dGitProvider',
displayName: 'Decentralized git',
description: '',
icon: 'assets/img/fileManager.webp',
version: '0.0.1',
methods: ['init', 'status', 'log', 'commit', 'add', 'remove', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pin', 'pull', 'pinList', 'unPin', 'setIpfsConfig', 'zip', 'setItem', 'getItem'],
kind: 'file-system'
}
class DGitProvider extends Plugin {
constructor (fileManager) {
super(profile)
this.fileManager = fileManager
this.ipfsconfig = {
host: 'ipfs.komputing.org',
port: 443,
protocol: 'https',
ipfsurl: 'https://ipfsgw.komputing.org/ipfs/'
}
this.globalIPFSConfig = {
host: 'ipfs.io',
port: 443,
protocol: 'https',
ipfsurl: 'https://ipfs.io/ipfs/'
}
}
async getGitConfig () {
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
return {
fs: window.remixFileSystem,
dir: workspace.absolutePath
}
}
async init () {
await git.init({
...await this.getGitConfig(),
defaultBranch: 'main'
})
}
async status (cmd) {
const status = await git.statusMatrix({
...await this.getGitConfig(),
...cmd
})
return status
}
async add (cmd) {
await git.add({
...await this.getGitConfig(),
...cmd
})
this.call('fileManager', 'refresh')
}
async rm (cmd) {
await git.remove({
...await this.getGitConfig(),
...cmd
})
this.call('fileManager', 'refresh')
}
async checkout (cmd) {
await git.checkout({
...await this.getGitConfig(),
...cmd
})
this.call('fileManager', 'refresh')
}
async log (cmd) {
const status = await git.log({
...await this.getGitConfig(),
...cmd
})
return status
}
async branch (cmd) {
const status = await git.branch({
...await this.getGitConfig(),
...cmd
})
this.call('fileManager', 'refresh')
return status
}
async currentbranch () {
const name = await git.currentBranch({
...await this.getGitConfig()
})
return name
}
async branches () {
const branches = await git.listBranches({
...await this.getGitConfig()
})
return branches
}
async commit (cmd) {
await this.init()
try {
const sha = await git.commit({
...await this.getGitConfig(),
...cmd
})
return sha
} catch (e) {}
}
async lsfiles (cmd) {
const filesInStaging = await git.listFiles({
...await this.getGitConfig(),
...cmd
})
return filesInStaging
}
async resolveref (cmd) {
const oid = await git.resolveRef({
...await this.getGitConfig(),
...cmd
})
return oid
}
async readblob (cmd) {
const readBlobResult = await git.readBlob({
...await this.getGitConfig(),
...cmd
})
return readBlobResult
}
async setIpfsConfig (config) {
this.ipfsconfig = config
return new Promise((resolve, reject) => {
resolve(this.checkIpfsConfig())
})
}
async checkIpfsConfig (config) {
this.ipfs = IpfsHttpClient(config || this.ipfsconfig)
try {
await this.ipfs.config.getAll()
return true
} catch (e) {
return false
}
}
async push () {
if (!this.checkIpfsConfig()) return false
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/')
this.filesToSend = []
for (const file of files) {
const c = window.remixFileSystem.readFileSync(`${workspace.absolutePath}/${file}`)
const ob = {
path: file,
content: c
}
this.filesToSend.push(ob)
}
const addOptions = {
wrapWithDirectory: true
}
const r = await this.ipfs.add(this.filesToSend, addOptions)
return r.cid.string
}
async pin (pinataApiKey, pinataSecretApiKey) {
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/')
this.filesToSend = []
const data = new FormData()
files.forEach(async (file) => {
const c = window.remixFileSystem.readFileSync(`${workspace.absolutePath}/${file}`)
data.append('file', new Blob([c]), `base/${file}`)
})
// get last commit data
let ob
try {
const commits = await this.log({ ref: 'HEAD' })
ob = {
ref: commits[0].oid,
message: commits[0].commit.message
}
} catch (e) {
ob = {
ref: 'no commits',
message: 'no commits'
}
}
const today = new Date()
const metadata = JSON.stringify({
name: `remix - ${workspace.name} - ${today.toLocaleString()}`,
keyvalues: ob
})
const pinataOptions = JSON.stringify({
wrapWithDirectory: false
})
data.append('pinataOptions', pinataOptions)
data.append('pinataMetadata', metadata)
const url = 'https://api.pinata.cloud/pinning/pinFileToIPFS'
try {
const result = await axios
.post(url, data, {
maxBodyLength: 'Infinity',
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataSecretApiKey
}
})
return result.data.IpfsHash
} catch (error) {
throw new Error(error)
}
}
async pinList (pinataApiKey, pinataSecretApiKey) {
const url = 'https://api.pinata.cloud/data/pinList?status=pinned'
try {
const result = await axios
.get(url, {
maxBodyLength: 'Infinity',
headers: {
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataSecretApiKey
}
})
return result.data
} catch (error) {
throw new Error(error)
}
}
async unPin (pinataApiKey, pinataSecretApiKey, hashToUnpin) {
const url = `https://api.pinata.cloud/pinning/unpin/${hashToUnpin}`
try {
await axios
.delete(url, {
headers: {
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataSecretApiKey
}
})
return true
} catch (error) {
throw new Error(error)
}
};
async pull (cmd) {
const permission = await this.askUserPermission('pull', 'Import multiple files into your workspaces.')
console.log(this.ipfsconfig)
if (!permission) return false
const cid = cmd.cid
if (!cmd.local) {
this.ipfs = IpfsHttpClient(this.globalIPFSConfig)
} else {
if (!this.checkIpfsConfig()) return false
}
await this.call('filePanel', 'createWorkspace', `workspace_${Date.now()}`, false)
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
for await (const file of this.ipfs.get(cid)) {
file.path = file.path.replace(cid, '')
if (!file.content) {
continue
}
const content = []
for await (const chunk of file.content) {
content.push(chunk)
}
const dir = path.dirname(file.path)
try {
this.createDirectories(`${workspace.absolutePath}/${dir}`)
} catch (e) {}
try {
window.remixFileSystem.writeFileSync(`${workspace.absolutePath}/${file.path}`, Buffer.concat(content) || new Uint8Array())
} catch (e) {}
}
this.call('fileManager', 'refresh')
}
async getItem (name) {
if (typeof window !== 'undefined') {
return window.localStorage.getItem(name)
}
}
async setItem (name, content) {
try {
if (typeof window !== 'undefined') {
window.localStorage.setItem(name, content)
}
} catch (exception) {
return false
}
return true
}
async zip () {
const zip = new JSZip()
const workspace = await this.call('filePanel', 'getCurrentWorkspace')
const files = await this.getDirectory('/')
this.filesToSend = []
for (const file of files) {
const c = window.remixFileSystem.readFileSync(`${workspace.absolutePath}/${file}`)
zip.file(file, c)
}
await zip.generateAsync({
type: 'blob'
})
.then(function (content) {
saveAs(content, `${workspace.name}.zip`)
})
}
async createDirectories (strdirectories) {
const ignore = ['.', '/.', '']
if (ignore.indexOf(strdirectories) > -1) return false
const directories = strdirectories.split('/')
for (let i = 0; i < directories.length; i++) {
let previouspath = ''
if (i > 0) previouspath = '/' + directories.slice(0, i).join('/')
const finalPath = previouspath + '/' + directories[i]
try {
window.remixFileSystem.mkdirSync(finalPath)
} catch (e) {}
}
}
async getDirectory (dir) {
let result = []
const files = await this.fileManager.readdir(dir)
const fileArray = normalize(files)
for (const fi of fileArray) {
if (fi) {
const type = fi.data.isDirectory
if (type === true) {
result = [
...result,
...(await this.getDirectory(
`${fi.filename}`
))
]
} else {
result = [...result, fi.filename]
}
}
}
return result
}
}
const normalize = (filesList) => {
const folders = []
const files = []
Object.keys(filesList || {}).forEach(key => {
if (filesList[key].isDirectory) {
folders.push({
filename: key,
data: filesList[key]
})
} else {
files.push({
filename: key,
data: filesList[key]
})
}
})
return [...folders, ...files]
}
module.exports = DGitProvider

@ -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'],
methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh'],
kind: 'file-system'
}
const errorMsg = {
@ -129,6 +129,16 @@ class FileManager extends Plugin {
}
}
/*
* refresh the file explorer
* TODO: it's a hack, can be better
*/
refresh () {
const provider = this.fileProviderOf('/')
provider.event.emit('folderAdded', '/')
}
/**
* Verify if the path provided is a file
* @param {string} path path of the directory or file

@ -35,7 +35,7 @@ const profile = {
name: 'filePanel',
displayName: 'File explorers',
methods: ['createNewFile', 'uploadFile', 'getCurrentWorkspace', 'getWorkspaces', 'createWorkspace'],
events: ['setWorkspace', 'renameWorkspace', 'deleteWorkspace'],
events: ['setWorkspace', 'renameWorkspace', 'deleteWorkspace', 'createWorkspace'],
icon: 'assets/img/fileManager.webp',
description: ' - ',
kind: 'fileexplorer',
@ -202,7 +202,7 @@ module.exports = class Filepanel extends ViewPlugin {
return browserProvider.exists(workspacePath)
}
async createWorkspace (workspaceName) {
async createWorkspace (workspaceName, setDefaults = true) {
if (!workspaceName) throw new Error('name cannot be empty')
if (checkSpecialChars(workspaceName) || checkSlash(workspaceName)) throw new Error('special characters are not allowed')
if (await this.workspaceExists(workspaceName)) throw new Error('workspace already exists')
@ -211,14 +211,16 @@ module.exports = class Filepanel extends ViewPlugin {
await this.processCreateWorkspace(workspaceName)
workspaceProvider.setWorkspace(workspaceName)
await this.request.setWorkspace(workspaceName) // tells the react component to switch to that workspace
for (const file in examples) {
setTimeout(async () => { // space creation of files to give react ui time to update.
try {
await workspaceProvider.set(examples[file].name, examples[file].content)
} catch (error) {
console.error(error)
}
}, 10)
if (setDefaults) {
for (const file in examples) {
setTimeout(async () => { // space creation of files to give react ui time to update.
try {
await workspaceProvider.set(examples[file].name, examples[file].content)
} catch (error) {
console.error(error)
}
}, 10)
}
}
}
}

@ -67,7 +67,7 @@ export const Workspace = (props: WorkspaceProps) => {
}
props.request.getCurrentWorkspace = () => {
return state.currentWorkspace
return { name: state.currentWorkspace, isLocalhost: state.currentWorkspace === LOCALHOST, absolutePath: `${props.workspace.workspacesPath}/${state.currentWorkspace}` }
}
useEffect(() => {

863
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -134,13 +134,13 @@
"@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.1.3",
"@ethereumjs/vm": "^5.3.2",
"@remixproject/engine": "^0.3.16",
"@remixproject/engine-web": "^0.3.16",
"@remixproject/plugin": "^0.3.16",
"@remixproject/plugin-api": "^0.3.16",
"@remixproject/plugin-utils": "^0.3.16",
"@remixproject/plugin-webview": "^0.3.16",
"@remixproject/plugin-ws": "^0.3.16",
"@remixproject/engine": "^0.3.17",
"@remixproject/engine-web": "^0.3.17",
"@remixproject/plugin": "^0.3.17",
"@remixproject/plugin-api": "^0.3.17",
"@remixproject/plugin-utils": "^0.3.17",
"@remixproject/plugin-webview": "^0.3.17",
"@remixproject/plugin-ws": "^0.3.17",
"ansi-gray": "^0.1.1",
"async": "^2.6.2",
"axios": ">=0.21.1",
@ -154,9 +154,12 @@
"ethereumjs-util": "^7.0.10",
"ethers": "^5.1.4",
"express-ws": "^4.0.0",
"file-saver": "^2.0.5",
"form-data": "^4.0.0",
"fs-extra": "^3.0.1",
"http-server": "^0.11.1",
"isbinaryfile": "^3.0.2",
"isomorphic-git": "^1.8.2",
"jquery": "^3.3.1",
"jszip": "^3.6.0",
"latest-version": "^5.1.0",

Loading…
Cancel
Save