mushy 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mushy/builder/api.rb +8 -8
- data/lib/mushy/builder/index.rb +147 -82
- data/lib/mushy/flow.rb +3 -1
- data/lib/mushy/flux.rb +7 -6
- data/lib/mushy/fluxs/browser.rb +14 -1
- data/lib/mushy/fluxs/format.rb +19 -0
- data/mushy.gemspec +4 -2
- metadata +30 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b0ff90e9b20233f5744ec73d94137a2a117dc5bbdcb1962242caf5d3fdec8f3
|
4
|
+
data.tar.gz: dd834f5294cf131393881c7647a25c27d54275e7c510c2b19bac233b9193be43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41b4cdfd6d24547838ba11b0bbdb3515ec8baee305ab5b97079d040019951354d29074d9a93c88cf94be9b70c0875220f3b76630097c9cc697ddf4ea4cef550f
|
7
|
+
data.tar.gz: 1ec8aab8a0ac9281d1ed036b84add01be639c6223ef46db6f7132d4140f09c10d2ea0a6707bca99aa79b3db024efa2f4cf34ce5430c68e8838953be21f125dd2
|
data/lib/mushy/builder/api.rb
CHANGED
@@ -40,14 +40,14 @@ module Mushy
|
|
40
40
|
{
|
41
41
|
fluxs: Mushy::Flux.all.select { |x| x.respond_to? :details }.map do |flux|
|
42
42
|
details = flux.details
|
43
|
-
details[:config][:incoming_split] = { type: 'text', description: 'Split an incoming event into multiple events by this key, an each event will be processed independently.', default: '' }
|
44
|
-
details[:config][:outgoing_split] = { type: 'text', description: 'Split an outgoing event into multiple events by this key.', default: '' }
|
45
|
-
details[:config][:merge] = { type: 'text', description: 'A comma-delimited list of fields from the event to carry through. Use * to merge all fields.', default: '' }
|
46
|
-
details[:config][:group] = { type: 'text', description: 'Group events by a field, which is stored in a key. The format is group_by|group_key.', default: '' }
|
47
|
-
details[:config][:limit] = { type: 'integer', description: 'Limit the number of events to this number.', default: '' }
|
48
|
-
details[:config][:join] = { type: 'text', description: 'Join all of the events from this flux into one event, under this name.', default: '' }
|
49
|
-
details[:config][:sort] = { type: 'text', description: 'Sort by this key.', default: '' }
|
50
|
-
details[:config][:model] = { type: 'keyvalue', description: 'Reshape the outgoing events.', value: {}, default: {} }
|
43
|
+
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: '' }
|
44
|
+
details[:config][:outgoing_split] = { type: 'text', shrink: true, description: 'Split an outgoing event into multiple events by this key.', default: '' }
|
45
|
+
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: '' }
|
46
|
+
details[:config][:group] = { type: 'text', shrink: true, description: 'Group events by a field, which is stored in a key. The format is group_by|group_key.', default: '' }
|
47
|
+
details[:config][:limit] = { type: 'integer', shrink: true, description: 'Limit the number of events to this number.', default: '' }
|
48
|
+
details[:config][:join] = { type: 'text', shrink: true, description: 'Join all of the events from this flux into one event, under this name.', default: '' }
|
49
|
+
details[:config][:sort] = { type: 'text', shrink: true, description: 'Sort by this key.', default: '' }
|
50
|
+
details[:config][:model] = { type: 'keyvalue', shrink: true, description: 'Reshape the outgoing events.', value: {}, default: {} }
|
51
51
|
|
52
52
|
details[:config]
|
53
53
|
.select { |_, v| v[:type] == 'keyvalue' }
|
data/lib/mushy/builder/index.rb
CHANGED
@@ -12,19 +12,28 @@ module Mushy
|
|
12
12
|
</head>
|
13
13
|
<body>
|
14
14
|
<div id="app">
|
15
|
-
<table>
|
15
|
+
<table v-if="setup.showFlux == false">
|
16
|
+
<tr>
|
17
|
+
<th>Name</th>
|
18
|
+
<th>Receives Events From</th>
|
19
|
+
<th>Actions</th>
|
20
|
+
</tr>
|
16
21
|
<tr v-for="flux in flow.fluxs">
|
17
22
|
<td>{{flux.name}}</td>
|
18
|
-
<td>{{flux.
|
19
|
-
<td
|
23
|
+
<td>{{flux_name_for(flux.parent, flow.fluxs)}}</td>
|
24
|
+
<td>
|
25
|
+
<button v-on:click.prevent.stop="editFlux({ flux: flux, setup: setup, configs: configs })">Edit</button>
|
26
|
+
<button v-on:click.prevent.stop="deleteFlux({ flux: flux, flow: flow })">Delete</button>
|
27
|
+
</td>
|
20
28
|
</tr>
|
21
29
|
</table>
|
22
|
-
<
|
23
|
-
<
|
24
|
-
<
|
30
|
+
<button v-if="setup.showFlux == false" v-on:click.prevent.stop="startNew({ setup: setup, configs: configs })">Start a New Flux</button>
|
31
|
+
<button v-if="setup.showFlux == false" v-on:click.prevent.stop="saveFlow({ setup: setup, flow: flow })">Save This Flow</button>
|
32
|
+
<button v-if="setup.showFlux" v-on:click.prevent.stop="setup.showFlux = false">< Go Back To List</button>
|
33
|
+
<div v-if="setup.showFlux">
|
25
34
|
<mip-heavy :data="setup"></mip-heavy>
|
26
35
|
<mip-heavy v-for="(data, id) in configs" v-show="setup.flux.value === id" :data="data"></mip-heavy>
|
27
|
-
<div v-if="results.
|
36
|
+
<div v-if="results.errorMessage">{{results.errorMessage}}</div>
|
28
37
|
<div v-else>{{results.length}} result{{results.length == 1 ? "" : "s"}}</div>
|
29
38
|
<mip-heavy v-for="data in results" :data="data"></mip-heavy>
|
30
39
|
</div>
|
@@ -48,28 +57,48 @@ module Mushy
|
|
48
57
|
|
49
58
|
var components = {
|
50
59
|
label: {
|
51
|
-
props: ['label', 'description'],
|
52
|
-
template: '<label :for="id" v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description">({{description}})</i></label>'
|
60
|
+
props: ['label', 'description', 'hide_description'],
|
61
|
+
template: '<label :for="id" v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></label>'
|
62
|
+
},
|
63
|
+
h1: {
|
64
|
+
props: ['label', 'description', 'hide_description'],
|
65
|
+
template: '<h1 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h1>'
|
66
|
+
},
|
67
|
+
h2: {
|
68
|
+
props: ['label', 'description', 'hide_description'],
|
69
|
+
template: '<h2 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h2>'
|
70
|
+
},
|
71
|
+
h3: {
|
72
|
+
props: ['label', 'description', 'hide_description'],
|
73
|
+
template: '<h3 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h3>'
|
74
|
+
},
|
75
|
+
h4: {
|
76
|
+
props: ['label', 'description', 'hide_description'],
|
77
|
+
template: '<h4 v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></h4>'
|
53
78
|
},
|
54
79
|
text: {
|
55
|
-
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description'],
|
56
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><input type="text" :name="id" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
80
|
+
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
81
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
82
|
+
},
|
83
|
+
hide: {
|
84
|
+
props: ['label', 'description'],
|
85
|
+
template: '<mip-label :id="id" :label="label" :description="description" v-if="false"></mip-label>'
|
57
86
|
},
|
58
87
|
integer: {
|
59
|
-
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description'],
|
60
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><input type="text" :name="id" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
88
|
+
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
89
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
61
90
|
},
|
62
91
|
email: {
|
63
|
-
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description'],
|
64
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><input type="email" :name="id" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
92
|
+
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
93
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><input type="email" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></div>'
|
65
94
|
},
|
66
95
|
textarea: {
|
67
|
-
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description'],
|
68
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><textarea :name="id" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></textarea></div>'
|
96
|
+
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
97
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></textarea></div>'
|
69
98
|
},
|
70
99
|
json: {
|
71
|
-
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description'],
|
72
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label
|
100
|
+
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
101
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'"></textarea></div>'
|
73
102
|
},
|
74
103
|
jsonview: {
|
75
104
|
data: function() {
|
@@ -80,19 +109,23 @@ module Mushy
|
|
80
109
|
};
|
81
110
|
},
|
82
111
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'view'],
|
83
|
-
template: '<div><mip-
|
112
|
+
template: '<div><mip-h4 :id="id" :label="label" :description="description"></mip-h4> <pre><code>{{show(view, value)}}</code></pre><button :disabled="view==\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">{{(view == \\'beautiful\\' ? \\'View Smaller\\' : \\'View Pretty\\')}}</button><button :disabled="view!=\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">View Smaller</button><button v-on:click.prevent.stop="copy(view, value)">Copy</button></div>'
|
84
113
|
},
|
85
114
|
radio: {
|
86
|
-
props: ['label', 'value', 'options', 'description'],
|
87
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><div v-for="option in options"><input type="radio" :name="id" v-bind:value="option" v-on:input="$emit(\\'update:value\\', $event.target.value)" :checked="value == option"> <label for="option">{{option}}</label></div></div>'
|
115
|
+
props: ['label', 'value', 'options', 'description', 'shrink'],
|
116
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div v-for="option in options"><input type="radio" :name="id" v-bind:value="option" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" :checked="value == option"> <label for="option">{{option}}</label></div></div>'
|
88
117
|
},
|
89
118
|
select: {
|
90
|
-
props: ['label', 'value', 'options', 'description'],
|
91
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><select :name="id" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
119
|
+
props: ['label', 'value', 'options', 'description', 'shrink'],
|
120
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
121
|
+
},
|
122
|
+
selectrecord: {
|
123
|
+
props: ['label', 'value', 'options', 'description', 'shrink'],
|
124
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option.id" :selected="value == option.id">{{option.name}}</option></select></div>'
|
92
125
|
},
|
93
126
|
boolean: {
|
94
|
-
props: ['label', 'value', 'options', 'description'],
|
95
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><select :name="id" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
127
|
+
props: ['label', 'value', 'options', 'description', 'shrink'],
|
128
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="(value != undefined && value != null && value != \\'\\') || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
96
129
|
},
|
97
130
|
table: {
|
98
131
|
props: ['value', 'description'],
|
@@ -113,12 +146,13 @@ module Mushy
|
|
113
146
|
}
|
114
147
|
};
|
115
148
|
},
|
116
|
-
props: ['value', 'editors', 'label', 'description'],
|
117
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><table><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="(v, z) in value"><td v-for="(d, i) in v">{{d}}</td><td><a href="#" v-on:click.prevent.stop="removeRecord(v, value, z)">[x]</a></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><a href="#" v-on:click.prevent.stop="addRecord(editors, value)">[Add]</a></td></tr></table></div>'
|
149
|
+
props: ['value', 'editors', 'label', 'description', 'shrink'],
|
150
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && value.length == 0">[^]</a><table v-if="value.length > 0 || !shrink"><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="(v, z) in value"><td v-for="(d, i) in v">{{d}}</td><td><a href="#" v-on:click.prevent.stop="removeRecord(v, value, z)">[x]</a></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><a href="#" v-on:click.prevent.stop="addRecord(editors, value)">[Add]</a></td></tr></table></div>'
|
118
151
|
},
|
119
152
|
keyvalue: {
|
120
153
|
data: function() {
|
121
154
|
return {
|
155
|
+
actionText: function(value, others) { found = false; for(var i in others){ if (i == value) found = true; } return found ? 'Replace' : 'Add'; },
|
122
156
|
removeRecord: function(data, key) { Vue.delete(data, key) },
|
123
157
|
addRecord: function(editors, data) {
|
124
158
|
Vue.set(data, editors[0].field.value, editors[1].field.value)
|
@@ -127,12 +161,12 @@ module Mushy
|
|
127
161
|
}
|
128
162
|
};
|
129
163
|
},
|
130
|
-
props: ['value', 'label', 'editors', 'description'],
|
131
|
-
template: '<div><mip-label :id="id" :label="label" :description="description"></mip-label><table><tr v-for="(v, k) in value"><td>{{k}}</td><td>{{v}}</td><td><
|
164
|
+
props: ['value', 'label', 'editors', 'description', 'shrink'],
|
165
|
+
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink">[^]</a><table v-if="JSON.stringify(value) != \\'{}\\' || !shrink"><tr v-for="(v, k) in value"><td>{{k}}</td><td>{{v}}</td><td><button v-on:click.prevent.stop="removeRecord(value, k)">Remove {{k}}</button></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><button v-on:click.prevent.stop="addRecord(editors, value)" v-show="editors[0].field.value">{{actionText(editors[0].field.value, value)}} {{editors[0].field.value}}</button></td></tr></table></div>'
|
132
166
|
},
|
133
167
|
button: {
|
134
|
-
props: ['click', 'description'],
|
135
|
-
template: '<button v-on:click.prevent.stop="click(pull(this))">{{id}}</button>'
|
168
|
+
props: ['click', 'description', 'name'],
|
169
|
+
template: '<button v-on:click.prevent.stop="click(pull(this), thisComponent())">{{name || id}}</button>'
|
136
170
|
}
|
137
171
|
};
|
138
172
|
|
@@ -152,6 +186,7 @@ module Mushy
|
|
152
186
|
return {
|
153
187
|
console: console,
|
154
188
|
pull: function(x) { return thingToData(foundIt.data); },
|
189
|
+
thisComponent: function() { return foundIt.data; },
|
155
190
|
}
|
156
191
|
},
|
157
192
|
props: props,
|
@@ -184,32 +219,6 @@ module Mushy
|
|
184
219
|
template: '<div><mip-thing v-for="(d, id) in data" :data="d" :id="id"></mip-thing></div>',
|
185
220
|
});
|
186
221
|
|
187
|
-
var sample = {
|
188
|
-
email: { type: 'email', value: 'darren@cauthon.com' },
|
189
|
-
first_name: { type: 'text', value: 'Darren' },
|
190
|
-
description: { type: 'textarea', value: 'more data' },
|
191
|
-
size: { type: 'select', value: 'medium', options: ['small', 'medium', 'large']},
|
192
|
-
heynow: { type: 'keyvalue',
|
193
|
-
value: {
|
194
|
-
first_name: 'John',
|
195
|
-
last_name: 'Doe',
|
196
|
-
},
|
197
|
-
editors: [
|
198
|
-
{ id: 'new_key', target: 'key', field: { type: 'text', value: '', default: '' } },
|
199
|
-
{ id: 'new_value', target: 'value', field: { type: 'text', value: '', default: '' } }
|
200
|
-
] },
|
201
|
-
past: { type: 'editgrid',
|
202
|
-
value: [
|
203
|
-
{ name: 'Godzilla', quantity: 1 },
|
204
|
-
{ name: 'Mothra', quantity: 2 },
|
205
|
-
],
|
206
|
-
editors: [
|
207
|
-
{ id: 'new_name', target: 'name', field: { type: 'text', value: '', default: '' } },
|
208
|
-
{ id: 'new_quantity', target: 'quantity', field: { type: 'select', value: '1', options: [1, 2, 3], default: 1 } }
|
209
|
-
] },
|
210
|
-
super_action: { type: 'button', click: function(x) { console.log(x) } },
|
211
|
-
};
|
212
|
-
|
213
222
|
var app = null;
|
214
223
|
|
215
224
|
axios.get('/fluxs')
|
@@ -232,31 +241,25 @@ module Mushy
|
|
232
241
|
options.push(fluxTypes[type]);
|
233
242
|
|
234
243
|
var setup = {
|
235
|
-
|
236
|
-
id: { type: '
|
244
|
+
showFlux: false,
|
245
|
+
id: { type: 'hide', value: '' },
|
237
246
|
name: { type: 'text', value: '' },
|
238
247
|
flux: { type: 'select', value: fluxdata.fluxs[0].name, options: options},
|
248
|
+
parent: { type: 'selectrecord', label: 'Receive Events From', value: '', options: flowdata.fluxs },
|
239
249
|
};
|
240
250
|
|
241
251
|
for (var key in configs)
|
242
252
|
{
|
243
|
-
configs[key].
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
.then(function(r){
|
248
|
-
Vue.set(app.results, 'loading', false);
|
249
|
-
for (var key in r.data.result)
|
250
|
-
app.results.push({darren: { type:'jsonview', value: r.data.result[key], view: 'thin' }});
|
251
|
-
});
|
252
|
-
} };
|
253
|
-
|
254
|
-
configs[key].save = { type: 'button', click: function(config) {
|
253
|
+
configs[key].save = { type: 'button', name: 'Save This Flux', click: function(config, hey) {
|
254
|
+
var nameOfTheSaveButton = hey.save.name;
|
255
|
+
Vue.set(hey.save, 'name', 'Saving');
|
256
|
+
delete config.test_event;
|
255
257
|
var setup = thingToData(app.setup);
|
256
258
|
var flux = {
|
257
259
|
id: setup.id,
|
258
260
|
name: setup.name,
|
259
261
|
flux: setup.flux,
|
262
|
+
parent: setup.parent,
|
260
263
|
config: config,
|
261
264
|
};
|
262
265
|
var index = -1;
|
@@ -268,16 +271,53 @@ module Mushy
|
|
268
271
|
else
|
269
272
|
app.flow.fluxs[index] = flux;
|
270
273
|
|
271
|
-
|
274
|
+
setTimeout(function(){
|
275
|
+
Vue.set(hey.save, 'name', nameOfTheSaveButton);
|
276
|
+
app.setup.id.value = '';
|
277
|
+
|
278
|
+
Vue.set(app.setup, 'showFlux', false);
|
279
|
+
}, 500);
|
272
280
|
}
|
273
281
|
};
|
282
|
+
|
283
|
+
configs[key].test_event = { type: 'json', value: '{}', default: '{}' };
|
284
|
+
|
285
|
+
configs[key].run_test = { type: 'button', name: 'Test Run This Flux', click: function(c, hey) {
|
286
|
+
var previousName = hey.run_test.name;
|
287
|
+
Vue.set(hey.run_test, 'name', 'Loading');
|
288
|
+
app.results = [];
|
289
|
+
Vue.set(app.results, 'errorMessage', '');
|
290
|
+
var the_setup = thingToData(app.setup);
|
291
|
+
the_setup.event = c.test_event;
|
292
|
+
axios.post('/run', { config: c, setup: the_setup })
|
293
|
+
.then(function(r){
|
294
|
+
var index = 1;
|
295
|
+
for (var key in r.data.result)
|
296
|
+
{
|
297
|
+
var result = {};
|
298
|
+
result['event_' + index] = { type: 'jsonview', label: 'Event ' + index + ' of ' + r.data.result.length, value: r.data.result[key], view: 'thin' };
|
299
|
+
app.results.push(result);
|
300
|
+
index += 1;
|
301
|
+
}
|
302
|
+
}).catch(function(r){
|
303
|
+
console.log(r);
|
304
|
+
Vue.set(app.results, 'errorMessage', 'This app failed while trying to execute your flux.');
|
305
|
+
}).then(function(){
|
306
|
+
Vue.set(hey.run_test, 'name', previousName);
|
307
|
+
});
|
308
|
+
} };
|
274
309
|
}
|
275
310
|
|
276
|
-
var loadThisFlux = function(
|
311
|
+
var loadThisFlux = function(args)
|
277
312
|
{
|
313
|
+
var flux = args.flux;
|
314
|
+
var setup = args.setup;
|
315
|
+
var config = args.config;
|
316
|
+
|
278
317
|
Vue.set(setup.id, 'value', flux.id);
|
279
318
|
Vue.set(setup.name, 'value', flux.name);
|
280
319
|
Vue.set(setup.flux, 'value', flux.flux);
|
320
|
+
Vue.set(setup.parent, 'value', flux.parent);
|
281
321
|
|
282
322
|
var applicable_config = configs[flux.flux];
|
283
323
|
for(var key in applicable_config)
|
@@ -285,35 +325,60 @@ module Mushy
|
|
285
325
|
Vue.set(applicable_config[key], 'value', flux.config[key]);
|
286
326
|
else
|
287
327
|
Vue.set(applicable_config[key], 'value', applicable_config[key].default);
|
328
|
+
|
329
|
+
if (applicable_config)
|
330
|
+
Vue.set(applicable_config.test_event, 'value', '{}');
|
331
|
+
|
332
|
+
options = flowdata.fluxs.filter(function(x){ return x.id != flux.id });
|
333
|
+
options.unshift( { id: '', name: '' } );
|
334
|
+
setup.parent.options = options;
|
335
|
+
|
336
|
+
Vue.set(setup, 'showFlux', true);
|
337
|
+
app.results = [];
|
288
338
|
};
|
289
339
|
|
340
|
+
function uuidv4() {
|
341
|
+
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
342
|
+
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
343
|
+
);
|
344
|
+
}
|
345
|
+
|
290
346
|
app = new Vue({
|
291
347
|
el: '#app',
|
292
348
|
data: {
|
293
349
|
flow: flowdata,
|
294
350
|
startNew: function(x) {
|
295
351
|
flux = {
|
296
|
-
id:
|
297
|
-
name: '
|
352
|
+
id: uuidv4(),
|
353
|
+
name: '',
|
298
354
|
config: {}
|
299
355
|
};
|
300
|
-
loadThisFlux(flux, x.setup, x.configs);
|
356
|
+
loadThisFlux({ flux: flux, setup: x.setup, configs: x.configs });
|
301
357
|
},
|
302
|
-
|
358
|
+
editFlux: function(x) {
|
303
359
|
var flux = x.flux;
|
304
360
|
|
305
|
-
loadThisFlux(x.flux, x.setup, x.configs);
|
361
|
+
loadThisFlux({ flux: x.flux, setup: x.setup, configs: x.configs });
|
306
362
|
},
|
307
|
-
|
363
|
+
deleteFlux: function(x) {
|
364
|
+
var set = x.flow.fluxs.filter( function(v){ return v.id != x.flux.id } );
|
365
|
+
Vue.set(x.flow, 'fluxs', set);
|
366
|
+
},
|
367
|
+
saveFlow: function(input)
|
308
368
|
{
|
309
|
-
|
369
|
+
var setup = input.setup;
|
370
|
+
var flow = input.flow;
|
310
371
|
axios.post('/save', flow)
|
311
372
|
.then(function(result){
|
312
|
-
|
373
|
+
Vue.set(setup, 'showFlux', false);
|
313
374
|
});
|
314
375
|
},
|
315
376
|
configs: configs,
|
316
377
|
setup: setup,
|
378
|
+
flux_name_for: function(id, fluxes) {
|
379
|
+
var flux = fluxes.filter(function(x){ return x.id == id })[0];
|
380
|
+
return flux != undefined ? flux.name : '';
|
381
|
+
},
|
317
382
|
results: [],
|
318
383
|
}
|
319
384
|
});
|
data/lib/mushy/flow.rb
CHANGED
@@ -26,9 +26,11 @@ module Mushy
|
|
26
26
|
|
27
27
|
def self.parse data
|
28
28
|
data = JSON.parse data
|
29
|
-
flow = new
|
30
29
|
|
31
30
|
data_fluxs = data['fluxs'] || []
|
31
|
+
data_fluxs.select { |x| x['parent'] }.map { |r| r["parent_fluxs"] = [r["parent"]] }
|
32
|
+
|
33
|
+
flow = new
|
32
34
|
|
33
35
|
flow.fluxs = data_fluxs.map { |s| build_flux s }
|
34
36
|
|
data/lib/mushy/flux.rb
CHANGED
@@ -40,17 +40,18 @@ module Mushy
|
|
40
40
|
|
41
41
|
event = incoming_event
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
incoming_split = masher.mash(config, event)[:incoming_split]
|
44
|
+
config_considering_an_imcoming_split = config
|
45
|
+
.reject { |x, _| incoming_split && x.to_s == 'join' }
|
46
|
+
.reduce({}) { |t, i| t[i[0]] = i[1]; t }
|
46
47
|
|
47
48
|
events = incoming_split ? incoming_event[incoming_split] : [event]
|
48
49
|
|
49
|
-
results = events.map { |e| execute_single_event e,
|
50
|
+
results = events.map { |e| execute_single_event e, config_considering_an_imcoming_split }
|
50
51
|
|
51
52
|
return results.first unless incoming_split
|
52
53
|
|
53
|
-
results = join_these_results(results, event, config[:join]) if config[:join]
|
54
|
+
results = join_these_results([results].flatten, event, config[:join]) if config[:join]
|
54
55
|
|
55
56
|
results.flatten
|
56
57
|
end
|
@@ -67,7 +68,7 @@ module Mushy
|
|
67
68
|
returned_one_result = results.is_a?(Hash)
|
68
69
|
|
69
70
|
results = standardize_these results
|
70
|
-
results = shape_these results, event,
|
71
|
+
results = shape_these results, event, config
|
71
72
|
|
72
73
|
return results.first if the_original_join
|
73
74
|
|
data/lib/mushy/fluxs/browser.rb
CHANGED
@@ -17,16 +17,19 @@ module Mushy
|
|
17
17
|
headless: {
|
18
18
|
description: 'Run this browser headless.',
|
19
19
|
type: 'boolean',
|
20
|
+
shrink: true,
|
20
21
|
value: 'true',
|
21
22
|
},
|
22
23
|
execute: {
|
23
24
|
description: 'Javascript to run after the page is loaded.',
|
24
25
|
type: 'textarea',
|
26
|
+
shrink: true,
|
25
27
|
value: '',
|
26
28
|
},
|
27
29
|
cookies: {
|
28
30
|
description: 'Cookies for the web request. These can be received from a previous browser event with {{cookies}}, or can be typed manually.',
|
29
31
|
type: 'editgrid',
|
32
|
+
shrink: true,
|
30
33
|
value: [],
|
31
34
|
editors: [
|
32
35
|
{ id: 'name', target: 'name', field: { type: 'text', value: '', default: '' } },
|
@@ -40,23 +43,31 @@ module Mushy
|
|
40
43
|
{ id: 'sameSite', target: 'sameSite', field: { type: 'text', value: 'None', default: 'None' } },
|
41
44
|
{ id: 'priority', target: 'priority', field: { type: 'text', value: 'Medium', default: 'Medium' } },
|
42
45
|
],
|
43
|
-
#{"name":"1P_JAR","value":"2021-01-21-13","domain":".google.com","path":"/","expires":1613828458.870408,"size":19,"httpOnly":false,"secure":true,"session":false,"sameSite":"None","priority":"Medium"
|
44
46
|
},
|
45
47
|
carry_cookies_from: {
|
46
48
|
description: 'Carry the cookies from this path in the event.',
|
47
49
|
type: 'text',
|
50
|
+
shrink: true,
|
48
51
|
value: 'cookies',
|
49
52
|
},
|
50
53
|
headers: {
|
51
54
|
description: 'Headers for the web request. These can be received from a previous browser event with {{headers}}, or can be typed manually.',
|
52
55
|
type: 'keyvalue',
|
56
|
+
shrink: true,
|
53
57
|
value: {},
|
54
58
|
},
|
55
59
|
carry_headers_from: {
|
56
60
|
description: 'Carry the headers from this path in the event.',
|
57
61
|
type: 'text',
|
62
|
+
shrink: true,
|
58
63
|
value: 'headers',
|
59
64
|
},
|
65
|
+
wait_before_closing: {
|
66
|
+
description: 'Wait this many seconds before closing the browser.',
|
67
|
+
type: 'integer',
|
68
|
+
shrink: true,
|
69
|
+
value: '',
|
70
|
+
},
|
60
71
|
},
|
61
72
|
}
|
62
73
|
end
|
@@ -73,6 +84,8 @@ module Mushy
|
|
73
84
|
|
74
85
|
browser.execute(config[:execute]) if config[:execute]
|
75
86
|
|
87
|
+
sleep(config[:wait_before_closing].to_i) if config[:wait_before_closing] && config[:wait_before_closing].to_i > 0
|
88
|
+
|
76
89
|
result = {
|
77
90
|
url: browser.url,
|
78
91
|
cookies: browser.cookies.all.map { |k, v| v.instance_variable_get('@attributes') },
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Mushy
|
2
|
+
|
3
|
+
class Format < Flux
|
4
|
+
|
5
|
+
def self.details
|
6
|
+
{
|
7
|
+
name: 'Format',
|
8
|
+
description: 'Return the event passed to it. This opens the opportunity to further alter results.',
|
9
|
+
config: {},
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def process event, config
|
14
|
+
event
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
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.0
|
7
|
+
s.version = '0.1.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.'
|
@@ -17,9 +17,11 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.license = 'MIT'
|
18
18
|
|
19
19
|
s.add_development_dependency 'minitest'
|
20
|
+
s.add_runtime_dependency 'sinatra'
|
21
|
+
s.add_runtime_dependency 'symbolized'
|
20
22
|
s.add_runtime_dependency 'thor'
|
21
23
|
s.add_runtime_dependency 'liquid'
|
22
24
|
s.add_runtime_dependency 'ferrum'
|
23
25
|
s.add_runtime_dependency 'nokogiri'
|
24
26
|
s.add_runtime_dependency 'faraday'
|
25
|
-
end
|
27
|
+
end
|
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.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darren Cauthon
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sinatra
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: symbolized
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: thor
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,6 +144,7 @@ files:
|
|
116
144
|
- lib/mushy/fluxs/build_csv.rb
|
117
145
|
- lib/mushy/fluxs/collection.rb
|
118
146
|
- lib/mushy/fluxs/filter.rb
|
147
|
+
- lib/mushy/fluxs/format.rb
|
119
148
|
- lib/mushy/fluxs/get.rb
|
120
149
|
- lib/mushy/fluxs/ls.rb
|
121
150
|
- lib/mushy/fluxs/parse_html.rb
|