diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c218333..0495e46 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,7 @@ jobs: zip -qq -r stm-linux-v${{ steps.package-version.outputs.current-version}}.zip . -i stm-linux zip -qq -r stm-alpine-v${{ steps.package-version.outputs.current-version}}.zip . -i stm-alpine zip -qq -r stm-win-v${{ steps.package-version.outputs.current-version}}.zip . -i stm-win.exe + rm stm-macos stm-linux stm-alpine stm-win.exe cd .. - name: Publish artifacts to github diff --git a/README.md b/README.md index 1fa68b3..80bc5fd 100644 --- a/README.md +++ b/README.md @@ -7,33 +7,33 @@ The Solace Try-Me CLI is a command line tool used to publish and receive messages from the Solace PubSub+ Broker. Designed to help develop, test and debug Solace PubSub+ services and applications faster without the need to use a graphical interface. - [Solace Try-Me CLI](#solace-try-me-cli) - * [Documentation](#documentation) - + [Installation](#installation) - - [Homebrew](#homebrew) - - [apt-get](#apt-get) - - [Download](#download) - + [Verify Installation](#verify-installation) - + [Command Structure](#command-structure) - + [Command Parameters](#command-parameters) - + [Command Examples](#command-examples) - + [Command Persistence](#command-persistence) - * [Setup `stm` configuration](#setup-stm-configuration) - + [Use with a Software Broker](#use-with-a-software-broker) - + [Use with a Cloud Broker](#use-with-a-cloud-broker) - * [Run `stm` tool](#run-stm-tool) - + [Working with Software Broker](#working-with-software-broker) - + [Receive Messages](#receive-messages) - + [Working with Cloud Broker](#working-with-cloud-broker) - * [Using `stm` to create and modify Broker resources](#using-stm-to-create-and-modify-broker-resources) - + [Create a Queue](#create-a-queue) - * [Using `stm feed` tool for event feed generation](#using-stm-feed-tool-for-event-feed-generation) - * [Contributing](#contributing) - + [Develop](#develop) - * [Run from build](#run-from-build) - * [Technology Stack](#technology-stack) - * [Resources](#resources) - * [Authors](#authors) - * [License](#license) + - [Documentation](#documentation) + - [Installation](#installation) + - [MacOS using Homebrew](#macos-using-homebrew) + - [Linux (or WSL on Windows) using apt-get](#linux-or-wsl-on-windows-using-apt-get) + - [Download the Archive](#download-the-archive) + - [Verify Installation](#verify-installation) + - [Command Structure](#command-structure) + - [Command Parameters](#command-parameters) + - [Command Examples](#command-examples) + - [Command Persistence](#command-persistence) + - [Setup `stm` configuration](#setup-stm-configuration) + - [Use with a Software Broker](#use-with-a-software-broker) + - [Use with a Cloud Broker](#use-with-a-cloud-broker) + - [Run `stm` tool](#run-stm-tool) + - [Working with Software Broker](#working-with-software-broker) + - [Receive Messages](#receive-messages) + - [Working with Cloud Broker](#working-with-cloud-broker) + - [Using `stm` to create and modify Broker resources](#using-stm-to-create-and-modify-broker-resources) + - [Create a Queue](#create-a-queue) + - [Using `stm feed` tool for event feed generation](#using-stm-feed-tool-for-event-feed-generation) + - [Contributing](#contributing) + - [Develop](#develop) + - [Run from build](#run-from-build) + - [Technology Stack](#technology-stack) + - [Resources](#resources) + - [Authors](#authors) + - [License](#license) ## Documentation diff --git a/package.json b/package.json index beee573..7311670 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solace-community/stm", - "version": "0.0.54", + "version": "0.0.55", "description": "Solace Try-Me Command Line Tool", "repository": { "type": "git", @@ -43,6 +43,8 @@ "enquirer": "^2.4.1", "express": "^4.18.2", "form-data": "^4.0.0", + "hexdump-nodejs": "^0.1.0", + "istextorbinary": "^9.5.0", "http": "^0.0.1-security", "json-schema-library": "^10.0.0-rc1", "node-localstorage": "^3.0.5", diff --git a/public/apibroker.html b/public/apibroker.html index 30c811e..c319610 100644 --- a/public/apibroker.html +++ b/public/apibroker.html @@ -35,14 +35,9 @@ diff --git a/public/apifeed.html b/public/apifeed.html index 489d8f2..c97ca37 100644 --- a/public/apifeed.html +++ b/public/apifeed.html @@ -37,14 +37,9 @@ diff --git a/public/broker.html b/public/broker.html index 85facef..705474c 100644 --- a/public/broker.html +++ b/public/broker.html @@ -35,14 +35,9 @@ diff --git a/public/favicon.ico b/public/favicon.ico index c38b0da..0d2aac9 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/feed.html b/public/feed.html index 6ca46e9..af0ffbe 100644 --- a/public/feed.html +++ b/public/feed.html @@ -35,14 +35,9 @@ diff --git a/public/feed/countform.js b/public/feed/countform.js new file mode 100644 index 0000000..6db1f62 --- /dev/null +++ b/public/feed/countform.js @@ -0,0 +1,76 @@ +function validateInstanceCountRule() { + let valid = true; + + let topic = $("#arr_parameterTopicName").text(); + let message = $("#arr_parameterMessageName").text(); + let fieldParam = $("#arr_parameterPayloadFieldName").text(); + + var feed = JSON.parse(localStorage.getItem('currentFeed')); + var feedRule = feed.rules.find(r => r.topic === topic && r.messageName === message); + + var field = feedRule.payload[fieldParam]; + if (fieldParam.indexOf('.') > 0) + field = getFieldRule(feedRule.payload, fieldParam) + + field.rule = { + ...field.rule, + count: parseInt($('#arr_dataFieldCount').val()) + } + + console.log(field.rule); + localStorage.setItem('changed', true); + localStorage.setItem('currentFeed', JSON.stringify(feed)); + + var parent = document.getElementById('payload-variable-pane'); + parent.innerHTML = ''; + parent.style.width = 'auto'; + + var node = $('#payload-tree-pane').treeview('getSelected') + if (!node || !node.length) return; + + var el = document.createElement('div'); + var field = feedRule.payload[node[0].path]; + if (node[0].path.indexOf('.') > 0) + field = getFieldRule(feedRule.payload, node[0].path) + + el.innerHTML = buildParamRuleUI('send', field.rule, feedRule.topic, 'payload', node[0]); + parent.appendChild(el); + + return valid; +} + +function arrayInstanceCountAssignSubmit() { + 'use strict'; + + // Fetch all the forms we want to apply custom Bootstrap validation styles to + // const forms = document.querySelectorAll('#parameterRulesForm'); + const forms = document.querySelectorAll('.needs-validation#arrayParameterCountForm'); + + + // Loop over them and prevent submission + Array.prototype.slice.call(forms).forEach((form) => { + form.addEventListener('submit', async (event) => { + console.log('In submit', form.id, form.classList); + event.preventDefault(); + if (!form.checkValidity()) { + event.stopPropagation(); + } + + $('#field_instance_count_form').modal('toggle'); + validateInstanceCountRule(); + + const path = window.location.href.substring(0, window.location.href.lastIndexOf('/')); + await fetch(path + `/feedrules`, { + method: "POST", + headers: { + 'Content-Type': 'application/json;charset=UTF-8' + }, + body: localStorage.getItem('currentFeed') + }); + + toastr.success('Instance count rule updated successfully.') + form.classList.toggle('was-validated'); + return false; + }); + }); +} \ No newline at end of file diff --git a/public/feed/manager.js b/public/feed/manager.js index a3acf58..56ecb18 100644 --- a/public/feed/manager.js +++ b/public/feed/manager.js @@ -383,6 +383,46 @@ async function editTopicVariable(el) { } +function editArrayInstanceCount(name, topic, type, nodeId) { + var html = ``; + if (type === 'topic') return html; + + var feed = JSON.parse(localStorage.getItem('currentFeed')); + var topic = $('#topic_name').text(); + var message = $('#message-feed-name').text(); + console.log(`topic - ${topic}, param - ${name}`); + console.log(feed.rules); + + var rule = feed.rules.find(r => r.topic === topic && r.messageName === message); + var node = $('#payload-tree-pane').treeview('getSelected'); + if (!node || !node.length) return; + + var param = node[0].path + console.log('rule-param - ', rule.payload[`${name}`]) + + var field = rule.payload[param]; + if (param.indexOf('.') > 0) + field = getFieldRule(rule.payload, param) + + if (field.type !== 'array') return html; + + var count = ' ('.concat(field.rule.count ? field.rule.count : 2).concat(')'); + html = ` + + + + + Instance count + `; + + return html; +} + async function editPayloadField(el) { var feed = JSON.parse(localStorage.getItem('currentFeed')); var topic = $('#topic_name').text(); @@ -456,6 +496,37 @@ async function editPayloadField(el) { } +async function editInstanceCount(el) { + var feed = JSON.parse(localStorage.getItem('currentFeed')); + var topic = $('#topic_name').text(); + var message = $('#message-feed-name').text(); + var param = el.dataset.name; + console.log(`topic - ${topic}, param - ${param}`); + console.log(feed.rules); + + var rule = feed.rules.find(r => r.topic === topic && r.messageName === message); + var node = $('#payload-tree-pane').treeview('getSelected'); + if (!node || !node.length) return; + + var param = node[0].path + console.log('rule-param - ', rule.payload[`${param}`]) + + var field = rule.payload[param]; + if (param.indexOf('.') > 0) + field = getFieldRule(rule.payload, param) + + $('#arr_parameterRuleType').html('Payload Array Field'); + $('#arr_parameterTopicName').text(topic); + $('#arr_dataFieldName').html(`${param.replaceAll('.properties', '')}`) + $('#arr_dataFieldType').html(`${field.type}${field.subType ? ' of ' + field.subType : ''}`) + $('#arr_parameterMessageName').text(message); + $('#arr_parameterPayloadFieldName').text(param); + $('#arr_parameterTopicVariableName').text(''); + $('#arr_parameterName').attr("placeholder", param); + $('#arr_dataFieldCount').val(field.rule.count ? field.rule.count : 2); + +} + async function editAPIParameter(el) { var feed = JSON.parse(localStorage.getItem('currentFeed')); var topic = $('#topic_name').text(); @@ -519,22 +590,76 @@ async function editAPIParameter(el) { function buildParamRuleUI(action, rule, topic, type = 'topic', node = '', name = '') { var html = ` -
+
${action === 'receive' ? name : rule.name}`; if (action === 'send') { - html += ` + html += ``; + if (type !== 'topic') + html += editArrayInstanceCount(rule.name, topic, type, node.nodeId); + if (!(node.type === 'array' && node.subType === 'object')) { + html += ` + - ` + + Set rule + `; + } + html += ``; + } + + html += ` +
+
+ +
+
`; + Object.keys(rule).forEach((p) => { + html += `
${p.toUpperCase()}
${rule[p]}
` + }); + html += ` +
+
+ +
+ `; + + return html; + +} + +function buildArrayParamRuleUI(action, rule, topic, type = 'topic', node = '', name = '') { + var html = ` +
+
+
+ + ${action === 'receive' ? name : rule.name}`; + if (action === 'send') { + html += ``; + if (type !== 'topic') + html += editArrayInstanceCount(rule.name, topic, type, node.nodeId); + html += ``; } + html += `
+ + + +
+ An array of ${node.subType}s - go ahead and set rules for ${node.subType === 'string' ? 'array element' : 'object atributes'}! +
+
` + html += `
@@ -974,23 +1099,24 @@ async function configureMessageSendTopics(messageName, rules, refresh = false) {
` return; - } else if (node.type === 'array' && node.subType === 'object') { - var el = document.getElementById('payload-variable-pane'); - el.innerHTML = ''; - el.style.width = 'auto'; - el.innerHTML = `
- + } + // else if (node.type === 'array' && node.subType === 'object') { + // var el = document.getElementById('payload-variable-pane'); + // el.innerHTML = ''; + // el.style.width = 'auto'; + // el.innerHTML = `
+ // - -
- An array of ${node.subType}s - go ahead and set rules for ${node.subType === 'string' ? 'array element' : 'object atributes'}! -
-
- ` - return; - } + // + //
+ // An array of ${node.subType}s - go ahead and set rules for ${node.subType === 'string' ? 'array element' : 'object atributes'}! + //
+ //
+ // ` + // return; + // } parent = document.getElementById('payload-variable-pane'); parent.innerHTML = ''; @@ -1647,7 +1773,7 @@ function loadPage() { $( "nav li.nav-item a.nav-link" ).css( "bobackground-color", "unset" ); - if (menuSelection) menuSelection.style.backgroundColor = "#00968857"; + if (menuSelection) menuSelection.style.backgroundColor = "#00c89587"; if (localStorage.getItem('currentFeed')) { var feed = JSON.parse(localStorage.getItem('currentFeed')); diff --git a/public/feed/mapform.js b/public/feed/mapform.js index ea96113..13ff647 100644 --- a/public/feed/mapform.js +++ b/public/feed/mapform.js @@ -52,7 +52,10 @@ async function manageFieldMap() { onNodeSelected: function(event, node) { console.log(node.text + ' @ ' + node.path + ' was selected'); var el = document.getElementById('sourceField'); - el.value = node.path ? `${node.class} : ${node.path}, ${node.type}${node.subType ? ' of ' + node.subType : ''}` : ''; + if (node.type === 'array' || node.type === 'object') + el.value = ''; + else + el.value = node.path ? `${node.class} : ${node.path}, ${node.type}${node.subType ? ' of ' + node.subType : ''}` : ''; $('#srcType').text(node.type); $('#srcSubType').text(node.subType); @@ -108,7 +111,11 @@ async function manageFieldMap() { onNodeSelected: function(event, node) { console.log(node.text + ' @ ' + node.path + ' was selected'); var el = document.getElementById('targetField'); - el.value = node.path ? `${node.class} : ${node.path}, ${node.type}${node.subType ? ' of ' + node.subType : ''}` : ''; + if (node.type === 'array' || node.type === 'object') + el.value = ''; + else + el.value = node.path ? `${node.class} : ${node.path}, ${node.type}${node.subType ? ' of ' + node.subType : ''}` : ''; + $('#tgtType').text(node.type); $('#tgtSubType').text(node.subType); $('#tgtFullPath').text(node.fullPath); diff --git a/public/feedportal b/public/feedportal index e2515fe..4641336 160000 --- a/public/feedportal +++ b/public/feedportal @@ -1 +1 @@ -Subproject commit e2515fe088ef555bbe34da1ab64fb33447617294 +Subproject commit 46413366a0cb2ddc3bf707232b76ab9d0f3a9b65 diff --git a/public/feeds.html b/public/feeds.html index 6dcf512..733dd48 100644 --- a/public/feeds.html +++ b/public/feeds.html @@ -35,14 +35,9 @@ diff --git a/public/images/stmfeed.png b/public/images/stmfeed.png index 09cb86a..0f98c09 100644 Binary files a/public/images/stmfeed.png and b/public/images/stmfeed.png differ diff --git a/public/info.html b/public/info.html index 3cc04c0..a7f7d8b 100644 --- a/public/info.html +++ b/public/info.html @@ -35,14 +35,9 @@ diff --git a/public/message.html b/public/message.html index f8f3097..735bf49 100644 --- a/public/message.html +++ b/public/message.html @@ -41,14 +41,9 @@ @@ -656,6 +651,46 @@

Target Attribute

+ + @@ -699,7 +734,8 @@