foobara 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/projects/command/src/transformed_command.rb +2 -2
  4. data/projects/command_connectors/lib/foobara/command_connectors.rb +1 -1
  5. data/projects/command_connectors/src/{commands → command_connector/commands}/describe.rb +2 -6
  6. data/projects/command_connectors/src/{commands → command_connector/commands}/list_commands.rb +1 -1
  7. data/projects/command_connectors/src/{commands → command_connector/commands}/ping.rb +1 -1
  8. data/projects/command_connectors/src/{commands → command_connector/commands}/query_git_commit_info.rb +1 -1
  9. data/projects/command_connectors/src/{request.rb → command_connector/request.rb} +24 -13
  10. data/projects/command_connectors/src/{response.rb → command_connector/response.rb} +1 -1
  11. data/projects/command_connectors/src/command_connector.rb +29 -20
  12. data/projects/domain/src/domain_module_extension.rb +2 -0
  13. data/projects/domain/src/module_extension.rb +2 -2
  14. metadata +9 -37
  15. data/projects/command_connectors_http/lib/foobara/command_connectors_http.rb +0 -6
  16. data/projects/command_connectors_http/src/http/commands/get_options.rb +0 -16
  17. data/projects/command_connectors_http/src/http/commands/help/presenter/command.rb +0 -14
  18. data/projects/command_connectors_http/src/http/commands/help/presenter/domain.rb +0 -14
  19. data/projects/command_connectors_http/src/http/commands/help/presenter/entity.rb +0 -14
  20. data/projects/command_connectors_http/src/http/commands/help/presenter/error.rb +0 -14
  21. data/projects/command_connectors_http/src/http/commands/help/presenter/model.rb +0 -14
  22. data/projects/command_connectors_http/src/http/commands/help/presenter/organization.rb +0 -14
  23. data/projects/command_connectors_http/src/http/commands/help/presenter/processor.rb +0 -14
  24. data/projects/command_connectors_http/src/http/commands/help/presenter/processor_class.rb +0 -14
  25. data/projects/command_connectors_http/src/http/commands/help/presenter/root.rb +0 -14
  26. data/projects/command_connectors_http/src/http/commands/help/presenter/type.rb +0 -14
  27. data/projects/command_connectors_http/src/http/commands/help/presenter.rb +0 -178
  28. data/projects/command_connectors_http/src/http/commands/help/templates/command.html.erb +0 -11
  29. data/projects/command_connectors_http/src/http/commands/help/templates/domain.html.erb +0 -1
  30. data/projects/command_connectors_http/src/http/commands/help/templates/entity.html.erb +0 -11
  31. data/projects/command_connectors_http/src/http/commands/help/templates/error.html.erb +0 -1
  32. data/projects/command_connectors_http/src/http/commands/help/templates/model.html.erb +0 -8
  33. data/projects/command_connectors_http/src/http/commands/help/templates/organization.html.erb +0 -1
  34. data/projects/command_connectors_http/src/http/commands/help/templates/processor.html.erb +0 -1
  35. data/projects/command_connectors_http/src/http/commands/help/templates/processor_class.html.erb +0 -1
  36. data/projects/command_connectors_http/src/http/commands/help/templates/root.html.erb +0 -3
  37. data/projects/command_connectors_http/src/http/commands/help/templates/type.html.erb +0 -1
  38. data/projects/command_connectors_http/src/http/commands/help.rb +0 -98
  39. data/projects/command_connectors_http/src/http/request.rb +0 -98
  40. data/projects/command_connectors_http/src/http/response.rb +0 -14
  41. data/projects/command_connectors_http/src/http.rb +0 -93
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da90f5634c4dd8b25e3e4025aba385db5a05fb905de0eab32a87dfc75758fbb5
4
- data.tar.gz: 558ce219e510e8dc3fa21c625d2c0350efe32636114015d070cbfcb07818b133
3
+ metadata.gz: b7077a308e6717ee928b02783aa216a17eadda9f29f1f5a831449a038ac0e864
4
+ data.tar.gz: 387d8d37306f936d9be1eda46ba150b8de93fc14ee5ef6e2780466200fa48abd
5
5
  SHA512:
6
- metadata.gz: 9385c980625d21deee50b0bb88ecaf9b9fcea1557c2fe8effc162a33ea465e914a6f3f4fb21d373f322e7939ad6048aaf0e15c3081de3412f01e185cd07c02c1
7
- data.tar.gz: 349e0c8bb94463e29c7b1515b0fa1add2aca04b1866262c45fa3a9345d9fb16068717df11c1e57cb55b47c4e2dc4dfffc56319bc2cb1840abc3d4e8c4fcc1c7b
6
+ metadata.gz: b503fc97d9d287cffc3fd70a70de32ad158e6aebd41a1fcb1700a6bbdd1fde1b6f2e07431d7cd58afe57e4225b265107e746a627a12fb84c38f410c13d3ba342
7
+ data.tar.gz: f2e2efc432d279ae402f90dd57039a25dda7e4728fc1ff7be1c7882de37890737070beac97584cb9bafa7479d8e9fb9f9aa012e43865ddc033357b9bebaafa57
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.10] - 2024-10-26
2
+
3
+ - Extract http command connector to a different repostiory
4
+
1
5
  ## [0.0.9] - 2024-09-11
2
6
 
3
7
  - Add CommandRegistry#size
@@ -442,9 +442,9 @@ module Foobara
442
442
  end
443
443
  end
444
444
 
445
- def method_missing(method_name, *, **, &)
445
+ def method_missing(method_name, ...)
446
446
  if command.respond_to?(method_name)
447
- command.send(method_name, *, **, &)
447
+ command.send(method_name, ...)
448
448
  else
449
449
  # :nocov:
450
450
  super
@@ -8,5 +8,5 @@ module Foobara
8
8
  foobara_domain!
9
9
  end
10
10
 
11
- Monorepo.project :command_connectors
11
+ Monorepo.project "command_connectors"
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  module Commands
4
4
  class Describe < Foobara::Command
5
5
  inputs manifestable: :duck,
@@ -24,11 +24,7 @@ module Foobara
24
24
  end
25
25
 
26
26
  def stamp_request_metadata
27
- manifest[:metadata] = {
28
- # TODO: why is this here instead of in Http ??
29
- url: request.url,
30
- when: Time.now
31
- }
27
+ manifest[:metadata] = { when: Time.now }
32
28
  end
33
29
  end
34
30
  end
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  module Commands
4
4
  class ListCommands < Command
5
5
  inputs request: :duck, # TODO: have some way to specify by Ruby class...
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  module Commands
4
4
  class Ping < Foobara::Command
5
5
  result :datetime
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  module Commands
4
4
  # NOTE: this assumes that the following has been executed to generate the `git_commit_info.json` file:
5
5
  #
@@ -1,21 +1,32 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  class Request
4
4
  include TruncatedInspect
5
5
 
6
6
  # TODO: this feels like a smell of some sort...
7
- attr_accessor :command_class, :command, :error, :command_connector, :serializers
8
-
9
- def full_command_name
10
- # :nocov:
11
- raise "subclass responsibility"
12
- # :nocov:
13
- end
7
+ attr_accessor :command_class,
8
+ :command,
9
+ :error,
10
+ :command_connector,
11
+ :serializers,
12
+ :inputs,
13
+ :full_command_name,
14
+ :action
15
+
16
+ def initialize(**opts)
17
+ valid_keys = %i[inputs full_command_name action]
18
+
19
+ invalid_keys = opts.keys - valid_keys
20
+
21
+ unless invalid_keys.empty?
22
+ # :nocov:
23
+ raise ArgumentError, "invalid keys: #{invalid_keys} expected only #{valid_keys}"
24
+ # :nocov:
25
+ end
14
26
 
15
- def inputs
16
- # :nocov:
17
- raise "subclass responsibility"
18
- # :nocov:
27
+ self.inputs = opts[:inputs] if opts.key?(:inputs)
28
+ self.action = opts[:action] if opts.key?(:action)
29
+ self.full_command_name = opts[:full_command_name] if opts.key?(:full_command_name)
19
30
  end
20
31
 
21
32
  def serializer
@@ -74,7 +85,7 @@ module Foobara
74
85
  when Value::Processor
75
86
  object
76
87
  when ::Symbol, ::String
77
- klass = Serializer.serializer_from_symbol(object)
88
+ klass = Foobara::CommandConnectors::Serializer.serializer_from_symbol(object)
78
89
 
79
90
  unless klass
80
91
  # :nocov:
@@ -1,5 +1,5 @@
1
1
  module Foobara
2
- module CommandConnectors
2
+ class CommandConnector
3
3
  class Response
4
4
  attr_accessor :status,
5
5
  :body,
@@ -78,6 +78,16 @@ module Foobara
78
78
  class NoTypeFoundError < NotFoundError; end
79
79
  class NoCommandOrTypeFoundError < NotFoundError; end
80
80
 
81
+ class << self
82
+ def find_builtin_command_class(command_class_name)
83
+ Util.find_constant_through_class_hierarchy(self, "Commands::#{command_class_name}")
84
+ end
85
+ end
86
+
87
+ def find_builtin_command_class(command_class_name)
88
+ self.class.find_builtin_command_class(command_class_name)
89
+ end
90
+
81
91
  foobara_delegate :add_default_inputs_transformer,
82
92
  :add_default_result_transformer,
83
93
  :add_default_errors_transformer,
@@ -126,7 +136,7 @@ module Foobara
126
136
  # :nocov:
127
137
  end
128
138
 
129
- command_class = Foobara::CommandConnectors::Commands::Describe
139
+ command_class = find_builtin_command_class("Describe")
130
140
  full_command_name = command_class.full_command_name
131
141
 
132
142
  inputs = { manifestable:, request: }
@@ -141,7 +151,7 @@ module Foobara
141
151
  # :nocov:
142
152
  end
143
153
 
144
- command_class = Foobara::CommandConnectors::Commands::Describe
154
+ command_class = find_builtin_command_class("Describe")
145
155
  full_command_name = command_class.full_command_name
146
156
 
147
157
  inputs = { manifestable: transformed_command_class, request: }
@@ -156,49 +166,41 @@ module Foobara
156
166
  # :nocov:
157
167
  end
158
168
 
159
- command_class = Foobara::CommandConnectors::Commands::Describe
169
+ command_class = find_builtin_command_class("Describe")
160
170
  full_command_name = command_class.full_command_name
161
171
 
162
172
  inputs = { manifestable: type, request: }
163
173
  transformed_command_class = transformed_command_from_name(full_command_name) ||
164
174
  transform_command_class(command_class)
165
175
  when "manifest"
166
- command_class = Foobara::CommandConnectors::Commands::Describe
176
+ command_class = find_builtin_command_class("Describe")
167
177
  full_command_name = command_class.full_command_name
168
178
 
169
179
  inputs = { manifestable: self, request: }
170
180
  transformed_command_class = transformed_command_from_name(full_command_name) ||
171
181
  transform_command_class(command_class)
172
182
  when "ping"
173
- command_class = Foobara::CommandConnectors::Commands::Ping
183
+ command_class = find_builtin_command_class("Ping")
174
184
  full_command_name = command_class.full_command_name
175
185
 
176
186
  transformed_command_class = transformed_command_from_name(full_command_name) ||
177
187
  transform_command_class(command_class)
178
188
  when "query_git_commit_info"
179
189
  # TODO: this feels out of control... should just accomplish this through run I think instead. Same with ping.
180
- command_class = Foobara::CommandConnectors::Commands::QueryGitCommitInfo
190
+ command_class = find_builtin_command_class("QueryGitCommitInfo")
181
191
  full_command_name = command_class.full_command_name
182
192
 
183
193
  transformed_command_class = transformed_command_from_name(full_command_name) ||
184
194
  transform_command_class(command_class)
185
195
  when "help"
186
- command_class = self.class::Commands::Help
196
+ command_class = find_builtin_command_class("Help")
187
197
  full_command_name = command_class.full_command_name
188
198
 
189
199
  inputs = { request: }
190
200
  transformed_command_class = transformed_command_from_name(full_command_name) ||
191
201
  transform_command_class(command_class)
192
202
  when "list"
193
- mod = self.class::Commands
194
- command_class = if mod.const_defined?(:ListCommands)
195
- # TODO: test this
196
- # :nocov:
197
- mod::ListCommands
198
- # :nocov:
199
- else
200
- CommandConnectors::Commands::ListCommands
201
- end
203
+ command_class = find_builtin_command_class("ListCommands")
202
204
 
203
205
  full_command_name = command_class.full_command_name
204
206
 
@@ -226,10 +228,17 @@ module Foobara
226
228
  command_registry.create_exposed_command_without_domain(klass).transformed_command_class
227
229
  end
228
230
 
229
- def request_to_response(_command)
230
- # :nocov:
231
- raise "subclass responsibility"
232
- # :nocov:
231
+ def request_to_response(request)
232
+ command = request.command
233
+ outcome = command.outcome
234
+
235
+ status = outcome.success? ? 0 : 1
236
+
237
+ # TODO: feels awkward to call this here... Maybe use result/errors transformers instead??
238
+ # Or call the serializer here??
239
+ body = command.respond_to?(:serialize_result) ? command.serialize_result : request.response_body
240
+
241
+ self.class::Response.new(request:, status:, body:)
233
242
  end
234
243
 
235
244
  def initialize(authenticator: nil, default_serializers: nil)
@@ -104,6 +104,8 @@ module Foobara
104
104
  break if child.foobara_domain?
105
105
 
106
106
  break if child.foobara_organization?
107
+
108
+ # TODO: unclear why we need this check, hmmm, figure it out and document it (or delete if not needed)
107
109
  break if child.constants(false).any? do |constant|
108
110
  value = child.const_get(constant)
109
111
 
@@ -15,8 +15,6 @@ module Foobara
15
15
  # :nocov:
16
16
  end
17
17
 
18
- include(DomainModuleExtension)
19
-
20
18
  unless is_a?(Namespace::IsNamespace)
21
19
  foobara_namespace!
22
20
  foobara_autoset_namespace!(default_namespace: Foobara::GlobalOrganization)
@@ -28,6 +26,8 @@ module Foobara
28
26
  self.foobara_parent_namespace = parent
29
27
  end
30
28
 
29
+ include(DomainModuleExtension)
30
+
31
31
  children = foobara_children
32
32
  children = children.sort_by { |child| child.scoped_path.size }
33
33
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foobara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-12 00:00:00.000000000 Z
11
+ date: 2024-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: foobara-util
@@ -137,17 +137,17 @@ files:
137
137
  - projects/command/src/transformed_command.rb
138
138
  - projects/command_connectors/lib/foobara/command_connectors.rb
139
139
  - projects/command_connectors/src/command_connector.rb
140
+ - projects/command_connectors/src/command_connector/commands/describe.rb
141
+ - projects/command_connectors/src/command_connector/commands/list_commands.rb
142
+ - projects/command_connectors/src/command_connector/commands/ping.rb
143
+ - projects/command_connectors/src/command_connector/commands/query_git_commit_info.rb
144
+ - projects/command_connectors/src/command_connector/request.rb
145
+ - projects/command_connectors/src/command_connector/response.rb
140
146
  - projects/command_connectors/src/command_registry.rb
141
147
  - projects/command_connectors/src/command_registry/allowed_rule.rb
142
148
  - projects/command_connectors/src/command_registry/exposed_command.rb
143
149
  - projects/command_connectors/src/command_registry/exposed_domain.rb
144
150
  - projects/command_connectors/src/command_registry/exposed_organization.rb
145
- - projects/command_connectors/src/commands/describe.rb
146
- - projects/command_connectors/src/commands/list_commands.rb
147
- - projects/command_connectors/src/commands/ping.rb
148
- - projects/command_connectors/src/commands/query_git_commit_info.rb
149
- - projects/command_connectors/src/request.rb
150
- - projects/command_connectors/src/response.rb
151
151
  - projects/command_connectors/src/serializer.rb
152
152
  - projects/command_connectors/src/serializers/aggregate_serializer.rb
153
153
  - projects/command_connectors/src/serializers/atomic_serializer.rb
@@ -160,33 +160,6 @@ files:
160
160
  - projects/command_connectors/src/serializers/yaml_serializer.rb
161
161
  - projects/command_connectors/src/transformers/auth_errors_transformer.rb
162
162
  - projects/command_connectors/src/transformers/load_aggregates_pre_commit_transformer.rb
163
- - projects/command_connectors_http/lib/foobara/command_connectors_http.rb
164
- - projects/command_connectors_http/src/http.rb
165
- - projects/command_connectors_http/src/http/commands/get_options.rb
166
- - projects/command_connectors_http/src/http/commands/help.rb
167
- - projects/command_connectors_http/src/http/commands/help/presenter.rb
168
- - projects/command_connectors_http/src/http/commands/help/presenter/command.rb
169
- - projects/command_connectors_http/src/http/commands/help/presenter/domain.rb
170
- - projects/command_connectors_http/src/http/commands/help/presenter/entity.rb
171
- - projects/command_connectors_http/src/http/commands/help/presenter/error.rb
172
- - projects/command_connectors_http/src/http/commands/help/presenter/model.rb
173
- - projects/command_connectors_http/src/http/commands/help/presenter/organization.rb
174
- - projects/command_connectors_http/src/http/commands/help/presenter/processor.rb
175
- - projects/command_connectors_http/src/http/commands/help/presenter/processor_class.rb
176
- - projects/command_connectors_http/src/http/commands/help/presenter/root.rb
177
- - projects/command_connectors_http/src/http/commands/help/presenter/type.rb
178
- - projects/command_connectors_http/src/http/commands/help/templates/command.html.erb
179
- - projects/command_connectors_http/src/http/commands/help/templates/domain.html.erb
180
- - projects/command_connectors_http/src/http/commands/help/templates/entity.html.erb
181
- - projects/command_connectors_http/src/http/commands/help/templates/error.html.erb
182
- - projects/command_connectors_http/src/http/commands/help/templates/model.html.erb
183
- - projects/command_connectors_http/src/http/commands/help/templates/organization.html.erb
184
- - projects/command_connectors_http/src/http/commands/help/templates/processor.html.erb
185
- - projects/command_connectors_http/src/http/commands/help/templates/processor_class.html.erb
186
- - projects/command_connectors_http/src/http/commands/help/templates/root.html.erb
187
- - projects/command_connectors_http/src/http/commands/help/templates/type.html.erb
188
- - projects/command_connectors_http/src/http/request.rb
189
- - projects/command_connectors_http/src/http/response.rb
190
163
  - projects/common/lib/foobara/common.rb
191
164
  - projects/common/src/data_path.rb
192
165
  - projects/common/src/error.rb
@@ -395,7 +368,6 @@ require_paths:
395
368
  - "./projects/callback/lib"
396
369
  - "./projects/command/lib"
397
370
  - "./projects/command_connectors/lib"
398
- - "./projects/command_connectors_http/lib"
399
371
  - "./projects/common/lib"
400
372
  - "./projects/concerns/lib"
401
373
  - "./projects/delegate/lib"
@@ -427,7 +399,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
427
399
  - !ruby/object:Gem::Version
428
400
  version: '0'
429
401
  requirements: []
430
- rubygems_version: 3.5.18
402
+ rubygems_version: 3.5.22
431
403
  signing_key:
432
404
  specification_version: 4
433
405
  summary: Implements command pattern for encapsulating and managing domain complexity
@@ -1,6 +0,0 @@
1
- module Foobara
2
- module CommandConnectorsHttp
3
- end
4
-
5
- Monorepo.project :command_connectors_http
6
- end
@@ -1,16 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- # TODO: this is a bit of a hack, just a total no-op... shouldn't really need this command at all ideally
6
- class GetOptions < Foobara::Command
7
- result :string
8
-
9
- def execute
10
- ""
11
- end
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Command < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Domain < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Entity < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Error < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Model < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Organization < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Processor < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class ProcessorClass < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Root < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- class Presenter
7
- class Type < Presenter
8
- end
9
- end
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,178 +0,0 @@
1
- require_relative "presenter/command"
2
- require_relative "presenter/entity"
3
- require_relative "presenter/error"
4
- require_relative "presenter/model"
5
- require_relative "presenter/organization"
6
- require_relative "presenter/domain"
7
- require_relative "presenter/processor"
8
- require_relative "presenter/processor_class"
9
- require_relative "presenter/root"
10
- require_relative "presenter/type"
11
-
12
- module Foobara
13
- module CommandConnectors
14
- class Http < CommandConnector
15
- module Commands
16
- class Help < Command
17
- class Presenter
18
- class << self
19
- def for(manifest)
20
- case manifest
21
- when Manifest::RootManifest
22
- Presenter::Root
23
- when Manifest::Command
24
- Presenter::Command
25
- when Manifest::Entity
26
- Presenter::Entity
27
- when Manifest::Model
28
- Presenter::Model
29
- when Manifest::Type
30
- Presenter::Type
31
- when Manifest::Error
32
- Presenter::Error
33
- when Manifest::Domain
34
- Presenter::Domain
35
- when Manifest::Organization
36
- Presenter::Organization
37
- when Manifest::Processor
38
- Presenter::Processor
39
- when Manifest::ProcessorClass
40
- Presenter::ProcessorClass
41
- else
42
- # :nocov:
43
- raise "No presenter found for #{manifest.path}"
44
- # :nocov:
45
- end.new(manifest)
46
- end
47
-
48
- def template_symbol
49
- Util.underscore(Util.non_full_name(self))
50
- end
51
-
52
- def template_path
53
- template_path = File.join(
54
- __dir__,
55
- "templates",
56
- "#{template_symbol}.html.erb"
57
- )
58
- Pathname.new(template_path).cleanpath.to_s
59
- end
60
- end
61
-
62
- attr_accessor :manifest
63
-
64
- def initialize(manifest)
65
- self.manifest = manifest
66
- end
67
-
68
- def render_html_list(data, skip_wrapper: false)
69
- html = ""
70
-
71
- case data
72
- when ::Hash
73
- html << "<ul>" unless skip_wrapper
74
- data.each do |key, value|
75
- html << "<li>#{key}"
76
- html << "<ul>"
77
- html << render_html_list(value, skip_wrapper: true)
78
- html << "</ul>"
79
- html << "</li>"
80
- end
81
- html << "</ul>" unless skip_wrapper
82
- when ::Array
83
- html << "<ul>" unless skip_wrapper
84
- data.each do |item|
85
- html << render_html_list(item)
86
- end
87
- html << "</ul>" unless skip_wrapper
88
- when Manifest::Attributes
89
- html << "<ul>" unless skip_wrapper
90
- data.relevant_manifest.each_pair do |key, value|
91
- if key.to_s == "type"
92
- next
93
- end
94
-
95
- if key.to_s == "element_type_declarations"
96
- key = :attributes
97
- value = data.attribute_declarations
98
- end
99
- html << "<li>#{key}"
100
- html << "<ul>"
101
- html << render_html_list(value, skip_wrapper: true)
102
- html << "</ul>"
103
- html << "</li>"
104
- end
105
- html << "</ul>" unless skip_wrapper
106
- when Manifest::Array
107
- html << "<ul>" unless skip_wrapper
108
- data.relevant_manifest.each_pair do |key, value|
109
- next if key == :element_type_declaration
110
-
111
- if key.to_s == "type"
112
- value = root_manifest.lookup_path(key, value)
113
- end
114
- html << "<li>#{key}"
115
- html << "<ul>"
116
- html << render_html_list(value, skip_wrapper: true)
117
- html << "</ul>"
118
- html << "</li>"
119
- end
120
- html << render_html_list({ element_type: data.element_type }, skip_wrapper: true)
121
- html << "</ul>" unless skip_wrapper
122
- when Manifest::TypeDeclaration
123
- html << "<ul>" unless skip_wrapper
124
- data.relevant_manifest.each_pair do |key, value|
125
- if key.to_s == "type"
126
- value = root_manifest.lookup_path(key, value)
127
- end
128
- html << "<li>#{key}"
129
- html << "<ul>"
130
- html << render_html_list(value, skip_wrapper: true)
131
- html << "</ul>"
132
- html << "</li>"
133
- end
134
- html << "</ul>" unless skip_wrapper
135
- when Manifest::Type, Manifest::Command, Manifest::Error
136
- html << foobara_reference_link(data)
137
- when Manifest::PossibleError
138
- html << render_html_list(data.error)
139
- else
140
- html << "<li>#{data}</li>"
141
- end
142
-
143
- html
144
- end
145
-
146
- def foobara_reference_link(manifest)
147
- path = "/help/#{manifest.reference}"
148
-
149
- "<a href=\"#{path}\">#{manifest.reference.split("::").last}</a>"
150
- end
151
-
152
- def root_manifest
153
- @root_manifest ||= Manifest::RootManifest.new(manifest.root_manifest)
154
- end
155
-
156
- def template_path
157
- self.class.template_path
158
- end
159
-
160
- def method_missing(method_name, *, &)
161
- if manifest.respond_to?(method_name)
162
- manifest.send(method_name, *, &)
163
- else
164
- # :nocov:
165
- super
166
- # :nocov:
167
- end
168
- end
169
-
170
- def respond_to_missing?(method_name, include_private = false)
171
- manifest.respond_to?(method_name, include_private)
172
- end
173
- end
174
- end
175
- end
176
- end
177
- end
178
- end
@@ -1,11 +0,0 @@
1
- <h1><%= full_command_name %></h1>
2
- <p><%= description %></p>
3
-
4
- <h2>Inputs</h2>
5
- <%= render_html_list(inputs_type) %>
6
-
7
- <h2>Result</h2>
8
- <%= render_html_list(result_type) %>
9
-
10
- <h2>Possible Errors</h2>
11
- <%= render_html_list(possible_errors) %>
@@ -1,11 +0,0 @@
1
- <h1><%= full_entity_name %></h1>
2
- <p><%= description %></p>
3
-
4
- <h2>Attributes</h2>
5
- <%= render_html_list(attributes_type) %>
6
-
7
- <h2>Primary Key</h2>
8
- <%= primary_key_attribute %>
9
-
10
- <h2>Possible Errors</h2>
11
- <%= render_html_list(possible_errors) %>
@@ -1,8 +0,0 @@
1
- <h1><%= full_model_name %></h1>
2
- <p><%= description %></p>
3
-
4
- <h2>Attributes</h2>
5
- <%= render_html_list(attributes_type) %>
6
-
7
- <h2>Possible Errors</h2>
8
- <%= render_html_list(possible_errors) %>
@@ -1,3 +0,0 @@
1
- <h1>Commands</h1>
2
-
3
- <%= render_html_list(commands) %>
@@ -1,98 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- module Commands
5
- class Help < Command
6
- description "Will extract items from the request to help with. Assumes the help is desired in HTML format"
7
- inputs request: Request
8
- result :string
9
- possible_error CommandConnector::NotFoundError
10
-
11
- def execute
12
- load_manifest
13
- determine_object_to_help_with
14
- build_presenter
15
- load_template
16
- generate_html_from_template
17
- set_header_to_html
18
-
19
- html
20
- end
21
-
22
- attr_accessor :raw_manifest, :root_manifest, :object_to_help_with, :template, :html, :presenter
23
-
24
- def load_manifest
25
- self.raw_manifest = command_connector.foobara_manifest
26
- self.root_manifest = Manifest::RootManifest.new(raw_manifest)
27
- end
28
-
29
- def determine_object_to_help_with(mode: Namespace::LookupMode::ABSOLUTE)
30
- arg = request.argument
31
-
32
- if arg
33
- result = command_connector.command_registry.foobara_lookup(arg, mode:)
34
-
35
- if result
36
- self.object_to_help_with = result
37
- else
38
- result = GlobalOrganization.foobara_lookup(arg, mode:)
39
-
40
- if result && root_manifest.contains?(result.foobara_manifest_reference,
41
- result.scoped_category)
42
- self.object_to_help_with = result
43
- elsif mode == Namespace::LookupMode::ABSOLUTE
44
- determine_object_to_help_with(mode: Namespace::LookupMode::GENERAL)
45
- elsif mode == Namespace::LookupMode::GENERAL
46
- determine_object_to_help_with(mode: Namespace::LookupMode::RELAXED)
47
- else
48
- # TODO: add an input error instead for missing record to trigger 404
49
- add_runtime_error(CommandConnector::NotFoundError.new(arg))
50
- end
51
- end
52
- else
53
- self.object_to_help_with = root_manifest
54
- end
55
- end
56
-
57
- def build_presenter
58
- self.presenter = Help::Presenter.for(manifest_to_help_with)
59
- end
60
-
61
- def template_path
62
- presenter.template_path
63
- end
64
-
65
- def load_template
66
- template_body = File.read(template_path)
67
-
68
- erb = ERB.new(template_body)
69
- erb.filename = template_path
70
-
71
- self.template = erb
72
- end
73
-
74
- def generate_html_from_template
75
- self.html = template.result(presenter.instance_eval { binding })
76
- end
77
-
78
- def set_header_to_html
79
- request.response_headers ||= {}
80
- request.response_headers = request.response_headers.merge("content-type" => "text/html")
81
- end
82
-
83
- def manifest_to_help_with
84
- @manifest_to_help_with ||= if object_to_help_with.is_a?(Manifest::BaseManifest)
85
- object_to_help_with
86
- else
87
- root_manifest.lookup(object_to_help_with.foobara_manifest_reference)
88
- end
89
- end
90
-
91
- def command_connector
92
- request.command_connector
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,98 +0,0 @@
1
- require "uri"
2
-
3
- module Foobara
4
- module CommandConnectors
5
- class Http < CommandConnector
6
- class Request < CommandConnectors::Request
7
- attr_accessor :path,
8
- :method,
9
- :headers,
10
- :query_string,
11
- :body,
12
- :scheme,
13
- :host,
14
- :port,
15
- :cookies,
16
- :remote_ip,
17
- :response_headers
18
-
19
- def initialize(
20
- path:,
21
- method: nil,
22
- headers: {},
23
- query_string: "",
24
- body: "",
25
- scheme: nil,
26
- host: nil,
27
- port: nil,
28
- cookies: nil,
29
- remote_ip: nil
30
- )
31
- self.path = path
32
- self.method = method
33
- self.headers = headers
34
- self.query_string = query_string
35
- self.body = body
36
- self.scheme = scheme
37
- self.host = host
38
- self.port = port
39
- self.cookies = cookies
40
- self.remote_ip = remote_ip
41
-
42
- super()
43
- end
44
-
45
- def url
46
- URI::Generic.build(
47
- scheme:,
48
- host:,
49
- port:,
50
- path:,
51
- query: query_string.nil? || query_string.empty? ? nil : query_string
52
- ).to_s
53
- end
54
-
55
- def inputs
56
- @inputs ||= parsed_body.merge(parsed_query_string)
57
- end
58
-
59
- def full_command_name
60
- unless defined?(@full_command_name)
61
- set_action_and_command_name
62
- end
63
-
64
- @full_command_name
65
- end
66
-
67
- def parsed_body
68
- body.empty? ? {} : JSON.parse(body)
69
- end
70
-
71
- def parsed_query_string
72
- if query_string.nil? || query_string.empty?
73
- {}
74
- else
75
- # TODO: override this in rack connector to use better rack utils
76
- CGI.parse(query_string).transform_values!(&:first)
77
- end
78
- end
79
-
80
- def action
81
- unless defined?(@action)
82
- set_action_and_command_name
83
- end
84
-
85
- @action
86
- end
87
-
88
- def argument
89
- path.split("/")[2]
90
- end
91
-
92
- def set_action_and_command_name
93
- @action, @full_command_name = path[1..].split("/")
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,14 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- class Response < CommandConnectors::Response
5
- attr_accessor :headers
6
-
7
- def initialize(headers:, **)
8
- self.headers = headers
9
- super(**)
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,93 +0,0 @@
1
- module Foobara
2
- module CommandConnectors
3
- class Http < CommandConnector
4
- include TruncatedInspect
5
-
6
- def request_to_command(context)
7
- if context.method == "OPTIONS"
8
- # TODO: this feels a bit hacky and like overkill...
9
- return Foobara::CommandConnectors::Http::Commands::GetOptions.new
10
- end
11
-
12
- command = super
13
-
14
- if context.action == "help"
15
- # Let's unwrap the transformed command to avoid serialization
16
- # TODO: maybe instead register Help without serializers?
17
- command = command.command
18
- end
19
-
20
- command
21
- end
22
-
23
- # TODO: eliminate passing the command here...
24
- def request_to_response(request)
25
- command = request.command
26
- outcome = command.outcome
27
-
28
- # TODO: feels awkward to call this here... Maybe use result/errors transformers instead??
29
- # Or call the serializer here??
30
- body = command.respond_to?(:serialize_result) ? command.serialize_result : outcome.result
31
-
32
- status = if outcome.success?
33
- 200
34
- else
35
- errors = outcome.errors
36
-
37
- if errors.size == 1
38
- error = errors.first
39
-
40
- case error
41
- when CommandConnector::UnknownError
42
- 500
43
- when CommandConnector::NotFoundError, Foobara::Entity::NotFoundError
44
- # TODO: we should not be coupled to Entities here...
45
- body ||= "Not found"
46
- 404
47
- when CommandConnector::UnauthenticatedError
48
- 401
49
- when CommandConnector::NotAllowedError
50
- 403
51
- end
52
- end || 422
53
- end
54
-
55
- headers = headers_for(request)
56
-
57
- Response.new(status:, headers:, body:, request:)
58
- end
59
-
60
- def headers_for(request)
61
- response_headers = request.response_headers
62
-
63
- if response_headers.nil? || !response_headers.key?("content-type")
64
- if request.command.respond_to?(:serialize_result)
65
- # TODO: we should ask the request this not the command.
66
- if request.command.serializers.include?(Serializers::JsonSerializer)
67
- response_headers = (response_headers || {}).merge("content-type" => "application/json")
68
- end
69
- end
70
- end
71
-
72
- if response_headers
73
- static_headers.merge(response_headers)
74
- else
75
- static_headers.dup
76
- end
77
- end
78
-
79
- private
80
-
81
- def static_headers
82
- @static_headers ||= ENV.each_with_object({}) do |(key, value), headers|
83
- match = key.match(/\AFOOBARA_HTTP_RESPONSE_HEADER_(.*)\z/)
84
-
85
- if match
86
- header_name = match[1].downcase.tr("_", "-")
87
- headers[header_name] = value
88
- end
89
- end.freeze
90
- end
91
- end
92
- end
93
- end