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,8 @@
1
+ class Jets::PolyFun
2
+ class PythonError < StandardError
3
+ def initialize(message, backtrace)
4
+ super(message)
5
+ set_backtrace(backtrace)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,23 @@
1
+ class Jets::PolyFun
2
+ class PythonExecutor < BaseExecutor
3
+ # Code for wrapper script that mimics lambda execution. Wrapper script usage:
4
+ #
5
+ # python WRAPPER_SCRIPT EVENT
6
+ #
7
+ # Example:
8
+ #
9
+ # python /tmp/jets/demo/executor/20180804-12816-imqb9/lambda_executor.py '{}'
10
+ def code
11
+ <<-EOL
12
+ import sys
13
+ import json
14
+ from #{@task.meth} import #{handler}
15
+ event = json.loads(sys.argv[1])
16
+ context = {}
17
+ resp = #{handler}(event, context)
18
+ result = json.dumps(resp)
19
+ print(result)
20
+ EOL
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,72 @@
1
+ module Jets
2
+ class Preheat
3
+ extend Memoist
4
+
5
+ # Examples:
6
+ #
7
+ # Jets::Preheat.warm("posts_controller-index")
8
+ # Jets::Preheat.warm("jets-preheat_job-warm")
9
+ #
10
+ def self.warm(function_name, options={})
11
+ Preheat.new(options).warm(function_name)
12
+ end
13
+
14
+ def self.warm_all(options={})
15
+ Preheat.new(options).warm_all
16
+ end
17
+
18
+ def initialize(options)
19
+ @options = options # passed to Call.new options
20
+ @options[:mute_output] = true if @options[:mute_output].nil?
21
+ end
22
+
23
+ def warm(function_name)
24
+ Jets::Commands::Call.new(function_name, '{"_prewarm": "1"}', @options).run unless ENV['TEST']
25
+ end
26
+
27
+ # loop through all methods fo each class
28
+ # make the special prewarm call to keep them warm
29
+ def warm_all
30
+ threads = []
31
+ all_functions.each do |function_name|
32
+ threads << Thread.new do
33
+ warm(function_name)
34
+ end
35
+ end
36
+ threads.each { |t| t.join }
37
+ # return the funciton names so we can see in the Lambda console
38
+ # the functions being prewarmed
39
+ all_functions
40
+ end
41
+
42
+ # Returns:
43
+ # [
44
+ # "posts_controller-index",
45
+ # "posts_controller-show",
46
+ # ...
47
+ # ]
48
+ def all_functions
49
+ classes.map do |klass|
50
+ tasks = klass.tasks.select { |t| t.lang == :ruby } # only prewarm ruby functions
51
+ tasks.map do |task|
52
+ meth = task.meth
53
+ underscored = klass.to_s.underscore.gsub('/','-')
54
+ "#{underscored}-#{meth}" # function_name
55
+ end
56
+ end.flatten.uniq.compact
57
+ end
58
+ memoize :all_functions
59
+
60
+ def classes
61
+ Jets::Commands::Build.app_files.map do |path|
62
+ next if path.include?("preheat_job.rb") # dont want to cause an infinite loop
63
+ next if path =~ %r{app/functions} # dont support app/functions
64
+
65
+ class_path = path.sub(%r{.*app/\w+/},'').sub(/\.rb$/,'')
66
+ class_name = class_path.classify
67
+ # IE: PostsController
68
+ class_name.constantize # load app/**/* class definition
69
+ end.compact
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,4 @@
1
+ module Jets::Processors
2
+ autoload :Deducer, 'jets/processors/deducer'
3
+ autoload :MainProcessor, 'jets/processors/main_processor'
4
+ end
@@ -0,0 +1,54 @@
1
+ # Jets::Processors::Deducer class figures out information that allows the
2
+ # controller or job to be called. Sme key methods for deducer:
3
+ #
4
+ # code - code to instance eval. IE: PostsController.new(event, context).index
5
+ # path - full path to the app code. IE: #{Jets.root}app/controllers/posts_controller.rb
6
+ #
7
+ class Jets::Processors::Deducer
8
+ def initialize(handler)
9
+ @handler = handler # handlers/controllers/posts.show
10
+ # @handler_path: "handlers/controllers/posts"
11
+ # @handler_method: "show"
12
+ @handler_path, @handler_method = @handler.split('.')
13
+ end
14
+
15
+ def code
16
+ # code: "PostsController.process(event, context, meth: "show")"
17
+ # code: "HardJob.process(event, context, meth: "dig")"
18
+ %|#{class_name}.process(event, context, "#{@handler_method}")|
19
+ end
20
+
21
+ # Input: @handler_path: handlers/jobs/hard_job.rb
22
+ # Output: #{Jets.root/app/jobs/hard_job.rb
23
+ def path
24
+ Jets.root.to_s + @handler_path.sub("handlers", "app") + ".rb"
25
+ end
26
+
27
+ # process_type is key. It can be either "controller" or "job". It is used to
28
+ # deduce the rest of the methods: code, path.
29
+ def process_type
30
+ @handler.split('/')[1].singularize # controller or job
31
+ end
32
+
33
+ # Example underscored_class_name:
34
+ # class_name = underscored_class_name
35
+ # class_name = class_name # PostsController
36
+ def class_name
37
+ regexp = Regexp.new(".*handlers/#{process_type.pluralize}/")
38
+ # Example regexp:
39
+ # /.*handlers\/controllers\//
40
+ # /.*handlers\/jobs\//
41
+ class_name = @handler_path.sub(regexp, "")
42
+ # Example class names:
43
+ # posts_controller
44
+ # hard_job
45
+ # hello
46
+ # hello_function
47
+
48
+ class_name.classify
49
+ end
50
+
51
+ def load_class
52
+ Jets::Klass.from_path(path)
53
+ end
54
+ end
@@ -0,0 +1,57 @@
1
+ require 'json'
2
+
3
+ # Node shim calls this class to process both controllers and jobs
4
+ class Jets::Processors::MainProcessor
5
+ attr_reader :event, :context, :handler
6
+ def initialize(event, context, handler)
7
+ # assume valid json from Lambda
8
+ @event = JSON.parse(event)
9
+ @context = JSON.parse(context)
10
+ @handler = handler
11
+ end
12
+
13
+ def run
14
+ # Use the handler to deduce app code to run.
15
+ # Example handlers: handlers/controllers/posts.create, handlers/jobs/sleep.perform
16
+ #
17
+ # deducer = Jets::Processors::Deducer.new("handlers/controllers/posts.create")
18
+ #
19
+ deducer = Jets::Processors::Deducer.new(handler)
20
+ begin
21
+ # Examples:
22
+ # deducer.code => PostsController.process(event, context, "show")
23
+ # deducer.path => app/controllers/posts_controller.rb
24
+ #
25
+ # deducer.code => HardJob.process(event, context, "dig")
26
+ # deducer.path => app/jobs/hard_job.rb
27
+ #
28
+ # deducer.code => HelloFunction.process(event, context, "world")
29
+ # deducer.path => app/functions/hello.rb
30
+ deducer.load_class
31
+ result = instance_eval(deducer.code, deducer.path)
32
+ # result = PostsController.process(event, context, "create")
33
+
34
+ # Puts the return value of project code to stdout because this is
35
+ # what eventually gets used by API Gateway.
36
+ # Explicitly using $stdout since puts has been redirected to $stderr.
37
+ #
38
+ # JSON.dump is pretty robust. If it cannot dump the structure into a
39
+ # json string, it just dumps it to a plain text string.
40
+ Jets::Util.normalize_result(result) # String
41
+ rescue Exception => e
42
+ # Customize error message slightly so nodejs shim can process the
43
+ # returned error message.
44
+ # The "RubyError: " is a marker that the javascript shim scans for.
45
+ $stderr.puts("RubyError: #{e.class}: #{e.message}") # js needs this as the first line
46
+ backtrace = e.backtrace.map {|l| " #{l}" }
47
+ $stderr.puts(backtrace)
48
+ # No need to having error in stderr above anymore because errors are handled in memory
49
+ # at ruby_server.rb but keeping around for posterity.
50
+
51
+ raise # raise error to ruby_server.rb to rescue and handle
52
+
53
+ # $stderr.puts("END OF RUBY OUTPUT") # uncomment for debugging
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,4 @@
1
+ require "jets/rails_overrides/common_methods"
2
+ require "jets/rails_overrides/url_helper"
3
+ require "jets/rails_overrides/rendering_helper"
4
+ require "jets/rails_overrides/asset_tag_helper"
@@ -0,0 +1,41 @@
1
+ # Override to prepend stage name when on AWS.
2
+ module Jets::AssetTagHelper
3
+ include Jets::CommonMethods
4
+
5
+ def javascript_include_tag(*sources, **options)
6
+ sources = sources.map { |s| stage_name_asset_url(s, :javascripts) }
7
+ super
8
+ end
9
+
10
+ def stylesheet_link_tag(*sources, **options)
11
+ sources = sources.map { |s| stage_name_asset_url(s, :stylesheets) }
12
+ super
13
+ end
14
+
15
+ # User can use:
16
+ # javascript_include_tag "assets/test"
17
+ #
18
+ # Rails automatically adds "javscript" in front, to become:
19
+ #
20
+ # /javascripts/assets/test
21
+ #
22
+ # We want to add the API Gateway stage name in front for this:
23
+ #
24
+ # /stag/javascript/asset/test
25
+ #
26
+ # But adding it in front results in this:
27
+ #
28
+ # /javascript/stag/asset/test
29
+ #
30
+ # If there's a / in front then rails will not add the "javascript":
31
+ # So we can add the javascript ourselves and then add the stag with a
32
+ # / in front.
33
+ def stage_name_asset_url(url, asset_type)
34
+ unless url.starts_with?('/') or url.starts_with?('http')
35
+ url = "/#{asset_type}/#{url}" # /javascript/asset/test
36
+ end
37
+ url = add_stage_name(url)
38
+ url
39
+ end
40
+ end
41
+ ActionView::Helpers.send(:include, Jets::AssetTagHelper)
@@ -0,0 +1,13 @@
1
+ module Jets::CommonMethods
2
+ # Add API Gateway Stage Name
3
+ def add_stage_name(url)
4
+ if request.host.include?("amazonaws.com") &&
5
+ url.starts_with?('/') &&
6
+ !url.starts_with?('http')
7
+ stage_name = Jets::Cfn::TemplateMappers::ApiGatewayDeploymentMapper.stage_name
8
+ url = "/#{stage_name}#{url}"
9
+ end
10
+
11
+ url
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Jets::RenderingHelper
2
+ # ensure that we always add the controller view name. So when rendering
3
+ # a partial:
4
+ # <%= render "mypartial" %>
5
+ # gets turned into:
6
+ # <%= render "articles/mypartial" %>
7
+ def render(options = {}, locals = {}, &block)
8
+ if options.is_a?(String) && !options.include?('/')
9
+ folder = _get_containing_folder(caller[0])
10
+ partial_name = options # happens to be the partial name
11
+ partial_name = "#{folder}/#{partial_name}"
12
+ options = partial_name
13
+ end
14
+
15
+ super(options, locals, &block)
16
+ end
17
+
18
+ # Ugly, going back up the caller stack to find out what view path
19
+ # we are in
20
+ def _get_containing_folder(caller_line)
21
+ text = caller_line.split(':').first
22
+ # .../fixtures/apps/demo/app/views/posts/index.html.erb
23
+ text.split('/')[-2] # posts
24
+ end
25
+ end
26
+ ActionView::Helpers.send(:include, Jets::RenderingHelper)
@@ -0,0 +1,26 @@
1
+ require "action_view"
2
+
3
+ # hackety hack
4
+ module Jets::UrlHelper
5
+ include Jets::CommonMethods
6
+
7
+ # Basic implementation of url_for to allow use helpers without routes existence
8
+ def url_for(options = nil) # :nodoc:
9
+ url = case options
10
+ when String
11
+ options
12
+ when :back
13
+ _back_url
14
+ # TODO: hook this up to Jets implmentation of config/routes.rb
15
+ # when ActiveRecord::Base
16
+ # record = options
17
+ # record.id
18
+ else
19
+ raise ArgumentError, "Please provided a String to link_to as the the second argument. The Jets link_to helper takes as the second argument."
20
+ end
21
+
22
+ url = add_stage_name(url)
23
+ url
24
+ end
25
+ end # UrlHelper
26
+ ActionView::Helpers.send(:include, Jets::UrlHelper)
@@ -0,0 +1,145 @@
1
+ # route = Jets::Route.new(
2
+ # path: "posts",
3
+ # method: :get,
4
+ # to: "posts#index",
5
+ # )
6
+ class Jets::Route
7
+ def initialize(options)
8
+ @options = options
9
+ end
10
+
11
+ # IE: standard: posts/:id/edit
12
+ # api_gateway: posts/{id}/edit
13
+ def path(format=:jets)
14
+ case format
15
+ when :api_gateway
16
+ api_gateway_format(@options[:path])
17
+ when :raw
18
+ @options[:path]
19
+ else # jets format
20
+ ensure_jets_format(@options[:path])
21
+ end
22
+ end
23
+
24
+ def method
25
+ @options[:method].to_s.upcase
26
+ end
27
+
28
+ # IE: posts#index
29
+ def to
30
+ @options[:to]
31
+ end
32
+
33
+ def internal?
34
+ !!@options[:internal]
35
+ end
36
+
37
+ def homepage?
38
+ path == ''
39
+ end
40
+
41
+ # IE: PostsController
42
+ def controller_name
43
+ to.sub(/#.*/,'').camelize + "Controller"
44
+ end
45
+
46
+ # IE: index
47
+ def action_name
48
+ to.sub(/.*#/,'')
49
+ end
50
+
51
+ # Extracts the path parameters from the actual path
52
+ # Only supports extracting 1 parameter. So:
53
+ #
54
+ # actual_path: posts/tung/edit
55
+ # route.path: posts/:id/edit
56
+ #
57
+ # Returns:
58
+ # { id: "tung" }
59
+ def extract_parameters(actual_path)
60
+ if path.include?(':')
61
+ extract_parameters_capture(actual_path)
62
+ elsif path.include?('*')
63
+ extract_parameters_proxy(actual_path)
64
+ else
65
+ # Lambda AWS_PROXY sets null to the input request when there are no path parmeters
66
+ nil
67
+ end
68
+ end
69
+
70
+ def extract_parameters_proxy(actual_path)
71
+ # changes path to a string used for a regexp
72
+ # others/*proxy => others\/(.*)
73
+ # nested/others/*proxy => nested/others\/(.*)
74
+ if path.include?('/')
75
+ leading_path = path.split('/')[0..-2].join('/') # drop last segment
76
+ # leading_path: nested/others
77
+ # capture everything after the leading_path as the value
78
+ regexp = Regexp.new("#{leading_path}/(.*)")
79
+ value = actual_path.match(regexp)[1]
80
+ else
81
+ value = actual_path
82
+ end
83
+
84
+ # the last segment without the '*' is the key
85
+ proxy_segment = path.split('/').last # last segment is the proxy segment
86
+ # proxy_segment: *proxy
87
+ key = proxy_segment.sub('*','')
88
+
89
+ { key => value }
90
+ end
91
+
92
+ def extract_parameters_capture(actual_path)
93
+ # changes path to a string used for a regexp
94
+ # posts/:id/edit => posts\/(.*)\/edit
95
+ regexp_string = path.split('/').map do |s|
96
+ s.include?(':') ? "([a-zA-Z0-9_]*)" : s
97
+ end.join('\/')
98
+ # make sure beginning and end of the string matches
99
+ regexp_string = "^#{regexp_string}$"
100
+ regexp = Regexp.new(regexp_string)
101
+ value = regexp.match(actual_path)[1]
102
+
103
+ # only supports one path parameter key right now
104
+ key = path.split('/').find {|s| s.include?(':') } # :id
105
+ key = key.sub(':','')
106
+
107
+ { key => value }
108
+ end
109
+
110
+ private
111
+ def ensure_jets_format(path)
112
+ path.split('/').map do |s|
113
+ if s =~ /^\{/ and s =~ /\+\}$/
114
+ s.sub(/^\{/, '*').sub(/\+\}$/,'') # {proxy+} => *proxy
115
+ elsif s =~ /^\{/ and s =~ /\}$/
116
+ s.sub('{',':').sub(/\}$/,'') # {id} => :id
117
+ else
118
+ s
119
+ end
120
+ end.join('/')
121
+ end
122
+
123
+ def api_gateway_format(path)
124
+ path.split('/')
125
+ .map {|s| transform_capture(s) }
126
+ .map {|s| transform_proxy(s) }
127
+ .join('/')
128
+ end
129
+
130
+ def transform_capture(text)
131
+ if text.starts_with?(':')
132
+ text = text.sub(':','')
133
+ text = "{#{text}}"
134
+ end
135
+ text
136
+ end
137
+
138
+ def transform_proxy(text)
139
+ if text.starts_with?('*')
140
+ text = text.sub('*','')
141
+ text = "{#{text}+}"
142
+ end
143
+ text
144
+ end
145
+ end