gloo 3.1.0 → 3.2.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.
@@ -13,6 +13,8 @@ module Gloo
13
13
  KEYWORD_SHORT = 'tbl'.freeze
14
14
  HEADERS = 'headers'.freeze
15
15
  DATA = 'data'.freeze
16
+ CELLS = 'cells'.freeze
17
+ STYLES = 'styles'.freeze
16
18
 
17
19
  #
18
20
  # The name of the object type.
@@ -58,12 +60,64 @@ module Gloo
58
60
  return [] unless o
59
61
 
60
62
  o = Gloo::Objs::Alias.resolve_alias( @engine, o )
61
- cols = self.columns
62
- return o.children.map do |e|
63
- cols.map { |h| e.find_child( h ).value }
63
+
64
+ if o.is_a? Gloo::Objs::Query
65
+ @engine.log.debug "Table getting data from query."
66
+ begin
67
+ result = o.run_query
68
+ return result
69
+ rescue => e
70
+ @engine.err e.message
71
+ return nil
72
+ end
73
+ else
74
+ cols = self.columns
75
+
76
+ if o.children&.first.children.empty?
77
+ # It is a simgle row table.
78
+ rows = [ cols.map { |h| o.find_child( h )&.value } ]
79
+ else
80
+ rows = o.children.map do |e|
81
+ cols.map { |h| e.find_child( h )&.value }
82
+ end
83
+ end
84
+
85
+ return [ cols, rows ]
64
86
  end
65
87
  end
66
88
 
89
+ #
90
+ # Get the styles for the table, if any.
91
+ #
92
+ def styles
93
+ style_h = {}
94
+ o = find_child STYLES
95
+ return style_h unless o
96
+ o = Gloo::Objs::Alias.resolve_alias( @engine, o )
97
+
98
+ o.children.each do |c|
99
+ style_h[ c.name ] = c.value
100
+ end
101
+
102
+ return style_h
103
+ end
104
+
105
+ #
106
+ # Get cell renderer hash keyed by column name.
107
+ #
108
+ def cell_renderers
109
+ h = {}
110
+ o = find_child CELLS
111
+ return h unless o
112
+
113
+ o.children.each do |c|
114
+ h[ c.name ] = c.value
115
+ end
116
+
117
+ return h
118
+ end
119
+
120
+
67
121
  # ---------------------------------------------------------------------
68
122
  # Children
69
123
  # ---------------------------------------------------------------------
@@ -88,6 +142,7 @@ module Gloo
88
142
  fac.create_can DATA, self
89
143
  end
90
144
 
145
+
91
146
  # ---------------------------------------------------------------------
92
147
  # Messages
93
148
  # ---------------------------------------------------------------------
@@ -96,7 +151,7 @@ module Gloo
96
151
  # Get a list of message names that this object receives.
97
152
  #
98
153
  def self.messages
99
- return super + %w[show]
154
+ return super + %w[show render]
100
155
  end
101
156
 
102
157
  #
@@ -107,6 +162,90 @@ module Gloo
107
162
  @engine.platform.show_table headers, data, title
108
163
  end
109
164
 
165
+ def msg_render
166
+ return render
167
+ end
168
+
169
+
170
+ # ---------------------------------------------------------------------
171
+ # Render
172
+ # ---------------------------------------------------------------------
173
+
174
+ #
175
+ # Render the table.
176
+ # The render_ƒ is 'render_html', 'render_text', 'render_json', etc.
177
+ #
178
+ def render render_ƒ
179
+ begin
180
+ result = self.data
181
+ head = self.headers
182
+ head = result[0] if head.empty?
183
+ rows = result[1]
184
+
185
+ columns = build_columns result[0]
186
+
187
+ params = {
188
+ head: head,
189
+ cols: result[0],
190
+ columns: columns,
191
+ rows: rows,
192
+ styles: self.styles,
193
+ cell_renderers: self.cell_renderers
194
+ }
195
+
196
+ helper = Gloo::WebSvr::TableRenderer.new( @engine )
197
+ return helper.data_to_table params
198
+ rescue => e
199
+ @engine.err e.message
200
+ return nil
201
+ end
202
+ end
203
+
204
+ #
205
+ # Build the column list based on the result data and
206
+ # the headers defined in the table object.
207
+ #
208
+ def build_columns result_data
209
+ head_children = find_child HEADERS
210
+ cell_renderers = find_child CELLS
211
+
212
+ columns = []
213
+ return columns unless result_data
214
+
215
+ result_data.each_with_index do |c,index|
216
+ visible = true
217
+ name = c
218
+ title = c
219
+ display_index = index
220
+
221
+ if head_children
222
+ child = head_children.find_child c
223
+ if child
224
+ title = child.value
225
+ display_index = head_children.child_index( c )
226
+ else
227
+ visible = false
228
+ end
229
+ end
230
+
231
+ cell_renderer = nil
232
+ if cell_renderers
233
+ this_cr = cell_renderers.find_child( c )
234
+ cell_renderer = this_cr.value if this_cr
235
+ end
236
+
237
+ columns << {
238
+ name: name,
239
+ title: title,
240
+ visible: visible,
241
+ data_index: index,
242
+ display_index: display_index,
243
+ cell_renderer: cell_renderer
244
+ }
245
+ end
246
+ return columns.sort_by { |hsh| hsh[ :display_index ] }
247
+ end
248
+
110
249
  end
111
250
  end
112
251
  end
@@ -63,6 +63,8 @@ module Gloo
63
63
  # Make the JSON pretty.
64
64
  #
65
65
  def msg_pretty
66
+ return unless self.value
67
+
66
68
  json = JSON.parse( self.value )
67
69
  pretty = JSON.pretty_generate( json )
68
70
  set_value pretty
@@ -173,7 +173,7 @@ module Gloo
173
173
  # Get the expiration date for the certificate.
174
174
  #
175
175
  def msg_render
176
- content = self.render
176
+ content = self.render_html
177
177
  @engine.heap.it.set_to content
178
178
  return content
179
179
  end
@@ -226,10 +226,9 @@ module Gloo
226
226
  e = Gloo::Objs::Alias.resolve_alias( engine, e )
227
227
  if e.class == Element
228
228
  rendered_obj_content << e.send( render_ƒ )
229
- elsif e.class == Partial
230
- rendered_obj_content << e.render( render_ƒ )
231
229
  else
232
- rendered_obj_content << e.value.to_s
230
+ data = render_thing e, render_ƒ, engine
231
+ ( rendered_obj_content << data ) if data # e.render( render_ƒ )
233
232
  end
234
233
  end
235
234
  else
@@ -238,7 +237,16 @@ module Gloo
238
237
 
239
238
  return rendered_obj_content
240
239
  end
241
-
240
+
241
+ def self.render_thing e, render_ƒ, engine
242
+ begin
243
+ return e.render( render_ƒ )
244
+ rescue => e
245
+ engine.err e.message
246
+ return ''
247
+ end
248
+ end
249
+
242
250
  end
243
251
  end
244
252
  end
@@ -17,6 +17,7 @@ module Gloo
17
17
 
18
18
  # Parameters used during render.
19
19
  PARAMS = 'params'.freeze
20
+ ID = 'id'.freeze
20
21
 
21
22
  # Content
22
23
  HEAD = 'head'.freeze
@@ -112,6 +113,19 @@ module Gloo
112
113
  params_can = find_child PARAMS
113
114
  return nil unless params_can
114
115
 
116
+ if @request
117
+ url_params = @request.query_params
118
+ url_params.each do |k,v|
119
+ o = params_can.find_child k
120
+ o.set_value( v ) if o
121
+ end
122
+
123
+ @request.body_params.each do |k,v|
124
+ o = params_can.find_child k
125
+ o.set_value( v ) if o
126
+ end
127
+ end
128
+
115
129
  h = {}
116
130
  params_can.children.each do |o|
117
131
  h[ o.name ] = o.value
@@ -281,15 +295,38 @@ module Gloo
281
295
  return @engine.running_app.obj.redirect
282
296
  end
283
297
 
298
+ #
299
+ # Set the ID parameter if there is one.
300
+ #
301
+ def set_id
302
+ return unless @request.id
303
+ @engine.log.info "Setting ID: #{@request.id}"
304
+
305
+ params_can = find_child PARAMS
306
+ return nil unless params_can
307
+
308
+ id_obj = params_can.find_child( ID )
309
+ return unless id_obj
310
+
311
+ id_obj.set_value( @request.id )
312
+ end
313
+
284
314
  #
285
315
  # Render the page.
316
+ # If this is being called from the web server,
317
+ # the request will be passed in and will include
318
+ # request context such as params.
286
319
  #
287
- def render
288
- run_on_render
289
- return nil if redirect_set?
320
+ def render request=nil
321
+ @request = request
322
+ set_id if @request
290
323
 
324
+ # Set Params before running on render
291
325
  params = params_hash
292
326
 
327
+ run_on_render
328
+ return nil if redirect_set?
329
+
293
330
  if is_html?
294
331
  contents = render_html params
295
332
  elsif is_json?
@@ -302,6 +339,7 @@ module Gloo
302
339
  end
303
340
 
304
341
  run_on_rendered
342
+ @request = nil
305
343
  return nil if redirect_set?
306
344
 
307
345
  return contents
@@ -161,8 +161,13 @@ module Gloo
161
161
  run_on_render
162
162
 
163
163
  part_content = ''
164
- content.children.each do |e|
165
- part_content << e.send( render_ƒ )
164
+ data = content
165
+ if data.children.empty?
166
+ part_content = data.value
167
+ else
168
+ data.children.each do |e|
169
+ part_content << e.send( render_ƒ )
170
+ end
166
171
  end
167
172
 
168
173
  # part_content = Page.render_params part_content, params_hash
@@ -16,6 +16,10 @@ module Gloo
16
16
  HOST = 'host'.freeze
17
17
  PORT = 'port'.freeze
18
18
 
19
+ # SSL Configuration
20
+ SSL_CERT = 'ssl_cert'.freeze
21
+ SSL_KEY = 'ssl_key'.freeze
22
+
19
23
  # Events
20
24
  ON_START = 'on_start'.freeze
21
25
  ON_STOP = 'on_stop'.freeze
@@ -32,7 +36,7 @@ module Gloo
32
36
 
33
37
 
34
38
  # Messages
35
- SERVER_NOT_RUNNING = 'The web server is not running and cannot be stopped'.freeze
39
+ SERVER_NOT_RUNNING = 'The web server is not running!'.freeze
36
40
 
37
41
  #
38
42
  # Should the current request be redirected?
@@ -115,6 +119,56 @@ module Gloo
115
119
  return o
116
120
  end
117
121
 
122
+
123
+ # ---------------------------------------------------------------------
124
+ # SSL
125
+ # ---------------------------------------------------------------------
126
+
127
+ #
128
+ # Is SSL configured for this server?
129
+ # True if the Cert and Key are both present.
130
+ #
131
+ def use_ssl?
132
+ return ssl_cert && ssl_key
133
+ end
134
+
135
+ #
136
+ # Get the SSL certificate from the child object.
137
+ # Returns nil if there is none.
138
+ #
139
+ def ssl_cert
140
+ cert = find_child SSL_CERT
141
+ return nil unless cert
142
+
143
+ cert = Gloo::Objs::Alias.resolve_alias( @engine, cert )
144
+ return cert
145
+ end
146
+
147
+ #
148
+ # Get the SSL key from the child object.
149
+ # Returns nil if there is none.
150
+ #
151
+ def ssl_key
152
+ key = find_child SSL_KEY
153
+ return nil unless key
154
+
155
+ key = Gloo::Objs::Alias.resolve_alias( @engine, key )
156
+ return key
157
+ end
158
+
159
+ #
160
+ # Get the SSL configuration for the server.
161
+ #
162
+ def ssl_config
163
+ return nil unless use_ssl?
164
+
165
+ return {
166
+ :private_key_file => ssl_key.value,
167
+ :cert_chain_file => ssl_cert.value,
168
+ :verify_peer => false,
169
+ }
170
+ end
171
+
118
172
  # ---------------------------------------------------------------------
119
173
  # Children
120
174
  # ---------------------------------------------------------------------
@@ -156,7 +210,7 @@ module Gloo
156
210
  # Get a list of message names that this object receives.
157
211
  #
158
212
  def self.messages
159
- return super + [ 'start', 'stop' ]
213
+ return super + [ 'start', 'stop', 'routes' ]
160
214
  end
161
215
 
162
216
  #
@@ -183,6 +237,18 @@ module Gloo
183
237
  end
184
238
  end
185
239
 
240
+ #
241
+ # Helper message to show all routes in the running server.
242
+ #
243
+ def msg_routes
244
+ if @router
245
+ @router.show_routes
246
+ else
247
+ @engine.log.error SERVER_NOT_RUNNING
248
+ end
249
+ end
250
+
251
+
186
252
  # ---------------------------------------------------------------------
187
253
  # Start and Stop Events
188
254
  # Might come from messages or from other application events.
@@ -197,10 +263,10 @@ module Gloo
197
263
  @engine.log.info "Web Server URL: #{config.base_url}"
198
264
 
199
265
  handler = Gloo::WebSvr::Handler.new( @engine, self )
200
- @web_server = Gloo::WebSvr::Server.new( @engine, handler, config )
266
+ @web_server = Gloo::WebSvr::Server.new( @engine, handler, config, ssl_config )
201
267
  @web_server.start
202
268
 
203
- @router = Gloo::WebSvr::Router.new( @engine, self )
269
+ @router = Gloo::WebSvr::Routing::Router.new( @engine, self )
204
270
  @router.add_page_routes
205
271
 
206
272
  @asset = Gloo::WebSvr::Asset.new( @engine, self )
@@ -219,6 +285,7 @@ module Gloo
219
285
  @engine.log.info "Stopping web server…"
220
286
  @web_server.stop
221
287
  @web_server = nil
288
+ @router = nil
222
289
 
223
290
  run_on_stop
224
291
  @engine.log.info "Web server stopped…"
@@ -0,0 +1,44 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Break out of the script without error.
5
+ #
6
+
7
+ module Gloo
8
+ module Verbs
9
+ class Break < Gloo::Core::Verb
10
+
11
+ KEYWORD = 'break'.freeze
12
+ KEYWORD_SHORT = 'stop'.freeze
13
+
14
+ #
15
+ # Run the verb.
16
+ # Stop the execution of the current script.
17
+ #
18
+ def run
19
+ @engine.exec_env.running_script.break_out
20
+ end
21
+
22
+ #
23
+ # Get the Verb's keyword.
24
+ #
25
+ def self.keyword
26
+ return KEYWORD
27
+ end
28
+
29
+ #
30
+ # Get the Verb's keyword shortcut.
31
+ #
32
+ def self.keyword_shortcut
33
+ return KEYWORD_SHORT
34
+ end
35
+
36
+ # ---------------------------------------------------------------------
37
+ # Private functions
38
+ # ---------------------------------------------------------------------
39
+
40
+ private
41
+
42
+ end
43
+ end
44
+ end
@@ -57,6 +57,12 @@ module Gloo
57
57
  if Gloo::Expr::LString.string?( value )
58
58
  value = Gloo::Expr::LString.strip_quotes( value )
59
59
  end
60
+
61
+ # Check to see if this is an alias
62
+ pn = Gloo::Core::Pn.new( @engine, name )
63
+ obj = pn.resolve if pn
64
+ name = obj.value if obj&.is_alias?
65
+
60
66
  obj = @engine.factory.create( { name: name, type: type, value: value } )
61
67
 
62
68
  obj.add_default_children if obj&.add_children_on_create?
@@ -16,11 +16,11 @@ module Gloo
16
16
  #
17
17
  def run
18
18
  if @tokens.token_count > 1
19
- expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
20
- result = expr.evaluate
21
- level = log_level_specified( result )
22
- @engine.log.write result, level
23
- @engine.heap.it.set_to result
19
+ if is_clear_cmd?
20
+ @engine.log.clear
21
+ else
22
+ write_to_log
23
+ end
24
24
  else
25
25
  @engine.log.debug ''
26
26
  end
@@ -46,6 +46,27 @@ module Gloo
46
46
 
47
47
  private
48
48
 
49
+ #
50
+ # Write to the specified logger.
51
+ #
52
+ def write_to_log
53
+ expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
54
+ result = expr.evaluate
55
+ level = log_level_specified( result )
56
+ @engine.log.write result, level
57
+ @engine.heap.it.set_to result
58
+ end
59
+
60
+ #
61
+ # Is this a clear logs command?
62
+ #
63
+ def is_clear_cmd?
64
+ return true if ( ( @tokens.token_count == 2 ) &&
65
+ ( @tokens.params.first == 'clear' ) )
66
+
67
+ return false
68
+ end
69
+
49
70
  #
50
71
  # Get the formatted string.
51
72
  #
@@ -12,7 +12,11 @@ module Gloo
12
12
  KEYWORD = 'redirect'.freeze
13
13
  KEYWORD_SHORT = 'go'.freeze
14
14
 
15
+ RUN_MESSAGE = 'run'.freeze
16
+
15
17
  MISSING_EXPR_ERR = 'Missing Expression!'.freeze
18
+ APP_NOT_RUNING_ERR = 'The application is not running!'.freeze
19
+ BAD_TARGET_ERR = 'Bad redirect target!'.freeze
16
20
 
17
21
  #
18
22
  # Run the verb.
@@ -23,12 +27,8 @@ module Gloo
23
27
  return
24
28
  end
25
29
 
26
- # Send the redirect page to the running app.
27
- if @engine.app_running?
28
- obj_name = @tokens.second
29
- pn = Gloo::Core::Pn.new( @engine, obj_name )
30
- @engine.running_app.obj.redirect = pn.resolve
31
- end
30
+ determine_target
31
+ redirect_to_target
32
32
  end
33
33
 
34
34
  #
@@ -51,6 +51,54 @@ module Gloo
51
51
 
52
52
  private
53
53
 
54
+ #
55
+ # Send the control to the redirect target.
56
+ # This could be a page or a script.
57
+ #
58
+ def redirect_to_target
59
+ if @target_obj.class == Gloo::Objs::Page
60
+ redirect_to_page
61
+ elsif @target_obj.can_receive_message?( RUN_MESSAGE )
62
+ redirect_to_script
63
+ else
64
+ @engine.err BAD_TARGET_ERR
65
+ end
66
+ end
67
+
68
+ #
69
+ # Find the target of the redirect.
70
+ #
71
+ def determine_target
72
+ obj_name = @tokens.second
73
+ pn = Gloo::Core::Pn.new( @engine, obj_name )
74
+
75
+ @target_obj = pn.resolve
76
+
77
+ @engine.log.info "obj type: #{@target_obj.class}"
78
+ end
79
+
80
+ #
81
+ # Redirect to a page.
82
+ # This requires a running web server.
83
+ #
84
+ def redirect_to_page
85
+ if @engine.app_running?
86
+ @engine.running_app.obj.redirect = @target_obj
87
+ else
88
+ @engine.err APP_NOT_RUNING_ERR
89
+ end
90
+ end
91
+
92
+ #
93
+ # Redirect to another script.
94
+ # This stops execution of the current script.
95
+ #
96
+ def redirect_to_script
97
+ @engine.exec_env.running_script.break_out
98
+
99
+ Gloo::Exec::Dispatch.message( @engine, RUN_MESSAGE, @target_obj )
100
+ end
101
+
54
102
  end
55
103
  end
56
104
  end
@@ -11,6 +11,7 @@ module Gloo
11
11
  ASSETS_FOLDER = 'assets'.freeze
12
12
  IMAGES_FOLDER = 'images'.freeze
13
13
  STYLESHEETS_FOLDER = 'stylesheets'.freeze
14
+ JAVASCRIPT_FOLDER = 'javascript'.freeze
14
15
 
15
16
  CSS_TYPE = 'text/css'.freeze
16
17
  JS_TYPE = 'text/javascript'.freeze
@@ -59,6 +60,13 @@ module Gloo
59
60
  return File.join( assets_folder, STYLESHEETS_FOLDER )
60
61
  end
61
62
 
63
+ #
64
+ # Get the stylesheets folder in the project.
65
+ #
66
+ def javascript_folder
67
+ return File.join( assets_folder, JAVASCRIPT_FOLDER )
68
+ end
69
+
62
70
  #
63
71
  # Find and return the page for the given route.
64
72
  #
@@ -125,6 +133,7 @@ module Gloo
125
133
  add_containers
126
134
  add_images
127
135
  add_stylesheets
136
+ add_javascript
128
137
  end
129
138
 
130
139
  #
@@ -141,6 +150,9 @@ module Gloo
141
150
 
142
151
  @stylesheets = @assets.find_child( STYLESHEETS_FOLDER ) ||
143
152
  @factory.create_can( STYLESHEETS_FOLDER, @assets )
153
+
154
+ @javascript = @assets.find_child( JAVASCRIPT_FOLDER ) ||
155
+ @factory.create_can( JAVASCRIPT_FOLDER, @assets )
144
156
  end
145
157
 
146
158
  #
@@ -175,6 +187,22 @@ module Gloo
175
187
  end
176
188
  end
177
189
 
190
+ #
191
+ # Add the Javascript files to the web server pages.
192
+ #
193
+ def add_javascript
194
+ @log.debug 'Adding javascript asset routes to web server…'
195
+
196
+ return unless File.exist? javascript_folder
197
+
198
+ # for each file in the javascript folder
199
+ # create a file object and add it to the javascript container
200
+ Dir.each_child( javascript_folder ) do |name|
201
+ pn = File.join( JAVASCRIPT_FOLDER, name )
202
+ add_file_obj( @javascript, name, pn )
203
+ end
204
+ end
205
+
178
206
  #
179
207
  # Add a file object (page route) to the given container.
180
208
  #