-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* first try with console * trying to compile * almost there * almost there * I think I got it * Update README.md * Update README.md * test with old file-client * cleanup * cjs to esm converer! * cjs to esm converter! * added new tests * added upload/download/copy * added upload/download/copy * readme updates * sol bursts forth * sol improvements * changed upload param order * changed upload param order * sol README * npmignore changes
- Loading branch information
1 parent
b9280b6
commit 9c97799
Showing
31 changed files
with
2,302 additions
and
828 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env node | ||
const program = require('commander'); // the command-line interface | ||
const sol = require('./sol.run.js'); // the commands | ||
const sh = require('./sol.shell.js'); // the interactive interface | ||
const batch = require('../src/batch'); // the batch interface | ||
/* | ||
* This file is the command-line interface | ||
*/ | ||
program | ||
.name('sol') | ||
.description('Command line and interactive shell tool for Solid') | ||
.version("0.1.0") | ||
; | ||
program | ||
.command('shell') | ||
.alias('sh') | ||
.description('run as an interactive shell') | ||
.action( () => { | ||
sol("login").then(()=>{sh()},err=>console.log(err)); | ||
}); | ||
program | ||
.command('read <URL>') | ||
.alias('r') | ||
.description('read a file on a Solid server') | ||
.action( (URL) => { | ||
sol("login").then( ()=> { | ||
sol("read",[URL]).then(()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
program | ||
.command('readFolder <URL>') | ||
.alias('rf') | ||
.description("list a Solid server folder's directory") | ||
.action( (URL) => { | ||
sol("login").then( ()=> { | ||
sol("read",["folder",URL]).then(()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
program | ||
.command('createFolder <URL...>') | ||
.alias('cf') | ||
.description('create one or more folders') | ||
.action( URL => { | ||
sol("login").then( ()=> { | ||
sol("createFolder",[URL]).then(()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
program | ||
.command('delete <URL...>') | ||
.alias('rm') | ||
.description('delete a file or empty folder on a Solid server') | ||
.action( URL => { | ||
sol("login").then( ()=> { | ||
sol("delete",[URL]).then(()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
program | ||
.command('upload <target> <files...>') | ||
.alias("up") | ||
.description('upload file(s) to a Solid server') | ||
.action( (target,files) => { | ||
sol("login").then( ()=>{ | ||
sol("upload",[target,files]).then( ()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
program | ||
.command('download <target> <URL>') | ||
.alias("dn") | ||
.description('download a Solid file') | ||
.action( (target,URL) => { | ||
sol("login").then( ()=>{ | ||
sol("download",[target,URL]).then( ()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
program | ||
.command('copy <oldURL> <newURL>') | ||
.alias('cp') | ||
.description('copy a file from one remote location to another') | ||
.action( (oldURL,newURL) => { | ||
sol("login").then( ()=> { | ||
sol("copy",[oldURL,newURL]).then(()=>{ | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
}); | ||
/* TBD | ||
program | ||
.command('batch <scriptFile>') | ||
.description('batch run commands in a script file') | ||
.action( (scriptFile) => { | ||
sol("login").then(()=>{ | ||
sol("batch",[scriptFile]).then(()=>{ | ||
},err=>console.log(err) ) | ||
},err=>console.log(err) ) | ||
},err=>console.log(err)) | ||
*/ | ||
if(process.argv.length<3){ | ||
process.argv.push("-h"); | ||
} | ||
program.parse(process.argv); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
//const fc = require("../dist/console/index.js"); | ||
const fc = require("../src/index.js"); | ||
const show = require("./sol.show.js"); | ||
const batch = require("../src/batch"); | ||
let credentials; | ||
|
||
module.exports = runSol; | ||
async function runSol(com,args) { | ||
let fn,source,target; | ||
return new Promise((resolve,reject)=>{ switch(com){ | ||
|
||
case "help" : | ||
case "h" : | ||
show("help"); | ||
resolve(); | ||
break; | ||
|
||
case "login" : | ||
console.log("logging in ..."); | ||
fc.getCredentials().then ( creds => { | ||
credentials = creds; | ||
fc.login( credentials ).then( session => { | ||
console.log("logged in"); | ||
resolve(); | ||
}, err => reject("error logging in : "+err) ); | ||
}, err => reject("error getting credentials : "+err) ); | ||
break; | ||
|
||
case "rf" : | ||
case "readFolder" : | ||
source = mungeURL(args[0]); | ||
console.log("fetching from "+source) | ||
fc.readFolder(source).then( folderObject => { | ||
show("folder",folderObject); | ||
resolve() | ||
},err=>console.log(err)); | ||
break; | ||
|
||
|
||
case "r" : | ||
case "read" : | ||
case "readFile" : | ||
source = mungeURL(args[0]); | ||
console.log("fetching from file "+source); | ||
fc.readFile(source).then( fileBody =>{ | ||
show("file",fileBody); | ||
resolve() | ||
},err=>console.log(err)); | ||
break; | ||
|
||
case "rm" : | ||
case "delete" : | ||
if( args.length>1 ){ | ||
target = [ args ] // in shell, multiple args | ||
} | ||
else target = args[0]; | ||
if( typeof(target)!="string" && target.length<2){ | ||
target = target[0]; | ||
} | ||
if( typeof(target)==="string" ){ | ||
target = mungeURL(target); | ||
if( target.match(/\*$/) ){ | ||
target = target.replace(/\*$/,''); | ||
fc.readFolder(target).then( gotFolder => { | ||
let all= gotFolder.folders.concat(gotFolder.files); | ||
doMany("rm",all).then( ()=>{ | ||
resolve() | ||
},err=>console.log(err)); | ||
},err=>console.log(err)); | ||
break; | ||
} | ||
console.log("deleting "+target); | ||
fc.deleteFile(target).then( () => { | ||
console.log("deleted"); | ||
resolve(); | ||
}, err => reject("error deleting "+err) ); | ||
break; | ||
} | ||
else { | ||
doMany("delete",target).then( ()=>{ | ||
resolve() | ||
}, err => reject(err) ) | ||
break; | ||
} | ||
break; | ||
|
||
case "cf" : | ||
case "createFolder" : | ||
if( args.length>1 ){ | ||
target = [ args ] | ||
} | ||
else target = args[0]; | ||
if( typeof(target)!="string" && target.length<2){ | ||
target = target[0]; | ||
} | ||
if( typeof(target)==="string" ){ | ||
target = mungeURL(target); | ||
console.log("creating folder '"+target+"'"); | ||
fc.createFolder(target).then( () => { | ||
console.log("created folder"); | ||
resolve(); | ||
}, err => reject("error creating folder "+err) ); | ||
} | ||
else { | ||
doMany("createFolder",target).then( ()=>{ | ||
resolve() | ||
}, err => reject(err) ) | ||
break; | ||
} | ||
break; | ||
|
||
case "dn" : | ||
case "download" : | ||
[target,source] = args; | ||
fn = path.join( target , source.replace(/.*\//,'') ) | ||
source = mungeURL(source); | ||
target = path.join(__dirname,fn); | ||
console.log("downloading from "+source+" to "+fn); | ||
fc.downloadFile(source,target).then( () => { | ||
console.log("downloaded"); | ||
resolve(); | ||
}, err => reject("error downloading file "+err) ); | ||
break; | ||
|
||
case "up" : | ||
case "upload" : | ||
[ target, source ] = args; | ||
target = mungeURL(target); | ||
if( source.match && source.match(/\*$/) ){ // shell | ||
source = source.replace(/\*$/,''); | ||
source = path.join(__dirname,source); | ||
fs.readdir(source, (err,files) => { | ||
if(err) reject(err); | ||
else { | ||
files = files.map(x=>path.join(source,x)) | ||
doMany("upload",files,target).then( ()=>{ | ||
resolve() | ||
}, err => reject(err) ) | ||
} | ||
},err=>reject(err)); | ||
break; | ||
} | ||
if( typeof(source)!="string" ){ | ||
doMany("upload",source,target).then( ()=>{ | ||
resolve() | ||
}, err => reject(err) ) | ||
break; | ||
} | ||
if( fs.lstatSync(source).isFile() ){ | ||
fn = source.replace(/.*\//,'') | ||
console.log("uploading file "+target+fn); | ||
fc.uploadFile(source,target).then( () => { | ||
console.log("uploaded file"); | ||
resolve(); | ||
}, err => reject("error uploading file "+err) ); | ||
break; | ||
} | ||
else if( fs.lstatSync(source).isDirectory() ){ | ||
source = source.replace(/.*\//,'') | ||
target = path.join(target,source).replace(/^https:\//,"https://") | ||
console.log("uploading folder "+target); | ||
fc.createFolder(target).then( () => { | ||
console.log("uploaded folder"); | ||
resolve(); | ||
}, err => reject("error uploading folder "+err) ); | ||
} | ||
break; | ||
|
||
case "cp" : | ||
case "copy" : | ||
args[0] = mungeURL(args[0]); | ||
args[1] = mungeURL(args[1]); | ||
console.log("copying "+args[0]+" to "+args[1]); | ||
fc.copyFile(args[0],args[1]).then( () => { | ||
console.log("copied"); | ||
resolve(); | ||
}, err => reject("error copying file "+err) ); | ||
break; | ||
|
||
case "batch" : | ||
source = path.join(__dirname,args[0]) | ||
fs.readFile( source, 'utf-8', (err,content) => { | ||
if(err) reject(err); | ||
else { | ||
let set = [] | ||
let commands = content.split("\n") | ||
for(c in commands){ | ||
let line = commands[c].trim() | ||
if( !line ) continue; | ||
let newArgs = line.split(/\s+/) | ||
let newCom = newArgs.shift() | ||
set.push( function(){ | ||
runSol( newCom, newArgs ).then( ()=> { | ||
batch.skip() | ||
},err=>batch.skip(err) ) | ||
}) | ||
} | ||
batch.run(set); | ||
} | ||
},err=>reject(err)); | ||
break; | ||
|
||
default : | ||
if( com.match && com.match(/^\!/) ){ | ||
/* issue shell command, needs work | ||
const shell = require('shelljs'); | ||
shell.config.silent = true; // suppress stdout | ||
com = com.replace(/^\!/,''); | ||
results = shell.exec( com ); | ||
console.log(results.stdout); | ||
resolve(); | ||
*/ | ||
} | ||
else if(com) console.log("can't parse last command") | ||
resolve(); | ||
}}); | ||
} | ||
function mungeURL(url) { | ||
if( url && url.match(/^https:\/[^/]/) ) | ||
url = url.replace(/^https:\//,"https://") | ||
if( url && !url.match(/^http/) && credentials && credentials.base) | ||
return credentials.base + url; | ||
else | ||
return url; | ||
} | ||
function mungeLocalFolder(source){ | ||
let files = []; | ||
for(var s in source){ | ||
if( fs.lstatSync(source[s]).isFile() ){ | ||
files.push(source[s]); | ||
} | ||
} | ||
return(files) | ||
} | ||
async function doMany(com,files,targetDir){ | ||
if( files.length < 1 ) return; | ||
let file = files.shift(); | ||
if( typeof(file)!="string" ){ | ||
file = file.url; | ||
} | ||
let fn = file.replace(/.*\//,''); | ||
if( targetDir ){ | ||
// let target = path.join(targetDir,fn).replace(/:\//,'://'); | ||
runSol(com,[targetDir,file]).then( ()=>{ | ||
doMany(com,files,targetDir); | ||
}); | ||
} | ||
else { | ||
runSol(com,[file]).then( ()=>{ | ||
doMany(com,files); | ||
}); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
const sol = require('./sol.run.js'); | ||
|
||
function prompt(question, callback) { | ||
var stdin = process.stdin, stdout = process.stdout; | ||
stdin.resume(); | ||
stdout.write(question); | ||
stdin.once('data', function (data) { | ||
callback(data.toString().trim()); | ||
}); | ||
} | ||
function sh(){ | ||
prompt("> ", data => { | ||
/* | ||
* TBD : real command parsing rather than split | ||
*/ | ||
let args = data.split(/\s+/) | ||
let com = args.shift() | ||
if( com.match(/(q|quit|exit)/) ) process.exit(); | ||
sol( com, args ).then(()=>{sh()},err=>{ | ||
console.log(err); | ||
sh(); | ||
}); | ||
}); | ||
} | ||
module.exports = sh; |
Oops, something went wrong.