gloo 4.6.1 → 5.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/gloo.gemspec +22 -11
  4. data/lib/VERSION +1 -1
  5. data/lib/VERSION_NOTES +12 -0
  6. data/lib/gloo/app/engine.rb +8 -1
  7. data/lib/gloo/app/running_app.rb +13 -0
  8. data/lib/gloo/app/settings.rb +5 -1
  9. data/lib/gloo/core/dictionary.rb +15 -2
  10. data/lib/gloo/objs/ctrl/each.rb +2 -2
  11. data/lib/gloo/plugin/base.rb +19 -0
  12. data/lib/gloo/plugin/callback.rb +33 -0
  13. data/lib/gloo/plugin/ext_manager.rb +90 -0
  14. data/lib/gloo/plugin/lib_manager.rb +97 -0
  15. data/lib/gloo/verbs/exists.rb +75 -0
  16. data/lib/gloo/verbs/help.rb +58 -1
  17. data/lib/gloo/verbs/load.rb +49 -5
  18. data/lib/gloo/verbs/redirect.rb +2 -1
  19. metadata +38 -166
  20. data/lib/gloo/objs/cli/colorize.rb +0 -73
  21. data/lib/gloo/objs/cli/confirm.rb +0 -96
  22. data/lib/gloo/objs/cli/menu.rb +0 -370
  23. data/lib/gloo/objs/cli/menu_item.rb +0 -95
  24. data/lib/gloo/objs/cli/prompt.rb +0 -110
  25. data/lib/gloo/objs/cli/select.rb +0 -127
  26. data/lib/gloo/objs/ctrl/each_repo.rb +0 -84
  27. data/lib/gloo/objs/data/markdown.rb +0 -133
  28. data/lib/gloo/objs/data/markdown_ext.rb +0 -260
  29. data/lib/gloo/objs/data/mysql.rb +0 -254
  30. data/lib/gloo/objs/data/pg.rb +0 -216
  31. data/lib/gloo/objs/data/query.rb +0 -269
  32. data/lib/gloo/objs/data/query_result.rb +0 -158
  33. data/lib/gloo/objs/data/sqlite.rb +0 -174
  34. data/lib/gloo/objs/data/table.rb +0 -267
  35. data/lib/gloo/objs/dev/git.rb +0 -140
  36. data/lib/gloo/objs/dev/stats.rb +0 -123
  37. data/lib/gloo/objs/system/ssh_exec.rb +0 -126
  38. data/lib/gloo/objs/web/slack.rb +0 -130
  39. data/lib/gloo/objs/web/teams.rb +0 -117
  40. data/lib/gloo/objs/web_svr/element.rb +0 -254
  41. data/lib/gloo/objs/web_svr/field.rb +0 -429
  42. data/lib/gloo/objs/web_svr/form.rb +0 -271
  43. data/lib/gloo/objs/web_svr/page.rb +0 -562
  44. data/lib/gloo/objs/web_svr/partial.rb +0 -210
  45. data/lib/gloo/objs/web_svr/svr.rb +0 -713
  46. data/lib/gloo/utils/stats.rb +0 -206
  47. data/lib/gloo/verbs/alert.rb +0 -79
  48. data/lib/gloo/verbs/beep.rb +0 -40
  49. data/lib/gloo/web_svr/asset.rb +0 -407
  50. data/lib/gloo/web_svr/asset_info.rb +0 -116
  51. data/lib/gloo/web_svr/config.rb +0 -56
  52. data/lib/gloo/web_svr/embedded_renderer.rb +0 -154
  53. data/lib/gloo/web_svr/handler.rb +0 -154
  54. data/lib/gloo/web_svr/request.rb +0 -143
  55. data/lib/gloo/web_svr/request_params.rb +0 -181
  56. data/lib/gloo/web_svr/response.rb +0 -177
  57. data/lib/gloo/web_svr/response_code.rb +0 -69
  58. data/lib/gloo/web_svr/routing/resource_router.rb +0 -47
  59. data/lib/gloo/web_svr/routing/router.rb +0 -232
  60. data/lib/gloo/web_svr/routing/show_routes.rb +0 -94
  61. data/lib/gloo/web_svr/server.rb +0 -105
  62. data/lib/gloo/web_svr/session.rb +0 -215
  63. data/lib/gloo/web_svr/table_renderer.rb +0 -151
  64. data/lib/gloo/web_svr/web_method.rb +0 -54
  65. /data/lib/gloo/objs/{security → str_utils}/cipher.rb +0 -0
  66. /data/lib/gloo/objs/{security → str_utils}/csrf_token.rb +0 -0
  67. /data/lib/gloo/objs/{security → str_utils}/password.rb +0 -0
  68. /data/lib/gloo/objs/{ror → system}/erb.rb +0 -0
  69. /data/lib/gloo/objs/{ror → system}/eval.rb +0 -0
@@ -1,177 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # The Response for a web Request.
5
- #
6
-
7
- module Gloo
8
- module WebSvr
9
- class Response
10
-
11
- #
12
- # SEE: https://stackoverflow.com/questions/23714383/what-are-all-the-possible-values-for-http-content-type-header#48704300
13
- # for a list of content types.
14
- #
15
- CONTENT_TYPE = 'Content-Type'.freeze
16
- TEXT_TYPE = 'text/plain'.freeze
17
- JSON_TYPE = 'application/json'.freeze
18
- HTML_TYPE = 'text/html'.freeze
19
-
20
- attr_reader :code, :type, :data
21
- attr_accessor :location
22
- attr_accessor :file_name
23
-
24
-
25
- # ---------------------------------------------------------------------
26
- # Initialization
27
- # ---------------------------------------------------------------------
28
-
29
- #
30
- # Set up the web server.
31
- #
32
- def initialize( engine = nil,
33
- code = Gloo::WebSvr::ResponseCode::SUCCESS,
34
- type = HTML_TYPE,
35
- data = nil,
36
- assetCache = false,
37
- file_name = nil,
38
- download = false )
39
-
40
- @engine = engine
41
- @log = @engine.log if @engine
42
-
43
- @code = code
44
- @type = type
45
- @data = data
46
- @assetCache = assetCache
47
- @location = nil
48
- @file_name = file_name
49
- @download = download
50
- end
51
-
52
-
53
- # ---------------------------------------------------------------------
54
- # Static Helper Functions
55
- # ---------------------------------------------------------------------
56
-
57
- #
58
- # Helper to create a successful JSON response with the given data.
59
- #
60
- def self.json_response( engine, data,
61
- code = Gloo::WebSvr::ResponseCode::SUCCESS )
62
-
63
- return Gloo::WebSvr::Response.new( engine, code, JSON_TYPE, data )
64
- end
65
-
66
- #
67
- # Helper to create a successful text response with the given data.
68
- #
69
- def self.text_response( engine, data,
70
- code = Gloo::WebSvr::ResponseCode::SUCCESS )
71
-
72
- return Gloo::WebSvr::Response.new( engine, code, TEXT_TYPE, data )
73
- end
74
-
75
- #
76
- # Helper to create a successful web response with the given data.
77
- #
78
- def self.html_response( engine, data,
79
- code = Gloo::WebSvr::ResponseCode::SUCCESS )
80
-
81
- return Gloo::WebSvr::Response.new( engine, code, HTML_TYPE, data )
82
- end
83
-
84
- #
85
- # Helper to create a redirect response.
86
- #
87
- def self.redirect_response( engine, target )
88
- code = Gloo::WebSvr::ResponseCode::FOUND
89
- data = <<~TEXT
90
- <head>
91
- <html>
92
- <body><a href="#{target}">target is here</a></body>
93
- </html>
94
- </head>
95
- TEXT
96
-
97
- response = Gloo::WebSvr::Response.new( engine, code, HTML_TYPE, data )
98
- response.location = target
99
-
100
- return response
101
- end
102
-
103
-
104
- # ---------------------------------------------------------------------
105
- # Data Functions
106
- # ---------------------------------------------------------------------
107
-
108
- #
109
- # Add content to the payload.
110
- #
111
- def add content
112
- @data = '' if @data.nil?
113
- @data << content
114
- end
115
-
116
- #
117
- # Get the headers for the response.
118
- #
119
- def headers
120
- #
121
- # TO DO: Add more cookie headers here.
122
- #
123
- # https://stackoverflow.com/questions/3295083/how-do-i-set-a-cookie-with-a-ruby-rack-middleware-component
124
- # https://www.rubydoc.info/gems/rack/1.4.7/Rack/Session/Cookie
125
- #
126
-
127
- headers = { CONTENT_TYPE => @type }
128
-
129
- if @location
130
- headers[ 'Location' ] = @location
131
- end
132
-
133
- if @assetCache || @file_name
134
- headers[ 'Cache-Control' ] = 'public, max-age=604800'
135
- headers[ 'Expires' ] = (Time.now.utc + 604800).to_s
136
- end
137
-
138
- if @file_name
139
- disp = @download ? 'attachment' : 'inline'
140
- headers[ 'Content-Disposition' ] = "#{disp}; filename=#{@file_name}"
141
- headers[ 'Content-Length' ] = @data.length.to_s
142
- end
143
-
144
- session = @engine&.running_app&.obj&.session
145
- headers = session.add_session_for_response( headers ) if session
146
-
147
- # Clear out session data after the response is prepared.
148
- @engine&.running_app&.obj&.reset_session_data
149
-
150
- return headers
151
- end
152
-
153
- #
154
- # Get the final result that will be returned as the
155
- # response to the web request.
156
- #
157
- def result
158
- return [ @code, headers, @data ]
159
- end
160
-
161
-
162
- # ---------------------------------------------------------------------
163
- # Helper functions
164
- # ---------------------------------------------------------------------
165
-
166
- #
167
- # Write the result information to the log.
168
- #
169
- def log
170
- return unless @log
171
-
172
- @log.info "Response #{@code} #{@type}"
173
- end
174
-
175
- end
176
- end
177
- end
@@ -1,69 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # Standard Response Codes.
5
- #
6
- # See:
7
- # https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
8
- # https://www.geeksforgeeks.org/10-most-common-http-status-codes/
9
- #
10
-
11
- module Gloo
12
- module WebSvr
13
- class ResponseCode
14
-
15
- # Gloo::WebSvr::ResponseCode::SUCCESS
16
- SUCCESS = 200.freeze
17
- CODE_200 = 'Success/OK'.freeze
18
-
19
- CREATED = 201.freeze
20
- CODE_201 = 'Created'.freeze
21
-
22
- ACCEPTED = 202.freeze
23
- CODE_202 = 'Accepted'.freeze
24
-
25
- NO_CONTENT = 204.freeze
26
- CODE_204 = 'No Content'.freeze
27
-
28
- PARTIAL_CONTENT = 206.freeze
29
- CODE_206 = 'Partial Content'.freeze
30
-
31
- MOVED_PERM = 301.freeze
32
- CODE_301 = 'Moved Permanently'.freeze
33
-
34
- FOUND = 302.freeze
35
- CODE_302 = 'Found'.freeze
36
-
37
- SEE_OTHER = 303.freeze
38
- CODE_303 = 'See Other'.freeze
39
-
40
- NOT_MODIFIED = 304.freeze
41
- CODE_304 = 'Not Modified'.freeze
42
-
43
- TEMP_REDIRECT = 307.freeze
44
- CODE_307 = 'Temporary Redirect'.freeze
45
-
46
- PERM_REDIRECT = 308.freeze
47
- CODE_308 = 'Permanent Redirect'.freeze
48
-
49
- BAD_REQUEST = 400.freeze
50
- CODE_400 = 'Bad Request'.freeze
51
-
52
- UNAUTHORIZED = 401.freeze
53
- CODE_401 = 'Unauthorized'.freeze
54
-
55
- FORBIDDEN = 403.freeze
56
- CODE_403 = 'Forbidden'.freeze
57
-
58
- NOT_FOUND = 404.freeze
59
- CODE_404 = 'Not Found'.freeze
60
-
61
- SERVER_ERR = 500.freeze
62
- CODE_500 = 'Internal Server Error'.freeze
63
-
64
- NOT_IMPLEMENTED = 501.freeze
65
- CODE_501 = 'Not Implemented'.freeze
66
-
67
- end
68
- end
69
- end
@@ -1,47 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A helper class for Resource routing.
5
- #
6
-
7
- module Gloo
8
- module WebSvr
9
- module Routing
10
- class ResourceRouter
11
-
12
- INDEX = 'index'.freeze
13
- SHOW = 'show'.freeze
14
- DELETE = 'delete'.freeze
15
- UPDATE = 'update'.freeze
16
-
17
- POST_ROUTE = 'create'.freeze
18
-
19
-
20
- #
21
- # Is the given route segment an implicit create resource?
22
- # It is explicit if it is 'create'
23
- # and implicit if it is a POST to the resource.
24
- #
25
- def self.is_implicit_create?( method, route_segment )
26
- return false unless Gloo::WebSvr::WebMethod.is_post?( method )
27
-
28
- return ! route_segment.eql?( POST_ROUTE )
29
- end
30
-
31
- #
32
- # Add the segment based on the method.
33
- #
34
- def self.segment_for_method( method )
35
- if Gloo::WebSvr::WebMethod.is_delete?( method )
36
- return DELETE
37
- elsif Gloo::WebSvr::WebMethod.is_patch?( method )
38
- return UPDATE
39
- else
40
- return SHOW
41
- end
42
- end
43
-
44
- end
45
- end
46
- end
47
- end
@@ -1,232 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A helper class for page routing.
5
- #
6
-
7
- module Gloo
8
- module WebSvr
9
- module Routing
10
- class Router
11
-
12
- PAGE_CONTAINER = 'page'.freeze
13
- SEGMENT_DIVIDER = '/'.freeze
14
-
15
- attr_reader :route_segments
16
-
17
-
18
- # ---------------------------------------------------------------------
19
- # Initialization
20
- # ---------------------------------------------------------------------
21
-
22
- #
23
- # Set up the web server.
24
- #
25
- def initialize( engine, web_svr_obj )
26
- @engine = engine
27
- @log = @engine.log
28
-
29
- @web_svr_obj = web_svr_obj
30
- @show_routes = ShowRoutes.new( @engine )
31
- end
32
-
33
-
34
- # ---------------------------------------------------------------------
35
- # Routing
36
- # ---------------------------------------------------------------------
37
-
38
- #
39
- # Find and return the page for the given route.
40
- #
41
- def page_for_route( path, method )
42
- @log.info "routing to #{path} for method #{method}"
43
- @method = method
44
- route_params = nil
45
- @id = nil
46
-
47
- detect_segments path
48
-
49
- return @web_svr_obj.home_page if is_root_path?
50
-
51
- pages = @web_svr_obj.pages_container
52
- if pages
53
- # If the method is POST and the last segment is NOT 'create',
54
- # we'll add create to the route segments.
55
- if Gloo::WebSvr::Routing::ResourceRouter.is_implicit_create?( method, @route_segments.last )
56
- @route_segments << Gloo::WebSvr::Routing::ResourceRouter::POST_ROUTE
57
- page = find_route_segment( pages.children )
58
- return [ page, @id, route_params ] if page
59
-
60
- # We didn't find the page, so remove the last segment and try again
61
- # posting to the resource.
62
- @route_segments.pop
63
- end
64
-
65
- page = find_route_segment( pages.children )
66
-
67
- # Are there any remaining segments to be added as route parameters?
68
- if @route_segments.count > 0
69
- route_params = @route_segments
70
- end
71
-
72
- return [ page, @id, route_params ] if page
73
- end
74
-
75
- return nil
76
- end
77
-
78
-
79
- # ---------------------------------------------------------------------
80
- # Dynamic Add Page Routes
81
- # ---------------------------------------------------------------------
82
-
83
- #
84
- # Get the root level page container.
85
- #
86
- def page_container
87
- pn = Gloo::Core::Pn.new( @engine, PAGE_CONTAINER )
88
- return pn.resolve
89
- end
90
-
91
- #
92
- # Add all page routes to the web server pages (routes).
93
- #
94
- def add_page_routes
95
- can = page_container
96
- return unless can
97
-
98
- @log.debug 'Adding page routes to web server…'
99
- @factory = @engine.factory
100
-
101
- add_pages can, @web_svr_obj.pages_container
102
- end
103
-
104
- #
105
- # Add the pages to the web server pages.
106
- # This is a recursive function that will add all
107
- # pages in the folder and subfolders.
108
- #
109
- def add_pages can, parent
110
- # for each file in the page container
111
- # create a page object and add it to the routes
112
- can.children.each do |obj|
113
- if obj.class == Gloo::Objs::Container
114
- child_can = parent.find_add_child( obj.name, 'container' )
115
- add_pages( obj, child_can )
116
- elsif obj.class == Gloo::Objs::Page
117
- add_route_alias( parent, obj.name, obj.pn )
118
- end
119
- end
120
- end
121
-
122
- #
123
- # Add route alias to the page.
124
- #
125
- def add_route_alias( parent, name, pn )
126
- name = name.gsub( '.', '_' )
127
-
128
- # First make sure the child doesn't already exist.
129
- child = parent.find_child( name )
130
- return if child
131
-
132
- @factory.create_alias( name, pn, parent )
133
- end
134
-
135
-
136
- # ---------------------------------------------------------------------
137
- # Helper funcions
138
- # ---------------------------------------------------------------------
139
-
140
- #
141
- # Show the routes in the running app.
142
- # This uses the ShowRoutes helper class.
143
- #
144
- def show_routes
145
- @show_routes.show page_container
146
- end
147
-
148
- #
149
- # Find the route segment in the object container.
150
- #
151
- def find_route_segment objs
152
- this_segment = next_segment
153
-
154
- if this_segment.blank? # && Gloo::WebSvr::WebMethod.is_post?( @method )
155
- this_segment = Gloo::WebSvr::Routing::ResourceRouter::INDEX
156
- end
157
-
158
- objs.each do |o|
159
- o = Gloo::Objs::Alias.resolve_alias( @engine, o )
160
-
161
- if o.name == this_segment
162
- if o.class == Gloo::Objs::Page
163
- @log.debug "found page for route: #{o.pn}"
164
- return o
165
- elsif o.class == Gloo::Objs::FileHandle
166
- @log.debug "found static file for route: #{o.pn}"
167
- return o
168
- else
169
- return nil unless o.child_count > 0
170
-
171
- return find_route_segment( o.children )
172
- end
173
- end
174
- end
175
-
176
- return nil
177
- end
178
-
179
- #
180
- # Get the next segment in the route.
181
- #
182
- def next_segment
183
- this_segment = @route_segments.shift
184
- return nil if this_segment.nil?
185
-
186
- # A URL might include a dot in a name, but we can't do that
187
- # because dot is a reserve path thing. So we replace it with
188
- # an underscore.
189
- this_segment = this_segment.gsub( '.', '_' )
190
-
191
- return this_segment
192
- end
193
-
194
- #
195
- # Is this the root path?
196
- def is_root_path?
197
- return @route_segments.count == 0
198
- end
199
-
200
- #
201
- # Create a list of path segments.
202
- #
203
- def detect_segments path
204
- # For Assets, substitute the published name with fingerprint
205
- # for the simple asset name (if it is found).
206
- asset_info = Gloo::WebSvr::AssetInfo.find_info_for( path )
207
- unless asset_info.blank?
208
- path = asset_info.pn
209
- end
210
-
211
- # Split the path into segments.
212
- @route_segments = path.split SEGMENT_DIVIDER
213
-
214
- # Remove the first segment if it is empty.
215
- @route_segments.shift if @route_segments.first.blank?
216
-
217
- @route_segments.each do |seg|
218
- if seg.to_i.to_s == seg
219
- @id = seg.to_i
220
- @log.info "found id for route: #{@id}"
221
- @route_segments.delete seg
222
- @route_segments << ResourceRouter.segment_for_method( @method )
223
- end
224
- end
225
-
226
- return @route_segments
227
- end
228
-
229
- end
230
- end
231
- end
232
- end
@@ -1,94 +0,0 @@
1
- # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
- # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
- #
4
- # A helper class for to show routes for a running app.
5
- #
6
-
7
- module Gloo
8
- module WebSvr
9
- module Routing
10
- class ShowRoutes
11
-
12
- SEGMENT_DIVIDER = '/'.freeze
13
-
14
-
15
- # ---------------------------------------------------------------------
16
- # Initialization
17
- # ---------------------------------------------------------------------
18
-
19
- #
20
- # Set up the web server.
21
- #
22
- def initialize( engine )
23
- @engine = engine
24
- @log = @engine.log
25
- end
26
-
27
-
28
- # ---------------------------------------------------------------------
29
- # Show Routes
30
- # ---------------------------------------------------------------------
31
-
32
- #
33
- # Show all available routes.
34
- #
35
- def show page_container
36
- @log.debug "showing routes"
37
-
38
- @found_routes = []
39
- @log.debug "building route table"
40
- add_container_routes( page_container, SEGMENT_DIVIDER )
41
-
42
- show_table
43
- end
44
-
45
- #
46
- # Show the routes in the given container.
47
- # This is a recursive function travese the object tree.
48
- #
49
- def add_container_routes can, route_path
50
- can.children.each do |obj|
51
- if obj.class == Gloo::Objs::Container
52
- add_container_routes obj, "#{route_path}#{obj.name}#{SEGMENT_DIVIDER}"
53
- elsif obj.class == Gloo::Objs::Page
54
- route = "#{route_path}#{obj.name}"
55
- @found_routes << [ obj.name, obj.pn, route, Gloo::WebSvr::WebMethod::GET ]
56
-
57
- # If the method is POST, add a route alias for the create.
58
- if obj.name.eql? ResourceRouter::POST_ROUTE
59
- @found_routes << [ '', '', route_path, Gloo::WebSvr::WebMethod::POST ]
60
- elsif obj.name.eql? ResourceRouter::UPDATE
61
- @found_routes << [ '', '', route_path, Gloo::WebSvr::WebMethod::PATCH ]
62
- elsif obj.name.eql? ResourceRouter::DELETE
63
- @found_routes << [ '', '', route_path, Gloo::WebSvr::WebMethod::DELETE ]
64
- end
65
- end
66
- end
67
- end
68
-
69
-
70
- # ---------------------------------------------------------------------
71
- # Show Routes
72
- # ---------------------------------------------------------------------
73
-
74
- #
75
- # Show the Routes title.
76
- #
77
- def show_table
78
- puts Gloo::App::Platform::RETURN
79
- title = "Routes in Running Web App"
80
- @engine.platform.table.show headers, @found_routes, title
81
- puts Gloo::App::Platform::RETURN
82
- end
83
-
84
- #
85
- # Get the table headers.
86
- #
87
- def headers
88
- return [ 'Obj Name', 'Obj Path', 'Route', 'Method' ]
89
- end
90
-
91
- end
92
- end
93
- end
94
- end