jets 0.2.0 → 0.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 (292) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/bin/commit_docs.sh +26 -0
  3. data/.circleci/config.yml +126 -0
  4. data/.codebuild/README.md +57 -0
  5. data/.codebuild/bin/jets +3 -0
  6. data/.codebuild/buildspec-base.yml +14 -0
  7. data/.codebuild/integration.sh +54 -0
  8. data/.codebuild/jets.postman_collection.json +323 -0
  9. data/.codebuild/scripts/install-docker.sh +12 -0
  10. data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
  11. data/.codebuild/scripts/install-java.sh +20 -0
  12. data/.codebuild/scripts/install-node.sh +4 -0
  13. data/.gitignore +3 -0
  14. data/.gitmodules +9 -0
  15. data/.python-version +1 -0
  16. data/.rspec +2 -0
  17. data/.ruby-version +1 -1
  18. data/CHANGELOG.md +3 -0
  19. data/Dockerfile +16 -0
  20. data/Dockerfile.base +53 -0
  21. data/Gemfile +8 -1
  22. data/Gemfile.lock +132 -28
  23. data/LICENSE.txt +1 -1
  24. data/Procfile +2 -0
  25. data/README.md +116 -17
  26. data/Rakefile +6 -0
  27. data/buildspec.yml +18 -0
  28. data/exe/jets +14 -0
  29. data/jets.gemspec +31 -3
  30. data/lib/jets.rb +56 -8
  31. data/lib/jets/application.rb +121 -0
  32. data/lib/jets/application/middleware.rb +23 -0
  33. data/lib/jets/aws_services.rb +71 -0
  34. data/lib/jets/booter.rb +95 -0
  35. data/lib/jets/builders.rb +6 -0
  36. data/lib/jets/builders/code_builder.rb +431 -0
  37. data/lib/jets/builders/deducer.rb +73 -0
  38. data/lib/jets/builders/gem_replacer.rb +154 -0
  39. data/lib/jets/builders/handler_generator.rb +76 -0
  40. data/lib/jets/builders/node-hello.js +73 -0
  41. data/lib/jets/builders/node-shim.js +151 -0
  42. data/lib/jets/cfn.rb +5 -4
  43. data/lib/jets/cfn/ship.rb +178 -0
  44. data/lib/jets/cfn/status.rb +208 -0
  45. data/lib/jets/cfn/template_builders.rb +21 -0
  46. data/lib/jets/cfn/template_builders/api_gateway_builder.rb +73 -0
  47. data/lib/jets/cfn/template_builders/api_gateway_deployment_builder.rb +38 -0
  48. data/lib/jets/cfn/template_builders/base_child_builder.rb +38 -0
  49. data/lib/jets/cfn/template_builders/controller_builder.rb +107 -0
  50. data/lib/jets/cfn/template_builders/function_builder.rb +20 -0
  51. data/lib/jets/cfn/template_builders/function_properties.rb +6 -0
  52. data/lib/jets/cfn/template_builders/function_properties/base_builder.rb +106 -0
  53. data/lib/jets/cfn/template_builders/function_properties/node_builder.rb +12 -0
  54. data/lib/jets/cfn/template_builders/function_properties/python_builder.rb +12 -0
  55. data/lib/jets/cfn/template_builders/function_properties/ruby_builder.rb +13 -0
  56. data/lib/jets/cfn/template_builders/interface.rb +91 -0
  57. data/lib/jets/cfn/template_builders/job_builder.rb +63 -0
  58. data/lib/jets/cfn/template_builders/parent_builder.rb +97 -0
  59. data/lib/jets/cfn/template_builders/rule_builder.rb +55 -0
  60. data/lib/jets/cfn/template_builders/templates/minimal-stack.yml +45 -0
  61. data/lib/jets/cfn/template_mappers.rb +23 -0
  62. data/lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb +48 -0
  63. data/lib/jets/cfn/template_mappers/api_gateway_mapper.rb +4 -0
  64. data/lib/jets/cfn/template_mappers/child_mapper.rb +41 -0
  65. data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +34 -0
  66. data/lib/jets/cfn/template_mappers/controller_mapper.rb +36 -0
  67. data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +40 -0
  68. data/lib/jets/cfn/template_mappers/function_mapper.rb +4 -0
  69. data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +56 -0
  70. data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +62 -0
  71. data/lib/jets/cfn/template_mappers/job_mapper.rb +4 -0
  72. data/lib/jets/cfn/template_mappers/lambda_function_mapper.rb +50 -0
  73. data/lib/jets/cfn/template_mappers/rule_mapper.rb +5 -0
  74. data/lib/jets/cli.rb +180 -15
  75. data/lib/jets/commands.rb +22 -0
  76. data/lib/jets/commands/base.rb +151 -0
  77. data/lib/jets/commands/build.rb +186 -0
  78. data/lib/jets/commands/call.rb +175 -0
  79. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  80. data/lib/jets/commands/call/autoload_guesser.rb +112 -0
  81. data/lib/jets/commands/call/base_guesser.rb +33 -0
  82. data/lib/jets/commands/call/guesser.rb +51 -0
  83. data/lib/jets/commands/console.rb +12 -0
  84. data/lib/jets/commands/db.rb +15 -0
  85. data/lib/jets/commands/db/environment-task.rake +3 -0
  86. data/lib/jets/commands/db/tasks.rb +30 -0
  87. data/lib/jets/commands/dbconsole.rb +131 -0
  88. data/lib/jets/commands/delete.rb +119 -0
  89. data/lib/jets/commands/deploy.rb +53 -0
  90. data/lib/jets/commands/dynamodb.rb +22 -0
  91. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  92. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  93. data/lib/jets/commands/help.rb +9 -0
  94. data/lib/jets/commands/help/build.md +1 -0
  95. data/lib/jets/commands/help/call.md +55 -0
  96. data/lib/jets/commands/help/console.md +4 -0
  97. data/lib/jets/commands/help/db/generate.md +8 -0
  98. data/lib/jets/commands/help/dbconsole.md +5 -0
  99. data/lib/jets/commands/help/delete.md +9 -0
  100. data/lib/jets/commands/help/deploy.md +5 -0
  101. data/lib/jets/commands/help/dynamodb/generate.md +50 -0
  102. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  103. data/lib/jets/commands/help/generate.md +5 -0
  104. data/lib/jets/commands/help/new.md +9 -0
  105. data/lib/jets/commands/help/process/controller.md +6 -0
  106. data/lib/jets/commands/help/process/function.md +5 -0
  107. data/lib/jets/commands/help/process/job.md +5 -0
  108. data/lib/jets/commands/help/process/rule.md +5 -0
  109. data/lib/jets/commands/help/routes.md +3 -0
  110. data/lib/jets/commands/help/server.md +6 -0
  111. data/lib/jets/commands/help/status.md +1 -0
  112. data/lib/jets/commands/help/url.md +5 -0
  113. data/lib/jets/commands/main.rb +111 -0
  114. data/lib/jets/commands/markdown.rb +8 -0
  115. data/lib/jets/commands/markdown/creator.rb +58 -0
  116. data/lib/jets/commands/markdown/index.rb +27 -0
  117. data/lib/jets/commands/markdown/page.rb +125 -0
  118. data/lib/jets/commands/markdown/shell.rb +11 -0
  119. data/lib/jets/commands/new.rb +110 -0
  120. data/lib/jets/commands/rake_command.rb +61 -0
  121. data/lib/jets/commands/rake_tasks.rb +45 -0
  122. data/lib/jets/commands/sequence.rb +44 -0
  123. data/lib/jets/commands/stack_info.rb +30 -0
  124. data/lib/jets/commands/templates/skeleton/.env +2 -0
  125. data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
  126. data/lib/jets/commands/templates/skeleton/.env.test +3 -0
  127. data/lib/jets/commands/templates/skeleton/.gitignore +14 -0
  128. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  129. data/lib/jets/commands/templates/skeleton/Gemfile.tt +27 -0
  130. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  131. data/lib/jets/commands/templates/skeleton/README.md +4 -0
  132. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  133. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  134. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  135. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +2 -0
  136. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  137. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  138. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +24 -0
  139. data/lib/jets/commands/templates/skeleton/bin/ruby_server +18 -0
  140. data/lib/jets/commands/templates/skeleton/bin/ruby_server.rb +2 -0
  141. data/lib/jets/commands/templates/skeleton/config.ru +4 -0
  142. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +26 -0
  143. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
  144. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +25 -0
  145. data/lib/jets/commands/templates/skeleton/config/routes.rb +8 -0
  146. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  147. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  148. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  149. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  150. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  151. data/lib/jets/commands/templates/skeleton/public/index.html.tt +79 -0
  152. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +18 -0
  153. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  154. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  155. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +27 -0
  156. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  157. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  158. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  159. data/lib/jets/commands/url.rb +45 -0
  160. data/lib/jets/commands/webpacker_template.rb +19 -0
  161. data/lib/jets/controller.rb +9 -0
  162. data/lib/jets/controller/base.rb +50 -0
  163. data/lib/jets/controller/callbacks.rb +43 -0
  164. data/lib/jets/controller/layout.rb +17 -0
  165. data/lib/jets/controller/params.rb +53 -0
  166. data/lib/jets/controller/redirection.rb +55 -0
  167. data/lib/jets/controller/renderers.rb +5 -0
  168. data/lib/jets/controller/renderers/aws_proxy_renderer.rb +69 -0
  169. data/lib/jets/controller/renderers/base_renderer.rb +16 -0
  170. data/lib/jets/controller/renderers/template_renderer.rb +107 -0
  171. data/lib/jets/controller/rendering.rb +80 -0
  172. data/lib/jets/controller/request.rb +55 -0
  173. data/lib/jets/core.rb +81 -0
  174. data/lib/jets/default/application.rb +20 -0
  175. data/lib/jets/dotenv.rb +37 -0
  176. data/lib/jets/erb.rb +51 -0
  177. data/lib/jets/generator.rb +40 -0
  178. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  179. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  180. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  181. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  182. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  183. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  184. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  185. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  186. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  187. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  188. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  189. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  190. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +71 -0
  191. data/lib/jets/internal/app/controllers/jets/public_controller.rb +30 -0
  192. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +47 -0
  193. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
  194. data/lib/jets/internal/app/controllers/jets/welcome_controller.rb +22 -0
  195. data/lib/jets/internal/app/controllers/jets/welcome_controller/python/index.py +24 -0
  196. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +52 -0
  197. data/lib/jets/job.rb +5 -0
  198. data/lib/jets/job/base.rb +29 -0
  199. data/lib/jets/job/dsl.rb +58 -0
  200. data/lib/jets/job/task.rb +17 -0
  201. data/lib/jets/klass.rb +71 -0
  202. data/lib/jets/lambda.rb +18 -0
  203. data/lib/jets/lambda/dsl.rb +153 -0
  204. data/lib/jets/lambda/function.rb +29 -0
  205. data/lib/jets/lambda/function_constructor.rb +60 -0
  206. data/lib/jets/lambda/functions.rb +22 -0
  207. data/lib/jets/lambda/task.rb +77 -0
  208. data/lib/jets/naming.rb +61 -0
  209. data/lib/jets/pascalize.rb +30 -0
  210. data/lib/jets/poly_fun.rb +61 -0
  211. data/lib/jets/poly_fun/base_executor.rb +129 -0
  212. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  213. data/lib/jets/poly_fun/node_error.rb +8 -0
  214. data/lib/jets/poly_fun/node_executor.rb +54 -0
  215. data/lib/jets/poly_fun/python_error.rb +8 -0
  216. data/lib/jets/poly_fun/python_executor.rb +23 -0
  217. data/lib/jets/preheat.rb +72 -0
  218. data/lib/jets/processors.rb +4 -0
  219. data/lib/jets/processors/deducer.rb +54 -0
  220. data/lib/jets/processors/main_processor.rb +57 -0
  221. data/lib/jets/rails_overrides.rb +4 -0
  222. data/lib/jets/rails_overrides/asset_tag_helper.rb +41 -0
  223. data/lib/jets/rails_overrides/common_methods.rb +13 -0
  224. data/lib/jets/rails_overrides/rendering_helper.rb +26 -0
  225. data/lib/jets/rails_overrides/url_helper.rb +26 -0
  226. data/lib/jets/route.rb +145 -0
  227. data/lib/jets/router.rb +115 -0
  228. data/lib/jets/ruby_server.rb +91 -0
  229. data/lib/jets/rule.rb +5 -0
  230. data/lib/jets/rule/base.rb +19 -0
  231. data/lib/jets/rule/dsl.rb +64 -0
  232. data/lib/jets/rule/task.rb +44 -0
  233. data/lib/jets/server.rb +16 -0
  234. data/lib/jets/server/api_gateway.rb +39 -0
  235. data/lib/jets/server/lambda_aws_proxy.rb +122 -0
  236. data/lib/jets/server/route_matcher.rb +96 -0
  237. data/lib/jets/server/timing_middleware.rb +16 -0
  238. data/lib/jets/server/webpacker_setup.rb +7 -0
  239. data/lib/jets/timing.rb +65 -0
  240. data/lib/jets/timing/report.rb +82 -0
  241. data/lib/jets/util.rb +7 -12
  242. data/lib/jets/version.rb +1 -1
  243. data/support/clean +3 -0
  244. data/support/console +3 -0
  245. metadata +473 -76
  246. data/bin/jets +0 -14
  247. data/lib/jets/base_controller.rb +0 -54
  248. data/lib/jets/build.rb +0 -46
  249. data/lib/jets/build/handler_generator.rb +0 -46
  250. data/lib/jets/build/lambda_deducer.rb +0 -23
  251. data/lib/jets/build/templates/handler.js +0 -149
  252. data/lib/jets/build/traveling_ruby.rb +0 -133
  253. data/lib/jets/cfn/base.rb +0 -17
  254. data/lib/jets/cfn/builder.rb +0 -53
  255. data/lib/jets/cfn/namer.rb +0 -30
  256. data/lib/jets/cli/help.rb +0 -19
  257. data/lib/jets/command.rb +0 -25
  258. data/lib/jets/process.rb +0 -18
  259. data/lib/jets/process/base_processor.rb +0 -23
  260. data/lib/jets/process/controller_processor.rb +0 -36
  261. data/lib/jets/process/help.rb +0 -11
  262. data/lib/jets/process/processor_deducer.rb +0 -51
  263. data/lib/jets/project.rb +0 -23
  264. data/notes/design.md +0 -107
  265. data/notes/faq.md +0 -3
  266. data/notes/lambda_ruby_info.md +0 -34
  267. data/notes/traveling-ruby-packaging-jets.md +0 -26
  268. data/notes/traveling-ruby-packaging.md +0 -103
  269. data/notes/traveling-ruby-structure.md +0 -6
  270. data/notes/traveling-ruby.md +0 -82
  271. data/spec/fixtures/classes.rb +0 -5
  272. data/spec/fixtures/project/.gitignore +0 -3
  273. data/spec/fixtures/project/.ruby-version +0 -1
  274. data/spec/fixtures/project/Gemfile +0 -4
  275. data/spec/fixtures/project/Gemfile.lock +0 -23
  276. data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
  277. data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
  278. data/spec/fixtures/project/bin/jets +0 -22
  279. data/spec/fixtures/project/config/routes.rb +0 -6
  280. data/spec/fixtures/project/handlers/controllers/posts.js +0 -212
  281. data/spec/lib/cli_spec.rb +0 -20
  282. data/spec/lib/jets/base_controller_spec.rb +0 -18
  283. data/spec/lib/jets/build/handler_generator_spec.rb +0 -20
  284. data/spec/lib/jets/build/lambda_deducer_spec.rb +0 -15
  285. data/spec/lib/jets/build_spec.rb +0 -34
  286. data/spec/lib/jets/cfn/builder_spec.rb +0 -18
  287. data/spec/lib/jets/cfn/namer_spec.rb +0 -16
  288. data/spec/lib/jets/process/controller_processor_spec.rb +0 -22
  289. data/spec/lib/jets/process/infer_spec.rb +0 -24
  290. data/spec/lib/jets/process_spec.rb +0 -18
  291. data/spec/lib/jets/project_spec.rb +0 -14
  292. data/spec/spec_helper.rb +0 -28
@@ -0,0 +1,45 @@
1
+ module Jets::Commands
2
+ class Url
3
+ include Jets::AwsServices
4
+
5
+ def initialize(options)
6
+ @options = options
7
+ end
8
+
9
+ def display
10
+ stack_name = Jets::Naming.parent_stack_name
11
+ stack = cfn.describe_stacks(stack_name: stack_name).stacks.first
12
+
13
+ unless stack
14
+ puts "Stack for '#{Jets.config.project_name} project for environment #{Jets.env}. Couldn't find '#{stack_name}' stack."
15
+ exit
16
+ end
17
+
18
+ api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway")
19
+ if api_gateway_stack_arn
20
+ STDOUT.puts get_url(api_gateway_stack_arn)
21
+ else
22
+ puts "API Gateway not found. This jets app does have an API Gateway associated with it. Please double check your config/routes.rb if you were expecting to see a url for the app."
23
+ end
24
+ end
25
+
26
+ def get_url(api_gateway_stack_arn)
27
+ stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first
28
+ rest_api = lookup(stack[:outputs], "RestApi")
29
+ region_id = lookup(stack[:outputs], "Region")
30
+ # Abusing ApiGatewayDeploymentMapper
31
+ # set path=nil,s3_bucket=nil
32
+ # not using any methods that rely on the initialization parameters
33
+ map = Jets::Cfn::TemplateMappers::ApiGatewayDeploymentMapper.new(path=nil,s3_bucket=nil)
34
+ # https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
35
+ # https://my-api-id.execute-api.region-id.amazonaws.com/stage-name/{resourcePath}
36
+ "https://#{rest_api}.execute-api.#{region_id}.amazonaws.com/#{map.stage_name}"
37
+ end
38
+
39
+ # Lookup output value
40
+ def lookup(outputs, key)
41
+ o = outputs.find { |o| o.output_key == key }
42
+ o.output_value
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ require 'thor'
2
+
3
+ # These commands are ran after rake webpacker:install to enhance the generated
4
+ # javascript assets to support Jets.
5
+ # Done this way so it works for both jets new and jets webpacker:install
6
+ class Jets::Commands::WebpackerTemplate < Thor::Group
7
+ include Thor::Actions
8
+
9
+ class_option :force, desc: "Bypass confirmation and overwrite existing files."
10
+ class_option :bootstrap, type: :boolean, default: true, desc: "Install bootstrap"
11
+ def self.source_root
12
+ File.expand_path("templates/webpacker", File.dirname(__FILE__))
13
+ end
14
+
15
+ def reapply_templates
16
+ puts "options #{options.inspect}"
17
+ directory "app/javascript", "app/javascript", force: options[:force]#, bootstrap: options[:bootstrap]
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ class Jets::Controller
2
+ autoload :Base, "jets/controller/base"
3
+ autoload :Layout, "jets/controller/layout"
4
+ autoload :Callbacks, "jets/controller/callbacks"
5
+ autoload :Request, "jets/controller/request"
6
+ autoload :Rendering, "jets/controller/rendering"
7
+ autoload :Redirection, "jets/controller/redirection"
8
+ autoload :Params, "jets/controller/params"
9
+ end
@@ -0,0 +1,50 @@
1
+ require "active_support/core_ext/hash"
2
+ require "active_support/core_ext/object"
3
+ require "json"
4
+ require "rack/utils" # Rack::Utils.parse_nested_query
5
+
6
+ # Controller public methods get turned into Lambda functions.
7
+ class Jets::Controller
8
+ class Base < Jets::Lambda::Functions
9
+ include Layout
10
+ include Callbacks
11
+ include Rendering
12
+ include Params
13
+
14
+ def self.process(event, context={}, meth)
15
+ t1 = Time.now
16
+ Jets.logger.info "Processing by #{self}##{meth}"
17
+
18
+ controller = new(event, context, meth)
19
+
20
+ Jets.logger.info " Event: #{event.inspect}"
21
+ Jets.logger.info " Parameters: #{controller.params(true).to_h.inspect}"
22
+
23
+ controller.run_before_actions
24
+ controller.send(meth)
25
+ resp = controller.ensure_render
26
+ controller.run_after_actions
27
+
28
+ time = Time.now - t1
29
+ Jets.logger.info "Completed Status Code #{resp["statusCode"]} in #{time}s"
30
+
31
+ resp
32
+ end
33
+
34
+ delegate :headers, to: :request
35
+ attr_reader :request
36
+ def initialize(event, context={}, meth)
37
+ super
38
+ @request = Request.new(event)
39
+ end
40
+
41
+ class_attribute :internal_controller
42
+ def self.internal(value=nil)
43
+ if !value.nil?
44
+ self.internal_controller = value
45
+ else
46
+ self.internal_controller
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,43 @@
1
+ # Simpified version of callbacks
2
+ # Does not support if
3
+ class Jets::Controller
4
+ module Callbacks
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ class_attribute :before_actions
8
+ self.before_actions = []
9
+ class_attribute :after_actions
10
+ self.after_actions = []
11
+
12
+ def self.before_action(meth, options={})
13
+ self.before_actions += [[meth, options]]
14
+ end
15
+
16
+ def self.after_action(meth, options={})
17
+ self.after_actions += [[meth, options]]
18
+ end
19
+ end # included
20
+
21
+ # Instance Methods
22
+ # define run_before_actions and run_after_actions
23
+ [:before, :after].each do |type|
24
+ define_method "run_#{type}_actions" do
25
+ called_method = @meth.to_sym
26
+ callbacks = self.class.send("#{type}_actions")
27
+ callbacks.each do |array|
28
+ callback, options = array
29
+
30
+ except = options[:except]
31
+ next if except && except.include?(called_method)
32
+
33
+ only = options[:only]
34
+ if only
35
+ send(callback) if only.include?(called_method)
36
+ else
37
+ send(callback)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end # ClassOptions
43
+ end
@@ -0,0 +1,17 @@
1
+ class Jets::Controller
2
+ module Layout
3
+ extend ActiveSupport::Concern
4
+ included do
5
+ class_attribute :layout_name
6
+
7
+ def self.layout(name=nil)
8
+ if !name.nil?
9
+ name = name.to_s if name.is_a?(Symbol)
10
+ self.layout_name = name
11
+ else
12
+ self.layout_name
13
+ end
14
+ end
15
+ end # included
16
+ end # Layout
17
+ end
@@ -0,0 +1,53 @@
1
+ require "action_controller/metal/strong_parameters"
2
+
3
+ class Jets::Controller
4
+ module Params
5
+ # Merge all the parameters together for convenience. Users still have
6
+ # access via events.
7
+ #
8
+ # Precedence:
9
+ # 1. path parameters have highest precdence
10
+ # 2. query string parameters
11
+ # 3. body parameters
12
+ def params(raw=false)
13
+ query_string_params = event["queryStringParameters"] || {}
14
+ path_params = event["pathParameters"] || {}
15
+ params = body_params
16
+ .deep_merge(query_string_params)
17
+ .deep_merge(path_params)
18
+ if raw
19
+ params
20
+ else
21
+ ActionController::Parameters.new(params)
22
+ end
23
+ end
24
+
25
+ private
26
+ def body_params
27
+ body = event["body"]
28
+ return {} if body.nil?
29
+
30
+ # Try json parsing
31
+ parsed_json = parse_json(body)
32
+ return parsed_json if parsed_json
33
+
34
+
35
+ # For content-type application/x-www-form-urlencoded CGI.parse the body
36
+ headers = event["headers"] || {}
37
+ headers = headers.transform_keys { |key| key.downcase }
38
+ # API Gateway seems to use either: content-type or Content-Type
39
+ content_type = headers["content-type"]
40
+ if content_type.to_s.include?("application/x-www-form-urlencoded")
41
+ return Rack::Utils.parse_nested_query(body)
42
+ end
43
+
44
+ {} # fallback to empty Hash
45
+ end
46
+
47
+ def parse_json(text)
48
+ JSON.parse(text)
49
+ rescue JSON::ParserError
50
+ nil
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,55 @@
1
+ class Jets::Controller
2
+ module Redirection
3
+ # redirect_to "/posts", :status => 301
4
+ # redirect_to :action=>'atom', :status => 302
5
+ def redirect_to(url, options={})
6
+ unless url.is_a?(String)
7
+ raise "redirect_to url parameter must be a String. Please pass in a string"
8
+ end
9
+
10
+ uri = URI.parse(url)
11
+ # if no location.host, we been provided a relative host
12
+ if !uri.host && actual_host
13
+ url = "/#{url}" unless url.starts_with?('/')
14
+ url = add_stage_name(url)
15
+ redirect_url = actual_host + url
16
+ else
17
+ redirect_url = url
18
+ end
19
+
20
+ redirect_url = ensure_protocol(redirect_url)
21
+
22
+ aws_proxy = Renderers::AwsProxyRenderer.new(self,
23
+ status: options[:status] || 302,
24
+ headers: { "Location" => redirect_url },
25
+ body: "",
26
+ isBase64Encoded: false,
27
+ )
28
+ resp = aws_proxy.render
29
+ # redirect is a type of rendering
30
+ @rendered = true
31
+ @rendered_data = resp
32
+ end
33
+
34
+ def ensure_protocol(url)
35
+ return url if url.starts_with?('http')
36
+
37
+ # annoying but the request payload is different with localhost/rack vs
38
+ # api gateway
39
+ # check out:
40
+ # spec/fixtures/dumps/api_gateway/posts/create.json
41
+ # spec/fixtures/dumps/rack/posts/create.json
42
+ protocol = if actual_host.include?("amazonaws.com") # API Gateway
43
+ headers["x-forwarded-proto"]
44
+ elsif headers["origin"] # Rack / localhost
45
+ URI.parse(headers["origin"]).scheme
46
+ else
47
+ "http" # fallback. Capybara / Selenium tests
48
+ end
49
+
50
+ raise "Invalid protocol #{protocol}" unless protocol.starts_with?('http')
51
+
52
+ "#{protocol}://#{url}"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ module Jets::Controller::Renderers
2
+ autoload :AwsProxyRenderer, "jets/controller/renderers/aws_proxy_renderer"
3
+ autoload :BaseRenderer, "jets/controller/renderers/base_renderer"
4
+ autoload :TemplateRenderer, "jets/controller/renderers/template_renderer"
5
+ end
@@ -0,0 +1,69 @@
1
+ require "rack/utils"
2
+
3
+ # Special renderer. All the other renderers lead here
4
+ module Jets::Controller::Renderers
5
+ class AwsProxyRenderer < BaseRenderer
6
+ # Transform the structure to AWS_PROXY compatiable structure
7
+ # http://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format
8
+ # Example response:
9
+ #
10
+ # {
11
+ # "statusCode" => status,
12
+ # "headers" => headers,
13
+ # "body" => body,
14
+ # "isBase64Encoded" => base64,
15
+ # }
16
+ def render
17
+ # we do some normalization here
18
+ status = map_status_code(@options[:status]) || 200
19
+ status = status.to_s # API Gateway requires a string but rack is okay with either
20
+ body = @options[:body]
21
+ base64 = normalized_base64_option(@options)
22
+
23
+ headers = @options[:headers] || {}
24
+ headers = cors_headers.merge(headers)
25
+ headers["Content-Type"] ||= @options[:content_type] || "text/html; charset=utf-8"
26
+
27
+ # Compatiable Lambda Proxy response Hash.
28
+ # Additional extra keys results in compatiability. Explictly assign keys.
29
+ {
30
+ "statusCode" => status,
31
+ "headers" => headers,
32
+ "body" => body,
33
+ "isBase64Encoded" => base64,
34
+ }
35
+ end
36
+
37
+ # maps:
38
+ # :continue => 100
39
+ # :success => 200
40
+ # etc
41
+ def map_status_code(code)
42
+ if code.is_a?(Symbol)
43
+ Rack::Utils::SYMBOL_TO_STATUS_CODE[code]
44
+ else
45
+ code
46
+ end
47
+ end
48
+
49
+ def normalized_base64_option(options)
50
+ base64 = @options[:base64] if options.key?(:base64)
51
+ base64 = @options[:isBase64Encoded] if options.key?(:isBase64Encoded)
52
+ base64
53
+ end
54
+
55
+ def cors_headers
56
+ case Jets.config.cors
57
+ when true
58
+ {
59
+ "Access-Control-Allow-Origin" => "*", # Required for CORS support to work
60
+ "Access-Control-Allow-Credentials" => "true" # Required for cookies, authorization headers with HTTPS
61
+ }
62
+ when Hash
63
+ Jets.config.cors # contains Hash with Access-Control-Allow-* values
64
+ else
65
+ {}
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,16 @@
1
+ # Interface:
2
+ # subclasses must implement render
3
+ module Jets::Controller::Renderers
4
+ class BaseRenderer
5
+ delegate :request, :event, :headers, to: :controller
6
+ attr_reader :controller
7
+ def initialize(controller, options={})
8
+ @controller = controller
9
+ @options = options
10
+ end
11
+
12
+ def render_aws_proxy(options)
13
+ AwsProxyRenderer.new(@controller, options).render
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,107 @@
1
+ module Jets::Controller::Renderers
2
+ class TemplateRenderer < BaseRenderer
3
+ def controller_instance_variables
4
+ instance_vars = @controller.instance_variables.inject({}) do |vars, v|
5
+ k = v.to_s.sub(/^@/,'') # @var => var
6
+ vars[k] = @controller.instance_variable_get(v)
7
+ vars
8
+ end
9
+ instance_vars[:event] = event
10
+ instance_vars
11
+ end
12
+
13
+ def render
14
+ setup_action_controller # setup only when necessary
15
+
16
+ # Rails rendering does heavy lifting
17
+ renderer = ActionController::Base.renderer.new(renderer_options)
18
+ body = renderer.render(render_options)
19
+ @options[:body] = body # important to set as it was originally nil
20
+
21
+ render_aws_proxy(@options)
22
+ end
23
+
24
+ # Example: posts/index
25
+ def default_template_name
26
+ "#{template_namespace}/#{@controller.meth}"
27
+ end
28
+
29
+ # PostsController => "posts" is the namespace
30
+ def template_namespace
31
+ @controller.class.to_s.sub('Controller','').underscore.pluralize
32
+ end
33
+
34
+ # default options:
35
+ # https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/renderer.rb#L41-L47
36
+ def renderer_options
37
+ origin = headers["origin"]
38
+ if origin
39
+ uri = URI.parse(origin)
40
+ https = uri.scheme == "https"
41
+ end
42
+ options = {
43
+ http_host: headers["host"],
44
+ https: https,
45
+ # script_name: "",
46
+ # input: ""
47
+ }
48
+ @options[:method] = event["httpMethod"].downcase if event["httpMethod"]
49
+ options
50
+ end
51
+
52
+ def render_options
53
+ # nomralize the template option
54
+ template = @options[:template]
55
+ if template and !template.include?('/')
56
+ template = "#{template_namespace}/#{template}"
57
+ end
58
+ template ||= default_template_name
59
+ # ready to override @options[:template]
60
+ @options[:template] = template if @options[:template]
61
+
62
+ render_options = {
63
+ template: template, # weird: template needs to be set no matter because it
64
+ # sets the name which is used in lookup_context.rb:209:in `normalize_name'
65
+ layout: @options[:layout],
66
+ assigns: controller_instance_variables,
67
+ }
68
+ types = %w[json inline plain file xml body action].map(&:to_sym)
69
+ types.each do |type|
70
+ render_options[type] = @options[type] if @options[type]
71
+ end
72
+
73
+ render_options
74
+ end
75
+
76
+ def setup_action_controller
77
+ require "action_controller"
78
+ require "jets/rails_overrides"
79
+
80
+ # laod helpers
81
+ helper_class = self.class.name.to_s.sub("Controller", "Helper")
82
+ helper_path = "#{Jets.root}app/helpers/#{helper_class.underscore}.rb"
83
+ ActiveSupport.on_load :action_view do
84
+ include ApplicationHelper
85
+ include helper_class.constantize if File.exist?(helper_path)
86
+ end
87
+
88
+ ActionController::Base.append_view_path("#{Jets.root}app/views")
89
+
90
+ setup_webpacker if Jets.webpacker?
91
+ end
92
+
93
+ def setup_webpacker
94
+ require 'webpacker'
95
+ require 'webpacker/helper'
96
+
97
+ ActiveSupport.on_load :action_controller do
98
+ ActionController::Base.helper Webpacker::Helper
99
+ end
100
+
101
+ ActiveSupport.on_load :action_view do
102
+ include Webpacker::Helper
103
+ end
104
+ end
105
+
106
+ end
107
+ end