mushy 0.15.3 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b743e14b0d41b727255550df74d33edc0c5eb33b4426e31d4eea41830aa167e
4
- data.tar.gz: 26e61eb0310e6a512deca465c0bb375c94b28ce58a3ee296e677b60a4fea5fc3
3
+ metadata.gz: 9f18a4ff7bf18c88f36a66481bd9fd56e7511ca276f5312b2f4bf2862e8d5aa5
4
+ data.tar.gz: 2d40205cd64f986cc7234c847173ed4dbf95f0ba2f3ccf5d81e71290fb23d6c4
5
5
  SHA512:
6
- metadata.gz: 9bcfe3677a5ca79b2e0249e1b03dec50bc2a019a06f8c61dcb0b4d6e76fc7f11f28f86f32c908d666ba163427a020630f43f73d0ad2c429a35a6f66bf047eab9
7
- data.tar.gz: 421e40fea84d8ed8e18f0f60584d55b21bb540139c6e9c28cfcf5ce8770a3102e6a92d17efe4b44fae4706bc36b9e2d080b036ba9208162ac5efe60e3c04a657
6
+ metadata.gz: 183e5fe0556b562c1747d1005dc238ca034ca1745e0505a763e394d008a4315de63c65f53cab0435cf45a219e54e68bf705095218ab85e572d04e658b0c6d25b
7
+ data.tar.gz: d856b27867d3946ff2ca840ae1eff9c96b07b7a06757bde41d6475351be68a36b97d9395324c4e3ee0e198ec3b5cd4352bffb5637e2f76a78663c5da08565245
@@ -129,6 +129,9 @@ module Mushy
129
129
  {
130
130
  fluxs: Mushy::Flux.all.select { |x| x.respond_to? :details }.select { |x| x.details }.map do |flux|
131
131
  details = flux.details
132
+
133
+ details[:documentation] = Documentation.build_from details
134
+
132
135
  details[:config][:incoming_split] = { type: 'text', shrink: true, description: 'Split an incoming event into multiple events by this key, an each event will be processed independently.', default: '' }
133
136
  details[:config][:outgoing_split] = { type: 'text', shrink: true, description: 'Split an outgoing event into multiple events by this key.', default: '' }
134
137
  details[:config][:merge] = { type: 'text', shrink: true, description: 'A comma-delimited list of fields from the event to carry through. Use * to merge all fields.', default: '' }
@@ -0,0 +1,37 @@
1
+ module Mushy
2
+ module Builder
3
+ module Documentation
4
+
5
+ def self.build_from config
6
+ basic_usage = "#{config[:description]}"
7
+ if config[:config]&.any?
8
+ rows = config[:config]
9
+ .map { |x| [x[0], x[1][:description], (x[1][:shrink] ? '(optional) ' : '')] }
10
+ .reduce("") { |t, i| "#{t}<tr><td>#{i[0]}</td><td>#{i[2]}#{i[1]}</td></tr>" }
11
+ basic_usage += '<table class="table is-bordered"><thead><tr><td>Field</td><td>Description</td></tr></thead>' + rows + "</table>"
12
+ end
13
+
14
+ {
15
+ "Basic Usage" => basic_usage,
16
+ }.tap do |documentation|
17
+ if config[:examples]
18
+ config[:examples].each do |item|
19
+ documentation[item[0]] = [
20
+ item[1][:description],
21
+ code_sample('Input', item[1][:input]),
22
+ code_sample('Config', item[1][:config]),
23
+ code_sample('Result', item[1][:result]),
24
+ ].select { |x| x }.reduce('') { |t, i| t + i }
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.code_sample title, value
31
+ return nil unless value
32
+ "<div><b>#{title}</b></div><pre><code>#{JSON.pretty_generate(value)}</code></pre>"
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -52,6 +52,49 @@ module Mushy
52
52
  <button v-on:click.prevent.stop="startNew({ setup: setup, configs: configs })" class="button is-link">Add a New Flux To This Flow</button>
53
53
  </div>
54
54
  </div>
55
+
56
+ <div v-bind:class="setup.fluxTypeSelect">
57
+ <div class="modal-background"></div>
58
+ <div class="modal-card">
59
+ <header class="modal-card-head">
60
+ <p class="modal-card-title">Flux Types</p>
61
+ <button class="delete" aria-label="close" v-on:click.prevent.stop="setup.fluxTypeSelect['is-active'] = false"></button>
62
+ </header>
63
+ <section class="modal-card-body">
64
+ <div class="content">
65
+ <div v-for="(fluxType, id) in fluxTypes">
66
+ <div class="level">
67
+ <div class="level-left"><h2>{{fluxType.title || fluxType.name}}</h2></div>
68
+ <div class="level-right">
69
+ <button class="button is-primary level-item" v-on:click.prevent.stop="setup.flux.value = fluxType.name;setup.fluxTypeSelect['is-active'] = false">
70
+ Select
71
+ </button>
72
+ <button class="button level-item" v-on:click.prevent.stop="fluxType.showDetails = true" v-if="fluxType['showDetails'] == false">
73
+ Open
74
+ </button>
75
+ <button class="button level-item" v-on:click.prevent.stop="fluxType.showDetails = false" v-if="fluxType['showDetails']">
76
+ Close
77
+ </button>
78
+ </div>
79
+ </div>
80
+
81
+ <div v-if="fluxType['showDetails']">
82
+ <div class="tabs">
83
+ <ul>
84
+ <li v-for="(a, b) in fluxType.documentation"><a v-on:click.prevent.stop="fluxType.detailsTab = b">{{b}}</a></li>
85
+ </ul>
86
+ </div>
87
+ <div v-for="(a, b) in fluxType.documentation" v-if="fluxType['detailsTab'] == b" v-html="a"></div>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </section>
92
+ <footer class="modal-card-foot">
93
+ <button class="button is-primary" v-on:click.prevent.stop="setup.fluxTypeSelect['is-active'] = false">Done</button>
94
+ </footer>
95
+ </div>
96
+ </div>
97
+
55
98
  <div class="column" v-if="setup.showFlux">
56
99
  <div class="columns">
57
100
  <div class="column is-half">
@@ -337,12 +380,18 @@ module Mushy
337
380
  fluxdata = fluxdata.data;
338
381
  flowdata = flowdata.data;
339
382
 
383
+ fluxdata.fluxs.map(function(x) {
384
+ x['showDetails'] = false;
385
+ x['detailsTab'] = Object.getOwnPropertyNames(x.documentation)[0];
386
+ } );
387
+
340
388
  var configs = {};
341
389
  fluxdata.fluxs.map(function(x){
342
390
  configs[x.name] = x.config;
343
391
  });
344
392
 
345
393
  var options = [''];
394
+ fluxTypesWithDetails = fluxdata.fluxs;
346
395
  fluxTypes = fluxdata.fluxs.map(function(x){ return x.name });
347
396
  for(var type in fluxTypes)
348
397
  options.push(fluxTypes[type]);
@@ -391,9 +440,18 @@ module Mushy
391
440
  "modal": true,
392
441
  "is-active": false,
393
442
  },
443
+ fluxTypeSelect: {
444
+ "modal": true,
445
+ "is-active": false,
446
+ },
394
447
  id: { type: 'hide', value: '' },
395
448
  name: { type: 'text', value: '' },
396
449
  flux: { type: 'select', value: fluxdata.fluxs[0].name, options: options},
450
+ open_flux: { type: 'button', name: 'Select a Flux', foghat: 'free', medium: 'hey', color: 'is-primary',
451
+ click: function() {
452
+ Vue.set(app.setup.fluxTypeSelect, 'is-active', true);
453
+ }
454
+ },
397
455
  parents: { type: 'selectmanyrecords', label: 'Receive Events From', value: '', options: flowdata.fluxs },
398
456
  };
399
457
 
@@ -507,6 +565,7 @@ module Mushy
507
565
  });
508
566
  },
509
567
  configs: configs,
568
+ fluxTypes: fluxTypesWithDetails,
510
569
  setup: setup,
511
570
  flux_name_for: function(ids, fluxes) {
512
571
  var fluxs = fluxes.filter(function(x){ return ids.includes(x.id) });
@@ -19,6 +19,28 @@ module Mushy
19
19
  value: '',
20
20
  },
21
21
  },
22
+ examples: {
23
+ "Successful Call" => {
24
+ description: 'This will run the ls command and return the full bash result.',
25
+ input: {
26
+ command: "ls",
27
+ },
28
+ result: {
29
+ "text": "bin\nblue_heart.png\nthe_output.txt\n",
30
+ "success": true,
31
+ "exit_code": 0
32
+ }
33
+ },
34
+ "Failed Call" => {
35
+ description: 'This is an example of what happens when the command fails.',
36
+ input: { command: 'rm file_that_does_not_exist.txt' },
37
+ result: {
38
+ "text": "",
39
+ "success": false,
40
+ "exit_code": 256
41
+ }
42
+ },
43
+ }
22
44
  }
23
45
  end
24
46
 
@@ -75,6 +75,124 @@ module Mushy
75
75
  value: '',
76
76
  },
77
77
  },
78
+ examples: {
79
+ "Successful Call" => {
80
+ description: 'This will open https://www.google.com and return the result.',
81
+ config: {
82
+ url: "https://www.google.com",
83
+ },
84
+ result: {
85
+ "url": "https://www.google.com/",
86
+ "status": 200,
87
+ "title": "Google",
88
+ "cookies": [
89
+ {
90
+ "name": "1P_JAR",
91
+ "value": "2021-10-06-12",
92
+ "domain": ".google.com",
93
+ "path": "/",
94
+ "expires": 1636117150.583117,
95
+ "size": 19,
96
+ "httpOnly": false,
97
+ "secure": true,
98
+ "session": false,
99
+ "sameSite": "None",
100
+ "priority": "Medium"
101
+ },
102
+ ],
103
+ "headers": {},
104
+ "time": 1.486214604,
105
+ "body": "<html itemscope=\"\" itemtype=\"http://schema.org/WebPage\" lang=\"en\">...</html>"
106
+ }
107
+ },
108
+ "Login To a Site" => {
109
+ description: 'This will open https://www.yoursitepleasethankyou.com, login using javascript, and then return the state of the browser after logging in.',
110
+ input: {
111
+ url: "https://www.yoursitepleasethankyou.com",
112
+ username: "MYUSERNAME",
113
+ password: "MYPASSWORD",
114
+ },
115
+ config: {
116
+ url: "{{url}}",
117
+ timeout: 10,
118
+ execute: "$('#username').val('{{username}}');
119
+ $('#next').click();
120
+ $('#password').val('{{password}}');
121
+ $('#login').click();"
122
+ },
123
+ result: {
124
+ "url": "https://yoursitepleasethankyou/",
125
+ "status": 200,
126
+ "title": "",
127
+ "cookies": [
128
+ {
129
+ "name": "session_id",
130
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
131
+ "domain": ".yoursitepleasethankyou",
132
+ "path": "/",
133
+ "expires": -1,
134
+ "size": 41,
135
+ "httpOnly": true,
136
+ "secure": true,
137
+ "session": true,
138
+ "sameSite": "Lax",
139
+ "priority": "Medium"
140
+ }
141
+ ],
142
+ "headers": {},
143
+ "time": 4.633920809,
144
+ "body": "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head>...</html>"
145
+ }
146
+ },
147
+ "Access a Page After Logging In" => {
148
+ description: 'This will open a page using cookies from the previous request. Note that the cookies came from another browser flux event.',
149
+ input: {
150
+ "url": "https://yoursitepleasethankyou/",
151
+ "cookies": [
152
+ {
153
+ "name": "session_id",
154
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
155
+ "domain": ".yoursitepleasethankyou",
156
+ "path": "/",
157
+ "expires": -1,
158
+ "size": 41,
159
+ "httpOnly": true,
160
+ "secure": true,
161
+ "session": true,
162
+ "sameSite": "Lax",
163
+ "priority": "Medium"
164
+ }
165
+ ],
166
+ },
167
+ config: {
168
+ url: "https://www.yoursitepleasethankyou.com/myaccount",
169
+ carry_cookies_from: "{{cookies}}"
170
+ },
171
+ result: {
172
+ "url": "https://yoursitepleasethankyou/",
173
+ "status": 200,
174
+ "title": "",
175
+ "cookies": [
176
+ {
177
+ "name": "session_id",
178
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
179
+ "domain": ".yoursitepleasethankyou",
180
+ "path": "/",
181
+ "expires": -1,
182
+ "size": 41,
183
+ "httpOnly": true,
184
+ "secure": true,
185
+ "session": true,
186
+ "sameSite": "Lax",
187
+ "priority": "Medium"
188
+ }
189
+ ],
190
+ "headers": {},
191
+ "time": 4.633920809,
192
+ "body": "<html><head></head>Your name is John Doe...</html>"
193
+ }
194
+ }
195
+ }
78
196
  }
79
197
  end
80
198
 
@@ -7,6 +7,7 @@ module Mushy
7
7
  def self.details
8
8
  {
9
9
  name: 'BuildCsv',
10
+ title: "Build CSV",
10
11
  description: 'Build a CSV.',
11
12
  config: {
12
13
  input_path: {
@@ -30,6 +31,27 @@ module Mushy
30
31
  value: true,
31
32
  },
32
33
  },
34
+ examples: {
35
+ "Build a Simple CSV" => {
36
+ description: 'Converts a set of records to a CSV.',
37
+ input: {
38
+ things: [
39
+ { name: "Apple", color:"Red" },
40
+ { name: "Banana", color: "Yellow" },
41
+ { name: "Pear", color: "Green" }
42
+ ]
43
+ },
44
+ config: {
45
+ input_path: "things",
46
+ output_path: "records",
47
+ headers: { name: "Name", color: "Color" },
48
+ header_row: true
49
+ },
50
+ result: {
51
+ records: "Name,Color\nApple,Red\nBanana,Yellow\nPear,Green\n"
52
+ }
53
+ },
54
+ }
33
55
  }
34
56
  end
35
57
 
@@ -5,9 +5,20 @@ module Mushy
5
5
  def self.details
6
6
  {
7
7
  name: 'Cli',
8
+ title: 'Command Line Interface',
8
9
  description: 'Accept CLI arguments from the run command.',
9
10
  config: {
10
11
  },
12
+ examples: {
13
+ "Calling From The Command Line" => {
14
+ description: 'Calling the CLI with command-line arguments.',
15
+ input: "mushy start file first:John last:Doe",
16
+ result: {
17
+ "first": "John",
18
+ "last": "Doe"
19
+ }
20
+ },
21
+ }
11
22
  }
12
23
  end
13
24
 
@@ -13,6 +13,20 @@ module Mushy
13
13
  value: '',
14
14
  },
15
15
  },
16
+ examples: {
17
+ "Example" => {
18
+ description: 'Using this Flux to build a document',
19
+ input: {
20
+ people: [ { name: "John" }, { name: "Jane" } ]
21
+ },
22
+ config: {
23
+ document: '{% for person in people %} {{ person.name }} {% endfor %}'
24
+ },
25
+ result: {
26
+ document: ' John Jane ',
27
+ }
28
+ },
29
+ }
16
30
  }
17
31
  end
18
32
 
@@ -20,6 +20,114 @@ module Mushy
20
20
  shrink: true,
21
21
  value: '',
22
22
  }
23
+ end.tap do |c|
24
+ c[:examples] = {
25
+ "Run In A Directory" => {
26
+ description: 'This will run the ls command in the specified directory.',
27
+ config: {
28
+ directory: '/home/pi/Desktop/mushy'
29
+ },
30
+ result: [{
31
+ inode: "416921",
32
+ hard_links: 1,
33
+ owner: "pi",
34
+ group: "pi",
35
+ size: 1270,
36
+ date: {
37
+ year: 2021,
38
+ month: 10,
39
+ day: 1,
40
+ hour: 10,
41
+ minute: 43,
42
+ second: 35,
43
+ nanosecond: 664409766,
44
+ utc_offset: -18000,
45
+ weekday: 5,
46
+ day_of_month: 1,
47
+ day_of_year: 274,
48
+ string: "2021-10-01 10:43:35 -0500",
49
+ epoch_integer: 1633103015,
50
+ epoch_float: 1633103015.6644099,
51
+ seconds_ago: 454725.436212074
52
+ },
53
+ name: "mushy.gemspec",
54
+ type: "-",
55
+ owner_permission: "rw-",
56
+ group_permission: "r--",
57
+ other_permission: "r--",
58
+ directory: "/home/pi/Desktop/mushy",
59
+ path: "/home/pi/Desktop/mushy/mushy.gemspec"
60
+ },
61
+ {
62
+ inode: "403479",
63
+ hard_links: 3,
64
+ owner: "pi",
65
+ group: "pi",
66
+ size: 4096,
67
+ date: {
68
+ year: 2021,
69
+ month: 3,
70
+ day: 18,
71
+ hour: 8,
72
+ minute: 58,
73
+ second: 51,
74
+ nanosecond: 149096220,
75
+ utc_offset: -18000,
76
+ weekday: 4,
77
+ day_of_month: 18,
78
+ day_of_year: 77,
79
+ string: "2021-03-18 08:58:51 -0500",
80
+ epoch_integer: 1616075931,
81
+ epoch_float: 1616075931.1490963,
82
+ seconds_ago: 17482042.0544623
83
+ },
84
+ name: "test",
85
+ type: "d",
86
+ owner_permission: "rwx",
87
+ group_permission: "r-x",
88
+ other_permission: "r-x",
89
+ directory: "test"
90
+ }
91
+ ]
92
+ },
93
+ "Run For a Specific File" => {
94
+ description: 'This will run the ls command in the specified directory.',
95
+ config: {
96
+ path: 'mushy.gemspec'
97
+ },
98
+ result: {
99
+ inode: "416921",
100
+ hard_links: 1,
101
+ owner: "pi",
102
+ group: "pi",
103
+ size: 1270,
104
+ date: {
105
+ year: 2021,
106
+ month: 10,
107
+ day: 1,
108
+ hour: 10,
109
+ minute: 43,
110
+ second: 35,
111
+ nanosecond: 664409766,
112
+ utc_offset: -18000,
113
+ weekday: 5,
114
+ day_of_month: 1,
115
+ day_of_year: 274,
116
+ string: "2021-10-01 10:43:35 -0500",
117
+ epoch_integer: 1633103015,
118
+ epoch_float: 1633103015.6644099,
119
+ seconds_ago: 454725.436212074
120
+ },
121
+ name: "mushy.gemspec",
122
+ type: "-",
123
+ owner_permission: "rw-",
124
+ group_permission: "r--",
125
+ other_permission: "r--",
126
+ directory: "/home/pi/Desktop/mushy",
127
+ path: "/home/pi/Desktop/mushy/mushy.gemspec"
128
+ }
129
+ }
130
+ }
23
131
  end
24
132
  end
25
133
 
@@ -129,6 +237,8 @@ module Mushy
129
237
  name_segments = result[:name].split "\/"
130
238
  result[:name] = name_segments.pop
131
239
  result[:directory] = name_segments.join "\/"
240
+ elsif result[:type] == 'd'
241
+ result[:directory] = result[:name]
132
242
  else
133
243
  result[:path] = File.join result[:directory], result[:name]
134
244
  end
@@ -7,7 +7,46 @@ module Mushy
7
7
  name: 'Pwd',
8
8
  description: 'Run the "pwd" command.',
9
9
  config: Mushy::Bash.details[:config].tap { |c| c.delete :command },
10
- }
10
+ }.tap do |c|
11
+ c[:examples] = {
12
+ "Example" => {
13
+ description: 'This will run the pwd command and return the directory information.',
14
+ result: {
15
+ pwd: {
16
+ inode: "403091",
17
+ hard_links: 5,
18
+ owner: "pi",
19
+ group: "pi",
20
+ size: 4095,
21
+ date: {
22
+ year: 2020,
23
+ month: 9,
24
+ day: 5,
25
+ hour: 10,
26
+ minute: 43,
27
+ second: 36,
28
+ nanosecond: 325720074,
29
+ utc_offset: -18001,
30
+ weekday: 2,
31
+ day_of_month: 5,
32
+ day_of_year: 278,
33
+ string: "2020-10-06 11:44:37 -0500",
34
+ epoch_integer: 1633538676,
35
+ epoch_float: 1633538676.32572,
36
+ seconds_ago: 17558.38995246
37
+ },
38
+ name: "mushy",
39
+ type: "d",
40
+ owner_permission: "rwx",
41
+ group_permission: "r-x",
42
+ other_permission: "r-x",
43
+ directory: "/home/pi/Desktop",
44
+ path: "/home/pi/Desktop/mushy"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ end
11
50
  end
12
51
 
13
52
  def process event, config
@@ -7,20 +7,33 @@ module Mushy
7
7
  def self.details
8
8
  {
9
9
  name: 'ReadJson',
10
+ title: 'Deserialize JSON',
10
11
  description: 'Read JSON and output it as an event.',
11
12
  config: {
12
- json: {
13
- description: 'The JSON contents that will be returned as an event.',
14
- type: 'text',
15
- value: 'json',
16
- },
13
+ key: {
14
+ description: 'The JSON contents that will be returned as an event.',
15
+ type: 'text',
16
+ value: 'json',
17
+ },
17
18
  },
19
+ examples: {
20
+ "Example" => {
21
+ description: 'Using this Flux to deserialize a JSON string.',
22
+ input: {
23
+ orange: "{\"people\":[{\"name\":\"John\"},{\"name\":\"Jane\"}]}"
24
+ },
25
+ config: {
26
+ key: 'orange'
27
+ },
28
+ result: { people: [ { name: "John" }, { name: "Jane" } ] }
29
+ },
30
+ }
18
31
  }
19
32
  end
20
33
 
21
34
  def process event, config
22
- return nil unless config[:json].to_s != ''
23
- JSON.parse config[:json]
35
+ return nil unless event[config[:key]].to_s != ''
36
+ JSON.parse event[config[:key]]
24
37
  end
25
38
 
26
39
  end
@@ -7,6 +7,7 @@ module Mushy
7
7
  def self.details
8
8
  {
9
9
  name: 'WriteJson',
10
+ title: 'Serialize as JSON',
10
11
  description: 'Write the incoming event as JSON.',
11
12
  config: {
12
13
  key: {
@@ -15,6 +16,20 @@ module Mushy
15
16
  value: 'json',
16
17
  },
17
18
  },
19
+ examples: {
20
+ "Example" => {
21
+ description: 'Using this Flux to convert input to a JSON string.',
22
+ input: {
23
+ people: [ { name: "John" }, { name: "Jane" } ]
24
+ },
25
+ config: {
26
+ key: 'apple'
27
+ },
28
+ result: {
29
+ apple: "{\"people\":[{\"name\":\"John\"},{\"name\":\"Jane\"}]}"
30
+ }
31
+ },
32
+ }
18
33
  }
19
34
  end
20
35
 
data/mushy.gemspec CHANGED
@@ -4,7 +4,7 @@ require 'mushy/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'mushy'
7
- s.version = '0.15.3'
7
+ s.version = '0.16.0'
8
8
  s.date = '2020-11-23'
9
9
  s.summary = 'Process streams of work using common modules.'
10
10
  s.description = 'This tool assists in the creation and processing of workflows.'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mushy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.3
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Cauthon
@@ -177,6 +177,7 @@ files:
177
177
  - lib/mushy/builder/axios.rb
178
178
  - lib/mushy/builder/bulma.rb
179
179
  - lib/mushy/builder/dark.rb
180
+ - lib/mushy/builder/documentation.rb
180
181
  - lib/mushy/builder/index.rb
181
182
  - lib/mushy/builder/vue.rb
182
183
  - lib/mushy/date_parts.rb