diff --git a/README.adoc b/README.adoc index 08b6995..74d9447 100644 --- a/README.adoc +++ b/README.adoc @@ -82,6 +82,11 @@ None == Version History +* 1.2.3 - 20181026 +- Added search results auto completion in the results history. +- Added `alias set|clear` commands for adding aliases for search queries. +- Added glob pattern matching for `list` and `delete` commands. + * 1.2.2 - 20181026 - Added better `delete` function with confirmation prompt. - Added `undo delete` to restore last deleted node. diff --git a/README.md b/README.md index df4e06b..bd35a2d 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,16 @@ None ## Version History +- 1.2.2 - 20181026 + + - Added better `delete` function with confirmation prompt. + + - Added `undo delete` to restore last deleted node. + +- 1.2.1 - 20181025 + + - Added `list versions` command. + - 1.2 - 20181025 - \[MAJOR\] Adding folder name auto completion diff --git a/package.json b/package.json index a9fb436..6f13fe1 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "flat": "^4.1.0", "fs": "0.0.1-security", "inquirer": "^6.2.0", + "minimatch": "^3.0.4", "shelljs": "^0.8.2", "source-map-loader": "^0.2.4", "ts-loader": "^5.2.2", diff --git a/src/index.ts b/src/index.ts index c43b395..deacf2f 100755 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,8 @@ import * as flatten from "flat"; import * as _cliProgress from "cli-progress"; import chalk = require('chalk'); import AsciiTable = require("ascii-table"); +var minimatch = require("minimatch") + import {throws} from "assert"; let parseNodeRef = (nodeRef?: string) => { @@ -30,6 +32,12 @@ let nodeNameAutoCompletion = async (input, callback) => { return entry.entry.name }); list.push('.', '..'); + + let resultsHistory = vorpal.localStorage.getItem('resultsHistory') ? JSON.parse(vorpal.localStorage.getItem('resultsHistory')) : []; + if(resultsHistory){ + list.push(resultsHistory); + } + return list; } ) @@ -318,9 +326,60 @@ vorpal.command('list versions ') }) }); +interface Alias { + alias: string; + expanded: string; +} -vorpal.command("create folder [path]", "Create folder at the destination.") - .option('-p', "--path", "Relative path from the destination nodeRef.") +vorpal.command('alias set ', 'Sets an alias for an argument/search query') + .action((args, callback) => { + let aliases = getAllAliases(); + + //if found, update + if(getAlias(args.alias)){ + //get all aliases except this one. + aliases = aliases.filter(item => { + return item.alias != args.alias; + }) + } + + let alias:Alias = {alias: args.alias, expanded: args.expanded}; + aliases.push(alias); + + vorpal.localStorage.setItem('aliases', JSON.stringify(aliases)); + //known issue, need to handle setting existing alias. + callback(); + }) ; + +vorpal.command('alias clear', 'Clears all aliases that have been set.') + .action((args, callback) => { + vorpal.localStorage.removeItem('aliases'); + callback(); + }) ; + +function getAllAliases(): Array{ + return vorpal.localStorage.getItem('aliases') ? JSON.parse(vorpal.localStorage.getItem('aliases')) : []; +} + +function getAlias(alias):Alias{ + let aliases = getAllAliases() ; + let filterElement:Alias = aliases.filter(aliasItem => { + return aliasItem.alias == alias + })[0]; + return filterElement; +} + +function getAliasString(alias): string{ + let foundAlias = getAlias(alias); + if(foundAlias){ + return foundAlias.expanded; + }else{ + throw new Error(`Unable to find matching alias for '${alias}'.`) + } +} + +vorpal.command("create folder [destinationNodeRef] [path]", "Create folder at the destination.") + .option('-p, --path', "Relative path from the destination nodeRef.") .alias('mkdir') .action(function (args, callback) { let self = this; @@ -356,9 +415,10 @@ let init = async () => { const error = chalk.default.keyword('red'); const warning = chalk.default.keyword('orange'); -const info = chalk.default.keyword('blue'); +const info = chalk.default.keyword('gray'); -vorpal.command('search [language]', "Searches the repostitory for content.") +vorpal.command('search [language] [alias]', "Searches the repostitory for content.") + .option('-a, --alias', 'Use search query alias') .action(function (args, callback) { let self = this; @@ -366,28 +426,50 @@ vorpal.command('search [language]', "Searches the repostitory for conten self.log(info("You have not set a language, using alfresco full text search syntax (AFTS).")) } - alfrescoJsApi.search.searchApi.search({ - "query": { - "query": args.query, - "language": args.language ? args.language : "afts" - } - }).then(function (data) { - printNodeList(data.list.entries) - }, function (error) { - self.log(error); - }).catch(() => { - }); - callback(); + let query: string; + try { + query = args.options.alias ? getAliasString(args.query) : args.query; + alfrescoJsApi.search.searchApi.search({ + "query": { + "query": query, + "language": args.language ? args.language : "afts" + } + }).then(function (data) { + printNodeList(data.list.entries); + cacheResults(data.list.entries); + }, function (error) { + self.log(error); + }).catch(() => { + + }).then(callback); + }catch(e){ + vorpal.log(e.message); + callback(); + } }); function printNodeList(entries) { var table = new AsciiTable(); table.setHeading('id', 'name', "type"); + //clear the results history + vorpal.localStorage.removeItem('resultsHistory'); + let found = false; entries.forEach(item => { + found = true; table.addRow(item.entry.id, item.entry.name, item.entry.nodeType); }); - vorpal.log(table.toString()); + if(found) + vorpal.log(table.toString()); +} + +function cacheResults(entries){ + vorpal.localStorage.removeItem('resultsHistory'); + entries.forEach(item => { + //add the results to the history. + let resultsHistory = vorpal.localStorage.getItem('resultsHistory'); + vorpal.localStorage.setItem('resultsHistory', JSON.stringify(resultsHistory ? JSON.parse(resultsHistory).push(item.entry.id) : [item.entry.id])) + }); } async function getParent(nodeRef) { @@ -412,16 +494,19 @@ vorpal.command("change node [nodeRef]", "Change into a nodeRef") let self = this; getNodeRef(args.nodeRef).then(nodeRef => { updateCurrentNodeRef(nodeRef, callback); + }).catch(e => () => { self.log(e.message); callback(); }); }); -vorpal.command('clear', "Clears the current node context.") +vorpal.command('clear', "Clears the current node context and history.") .alias('cls') .action((args, callback) => { updateCurrentNodeRef("", callback); + vorpal.localStorage.removeItem('resultsHistory'); + callback(); }); @@ -449,6 +534,10 @@ vorpal.command('undo delete', "Undoes the last delete.") } }); +function matchesPattern(entry, pattern) { + return minimatch(entry.entry.id, pattern) || minimatch(entry.entry.name, pattern); +} + vorpal.command('delete [nodeRefPattern] [force]', 'Deletes a nodeRef matching a pattern') .alias('rm') .option('-f, --force', "Force deletion (no prompt)") @@ -484,17 +573,21 @@ vorpal.command('delete [nodeRefPattern] [force]', 'Deletes a nodeRef m let f: any; if (args.nodeRefPattern) { - if (args.nodeRefPattern == "*") { - vorpal.log(info(`looking for children of the specified node with pattern: ${args.nodeRefPattern}`)) - f = getNodeRef(args.nodeRef, true).then(nodeRef => { - return alfrescoJsApi.core.nodesApi.getNodeChildren(nodeRef).then( - value => { - value.list.entries.forEach(entry => { + vorpal.log(info(`looking for children of the specified node with pattern: ${args.nodeRefPattern}`)) + f = getNodeRef(args.nodeRef, true).then(nodeRef => { + return alfrescoJsApi.core.nodesApi.getNodeChildren(nodeRef).then( + value => { + value.list.entries.forEach(entry => { + if(matchesPattern(entry, args.nodeRefPattern)){ + vorpal.log(warning(`deleting node: ${entry.entry.id}:${entry.entry.name}`)) deleteNode(entry.entry.id); - }); - } - ).then(callback) - }); + } + }); + } + ).then(callback) + }); + if (args.nodeRefPattern == "*") { + }else{ //throw error or show there are no results for pattern. } @@ -536,8 +629,9 @@ vorpal.command('delete [nodeRefPattern] [force]', 'Deletes a nodeRef m } }); -vorpal.command('list children [nodeRef]', "List all children of a given folder.") +vorpal.command('list children [nodeRef] [pattern]', "List all children of a given folder.") .alias('ls') + .option('-p, --pattern', "Pattern for filtering.") .autocomplete({data: nodeNameAutoCompletion}) .action(function (args, callback) { let self = this; @@ -547,8 +641,14 @@ vorpal.command('list children [nodeRef]', "List all children of a given folder." let count = data.list.pagination.count; if (count > 0) { - printNodeList(data.list.entries); - self.log('The number of children in this folder are ' + count); + self.log('The total number of children in this folder are ' + count); + if(args.options.pattern){ + printNodeList(data.list.entries.filter(entry => { + return matchesPattern(entry, args.pattern); + })) + }else{ + printNodeList(data.list.entries); + } } else { self.log("No children found.") }