jets.benforeva 3.0.17.pre.mount.pre.fix

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 (459) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +92 -0
  3. data/.cody/README.md +13 -0
  4. data/.cody/docs/bin/build.sh +7 -0
  5. data/.cody/docs/bin/bundler_setup.sh +8 -0
  6. data/.cody/docs/bin/cli_docs.sh +6 -0
  7. data/.cody/docs/bin/git_commit.sh +27 -0
  8. data/.cody/docs/bin/git_setup.sh +12 -0
  9. data/.cody/docs/bin/subnav.sh +14 -0
  10. data/.cody/docs/buildspec.yml +10 -0
  11. data/.cody/docs/project.rb +10 -0
  12. data/.github/ISSUE_TEMPLATE/bug_report.md +84 -0
  13. data/.github/ISSUE_TEMPLATE/documentation.md +27 -0
  14. data/.github/ISSUE_TEMPLATE/feature_request.md +64 -0
  15. data/.github/ISSUE_TEMPLATE/question.md +14 -0
  16. data/.github/ISSUE_TEMPLATE.md +7 -0
  17. data/.github/PULL_REQUEST_TEMPLATE.md +50 -0
  18. data/.gitignore +24 -0
  19. data/.gitmodules +0 -0
  20. data/.python-version +1 -0
  21. data/.rspec +4 -0
  22. data/.ruby-gemset +1 -0
  23. data/.ruby-version +1 -0
  24. data/CHANGELOG.md +1035 -0
  25. data/CONDUCT.md +1 -0
  26. data/CONTRIBUTING.md +1 -0
  27. data/Dockerfile +16 -0
  28. data/Dockerfile.base +53 -0
  29. data/Gemfile +14 -0
  30. data/Guardfile +22 -0
  31. data/LICENSE.txt +22 -0
  32. data/Procfile +2 -0
  33. data/README.md +212 -0
  34. data/Rakefile +24 -0
  35. data/backers.md +20 -0
  36. data/bin/release +9 -0
  37. data/exe/jets.benforeva +14 -0
  38. data/jets.benforeva.gemspec +71 -0
  39. data/lib/jets/application/defaults.rb +200 -0
  40. data/lib/jets/application.rb +240 -0
  41. data/lib/jets/authorizer/base.rb +36 -0
  42. data/lib/jets/authorizer/dsl.rb +69 -0
  43. data/lib/jets/authorizer/helpers/iam_helper.rb +47 -0
  44. data/lib/jets/autoloaders.rb +112 -0
  45. data/lib/jets/aws_info.rb +111 -0
  46. data/lib/jets/aws_services/global_memoist.rb +57 -0
  47. data/lib/jets/aws_services/s3_bucket.rb +34 -0
  48. data/lib/jets/aws_services/stack_status.rb +64 -0
  49. data/lib/jets/aws_services.rb +95 -0
  50. data/lib/jets/booter.rb +167 -0
  51. data/lib/jets/builders/code_builder.rb +410 -0
  52. data/lib/jets/builders/code_size.rb +57 -0
  53. data/lib/jets/builders/gem_replacer.rb +89 -0
  54. data/lib/jets/builders/handler_generator.rb +186 -0
  55. data/lib/jets/builders/lambda_layer.rb +68 -0
  56. data/lib/jets/builders/md5.rb +60 -0
  57. data/lib/jets/builders/md5_zip.rb +61 -0
  58. data/lib/jets/builders/purger.rb +35 -0
  59. data/lib/jets/builders/rack_packager.rb +51 -0
  60. data/lib/jets/builders/rackup_wrappers/rackup +19 -0
  61. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  62. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +16 -0
  63. data/lib/jets/builders/reconfigure_rails.rb +114 -0
  64. data/lib/jets/builders/ruby_packager.rb +235 -0
  65. data/lib/jets/builders/shim_vars/app.rb +78 -0
  66. data/lib/jets/builders/shim_vars/base.rb +25 -0
  67. data/lib/jets/builders/shim_vars/shared.rb +37 -0
  68. data/lib/jets/builders/templates/handler.rb +12 -0
  69. data/lib/jets/builders/tidy.rb +107 -0
  70. data/lib/jets/builders/util.rb +31 -0
  71. data/lib/jets/bundle.rb +88 -0
  72. data/lib/jets/camelizer.rb +4 -0
  73. data/lib/jets/cfn/builders/api_deployment_builder.rb +56 -0
  74. data/lib/jets/cfn/builders/api_gateway_builder.rb +123 -0
  75. data/lib/jets/cfn/builders/api_resources_builder.rb +44 -0
  76. data/lib/jets/cfn/builders/authorizer_builder.rb +67 -0
  77. data/lib/jets/cfn/builders/base_child_builder.rb +69 -0
  78. data/lib/jets/cfn/builders/controller_builder.rb +50 -0
  79. data/lib/jets/cfn/builders/function_builder.rb +14 -0
  80. data/lib/jets/cfn/builders/interface.rb +133 -0
  81. data/lib/jets/cfn/builders/job_builder.rb +14 -0
  82. data/lib/jets/cfn/builders/parent_builder/stagger.rb +34 -0
  83. data/lib/jets/cfn/builders/parent_builder.rb +130 -0
  84. data/lib/jets/cfn/builders/rule_builder.rb +24 -0
  85. data/lib/jets/cfn/builders/shared_builder.rb +14 -0
  86. data/lib/jets/cfn/builders/util/source.rb +21 -0
  87. data/lib/jets/cfn/built_template.rb +15 -0
  88. data/lib/jets/cfn/ship.rb +188 -0
  89. data/lib/jets/cfn/status.rb +10 -0
  90. data/lib/jets/cfn/template_source.rb +61 -0
  91. data/lib/jets/cfn/upload.rb +157 -0
  92. data/lib/jets/cli.rb +208 -0
  93. data/lib/jets/commands/base.rb +145 -0
  94. data/lib/jets/commands/build.rb +252 -0
  95. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  96. data/lib/jets/commands/call/autoload_guesser.rb +136 -0
  97. data/lib/jets/commands/call/base_guesser.rb +62 -0
  98. data/lib/jets/commands/call/guesser.rb +48 -0
  99. data/lib/jets/commands/call.rb +182 -0
  100. data/lib/jets/commands/clean/base.rb +24 -0
  101. data/lib/jets/commands/clean/build.rb +13 -0
  102. data/lib/jets/commands/clean/log.rb +111 -0
  103. data/lib/jets/commands/clean.rb +19 -0
  104. data/lib/jets/commands/configure.rb +51 -0
  105. data/lib/jets/commands/console.rb +12 -0
  106. data/lib/jets/commands/db/environment-task.rake +3 -0
  107. data/lib/jets/commands/db/tasks/dummy/app.rb +25 -0
  108. data/lib/jets/commands/db/tasks/dummy/config.rb +14 -0
  109. data/lib/jets/commands/db/tasks.rb +34 -0
  110. data/lib/jets/commands/db.rb +13 -0
  111. data/lib/jets/commands/dbconsole.rb +134 -0
  112. data/lib/jets/commands/delete.rb +136 -0
  113. data/lib/jets/commands/deploy.rb +137 -0
  114. data/lib/jets/commands/dotenv.rb +9 -0
  115. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  116. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  117. data/lib/jets/commands/dynamodb.rb +19 -0
  118. data/lib/jets/commands/gems.rb +13 -0
  119. data/lib/jets/commands/help/build.md +6 -0
  120. data/lib/jets/commands/help/call.md +69 -0
  121. data/lib/jets/commands/help/clean/build.md +5 -0
  122. data/lib/jets/commands/help/clean/log.md +5 -0
  123. data/lib/jets/commands/help/console.md +18 -0
  124. data/lib/jets/commands/help/db/generate.md +8 -0
  125. data/lib/jets/commands/help/dbconsole.md +9 -0
  126. data/lib/jets/commands/help/degenerate.md +16 -0
  127. data/lib/jets/commands/help/delete.md +22 -0
  128. data/lib/jets/commands/help/deploy.md +32 -0
  129. data/lib/jets/commands/help/dynamodb/generate.md +52 -0
  130. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  131. data/lib/jets/commands/help/gems/check.md +6 -0
  132. data/lib/jets/commands/help/generate.md +28 -0
  133. data/lib/jets/commands/help/import/rack.md +13 -0
  134. data/lib/jets/commands/help/import/rails.md +11 -0
  135. data/lib/jets/commands/help/new.md +42 -0
  136. data/lib/jets/commands/help/routes.md +16 -0
  137. data/lib/jets/commands/help/runner.md +17 -0
  138. data/lib/jets/commands/help/server.md +15 -0
  139. data/lib/jets/commands/help/status.md +14 -0
  140. data/lib/jets/commands/help/upgrade.md +7 -0
  141. data/lib/jets/commands/help/url.md +6 -0
  142. data/lib/jets/commands/help.rb +9 -0
  143. data/lib/jets/commands/import/base.rb +49 -0
  144. data/lib/jets/commands/import/cheatsheet.rb +35 -0
  145. data/lib/jets/commands/import/rack.rb +16 -0
  146. data/lib/jets/commands/import/rails.rb +74 -0
  147. data/lib/jets/commands/import/sequence.rb +90 -0
  148. data/lib/jets/commands/import/templates/config/database.yml +30 -0
  149. data/lib/jets/commands/import/templates/submodules-cheatsheet.md +89 -0
  150. data/lib/jets/commands/import.rb +12 -0
  151. data/lib/jets/commands/main.rb +166 -0
  152. data/lib/jets/commands/markdown/creator.rb +58 -0
  153. data/lib/jets/commands/markdown/index.rb +27 -0
  154. data/lib/jets/commands/markdown/page.rb +125 -0
  155. data/lib/jets/commands/markdown/shell.rb +11 -0
  156. data/lib/jets/commands/new.rb +173 -0
  157. data/lib/jets/commands/rake_command.rb +61 -0
  158. data/lib/jets/commands/rake_tasks.rb +50 -0
  159. data/lib/jets/commands/runner.rb +16 -0
  160. data/lib/jets/commands/sequence.rb +105 -0
  161. data/lib/jets/commands/stack_info.rb +30 -0
  162. data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
  163. data/lib/jets/commands/templates/skeleton/.env.test +3 -0
  164. data/lib/jets/commands/templates/skeleton/.env.tt +3 -0
  165. data/lib/jets/commands/templates/skeleton/.gitignore +12 -0
  166. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  167. data/lib/jets/commands/templates/skeleton/.rspec +3 -0
  168. data/lib/jets/commands/templates/skeleton/Gemfile.tt +39 -0
  169. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  170. data/lib/jets/commands/templates/skeleton/README.md +11 -0
  171. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  172. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  173. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  174. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +4 -0
  175. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  176. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  177. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +26 -0
  178. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +71 -0
  179. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
  180. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +22 -0
  181. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +7 -0
  182. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +9 -0
  183. data/lib/jets/commands/templates/skeleton/config/environments/test.rb +7 -0
  184. data/lib/jets/commands/templates/skeleton/config/routes.rb +9 -0
  185. data/lib/jets/commands/templates/skeleton/config.ru +5 -0
  186. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  187. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  188. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  189. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  190. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  191. data/lib/jets/commands/templates/skeleton/public/index.html.tt +91 -0
  192. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +15 -0
  193. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  194. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  195. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +30 -0
  196. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +23 -0
  197. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  198. data/lib/jets/commands/upgrade/templates/bin/webpack +19 -0
  199. data/lib/jets/commands/upgrade/templates/bin/webpack-dev-server +19 -0
  200. data/lib/jets/commands/upgrade/version1.rb +136 -0
  201. data/lib/jets/commands/upgrade.rb +105 -0
  202. data/lib/jets/commands/url.rb +69 -0
  203. data/lib/jets/commands/webpacker_template.rb +18 -0
  204. data/lib/jets/controller/authorization.rb +91 -0
  205. data/lib/jets/controller/base.rb +175 -0
  206. data/lib/jets/controller/callbacks.rb +73 -0
  207. data/lib/jets/controller/cookies/jar.rb +269 -0
  208. data/lib/jets/controller/cookies.rb +38 -0
  209. data/lib/jets/controller/error/invalid_authenticity_token.rb +6 -0
  210. data/lib/jets/controller/error.rb +4 -0
  211. data/lib/jets/controller/forgery_protection.rb +43 -0
  212. data/lib/jets/controller/layout.rb +17 -0
  213. data/lib/jets/controller/middleware/cors.rb +60 -0
  214. data/lib/jets/controller/middleware/local/api_gateway.rb +93 -0
  215. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +38 -0
  216. data/lib/jets/controller/middleware/local/route_matcher.rb +22 -0
  217. data/lib/jets/controller/middleware/local.rb +120 -0
  218. data/lib/jets/controller/middleware/main.rb +53 -0
  219. data/lib/jets/controller/middleware/reloader.rb +15 -0
  220. data/lib/jets/controller/middleware/webpacker_setup.rb +6 -0
  221. data/lib/jets/controller/parameters_filter.rb +29 -0
  222. data/lib/jets/controller/params.rb +117 -0
  223. data/lib/jets/controller/rack/adapter.rb +94 -0
  224. data/lib/jets/controller/rack/env.rb +122 -0
  225. data/lib/jets/controller/redirection.rb +51 -0
  226. data/lib/jets/controller/rendering/rack_renderer.rb +267 -0
  227. data/lib/jets/controller/rendering.rb +96 -0
  228. data/lib/jets/controller/request.rb +29 -0
  229. data/lib/jets/controller/response.rb +61 -0
  230. data/lib/jets/controller/stage.rb +34 -0
  231. data/lib/jets/controller.rb +3 -0
  232. data/lib/jets/core.rb +157 -0
  233. data/lib/jets/core_ext/bundler.rb +7 -0
  234. data/lib/jets/core_ext/kernel.rb +13 -0
  235. data/lib/jets/db.rb +15 -0
  236. data/lib/jets/dotenv/show.rb +11 -0
  237. data/lib/jets/dotenv/ssm.rb +64 -0
  238. data/lib/jets/dotenv.rb +48 -0
  239. data/lib/jets/erb.rb +51 -0
  240. data/lib/jets/generator/templates/active_job/job/templates/application_job.rb.tt +6 -0
  241. data/lib/jets/generator/templates/active_job/job/templates/job.rb.tt +8 -0
  242. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  243. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +34 -0
  244. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  245. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  246. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  247. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  248. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  249. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  250. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  251. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  252. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  253. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  254. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +79 -0
  255. data/lib/jets/generator.rb +112 -0
  256. data/lib/jets/inflections.rb +32 -0
  257. data/lib/jets/internal/app/controllers/jets/bare_controller.rb +16 -0
  258. data/lib/jets/internal/app/controllers/jets/mailers_controller.rb +97 -0
  259. data/lib/jets/internal/app/controllers/jets/mount_controller.rb +63 -0
  260. data/lib/jets/internal/app/controllers/jets/public_controller.rb +31 -0
  261. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +12 -0
  262. data/lib/jets/internal/app/functions/jets/base_path.rb +18 -0
  263. data/lib/jets/internal/app/functions/jets/base_path_mapping.rb +100 -0
  264. data/lib/jets/internal/app/helpers/jets/mailers_helper.rb +9 -0
  265. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +70 -0
  266. data/lib/jets/internal/app/shared/functions/jets/s3_bucket_config.rb +33 -0
  267. data/lib/jets/internal/app/views/jets/mailers/email.html.erb +145 -0
  268. data/lib/jets/internal/app/views/jets/mailers/index.html.erb +8 -0
  269. data/lib/jets/internal/app/views/jets/mailers/mailer.html.erb +6 -0
  270. data/lib/jets/internal/turbines/jets/mailer.rb +52 -0
  271. data/lib/jets/job/base.rb +49 -0
  272. data/lib/jets/job/dsl/dynamodb_event.rb +67 -0
  273. data/lib/jets/job/dsl/event_source_mapping.rb +11 -0
  274. data/lib/jets/job/dsl/iot_event.rb +24 -0
  275. data/lib/jets/job/dsl/kinesis_event.rb +46 -0
  276. data/lib/jets/job/dsl/log_event.rb +15 -0
  277. data/lib/jets/job/dsl/rule_event.rb +75 -0
  278. data/lib/jets/job/dsl/s3_event.rb +36 -0
  279. data/lib/jets/job/dsl/sns_event.rb +54 -0
  280. data/lib/jets/job/dsl/sqs_event.rb +96 -0
  281. data/lib/jets/job/dsl.rb +40 -0
  282. data/lib/jets/job/helpers/kinesis_event_helper.rb +13 -0
  283. data/lib/jets/job/helpers/log_event_helper.rb +17 -0
  284. data/lib/jets/job/helpers/s3_event_helper.rb +13 -0
  285. data/lib/jets/klass.rb +109 -0
  286. data/lib/jets/lambda/dsl.rb +404 -0
  287. data/lib/jets/lambda/function.rb +29 -0
  288. data/lib/jets/lambda/function_constructor.rb +55 -0
  289. data/lib/jets/lambda/functions.rb +39 -0
  290. data/lib/jets/lambda/task.rb +111 -0
  291. data/lib/jets/logger.rb +21 -0
  292. data/lib/jets/mega/hash_converter.rb +25 -0
  293. data/lib/jets/mega/request/source.rb +21 -0
  294. data/lib/jets/mega/request.rb +163 -0
  295. data/lib/jets/middleware/configurator.rb +84 -0
  296. data/lib/jets/middleware/default_stack.rb +53 -0
  297. data/lib/jets/middleware/layer.rb +34 -0
  298. data/lib/jets/middleware/stack.rb +77 -0
  299. data/lib/jets/middleware.rb +33 -0
  300. data/lib/jets/naming.rb +63 -0
  301. data/lib/jets/overrides/lambda/marshaller.rb +31 -0
  302. data/lib/jets/overrides/lambda.rb +1 -0
  303. data/lib/jets/overrides/rails/action_controller.rb +13 -0
  304. data/lib/jets/overrides/rails/asset_tag_helper.rb +114 -0
  305. data/lib/jets/overrides/rails/common_methods.rb +13 -0
  306. data/lib/jets/overrides/rails/migration_checker.rb +34 -0
  307. data/lib/jets/overrides/rails/rendering_helper.rb +27 -0
  308. data/lib/jets/overrides/rails/url_helper.rb +88 -0
  309. data/lib/jets/overrides/rails.rb +6 -0
  310. data/lib/jets/poly_fun/base_executor.rb +125 -0
  311. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  312. data/lib/jets/poly_fun/node_error.rb +8 -0
  313. data/lib/jets/poly_fun/node_executor.rb +54 -0
  314. data/lib/jets/poly_fun/python_error.rb +8 -0
  315. data/lib/jets/poly_fun/python_executor.rb +23 -0
  316. data/lib/jets/poly_fun.rb +73 -0
  317. data/lib/jets/preheat.rb +117 -0
  318. data/lib/jets/processors/deducer.rb +65 -0
  319. data/lib/jets/processors/main_processor.rb +61 -0
  320. data/lib/jets/rack_server.rb +86 -0
  321. data/lib/jets/rdoc.rb +30 -0
  322. data/lib/jets/resource/api_gateway/authorizer.rb +82 -0
  323. data/lib/jets/resource/api_gateway/base_path/function.rb +49 -0
  324. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  325. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  326. data/lib/jets/resource/api_gateway/cors.rb +61 -0
  327. data/lib/jets/resource/api_gateway/deployment.rb +80 -0
  328. data/lib/jets/resource/api_gateway/domain_name.rb +65 -0
  329. data/lib/jets/resource/api_gateway/method/authorization.rb +41 -0
  330. data/lib/jets/resource/api_gateway/method.rb +102 -0
  331. data/lib/jets/resource/api_gateway/resource.rb +82 -0
  332. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +10 -0
  333. data/lib/jets/resource/api_gateway/rest_api/logical_id/message.rb +49 -0
  334. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +98 -0
  335. data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +136 -0
  336. data/lib/jets/resource/api_gateway/rest_api/routes/change/media_types.rb +36 -0
  337. data/lib/jets/resource/api_gateway/rest_api/routes/change/page.rb +93 -0
  338. data/lib/jets/resource/api_gateway/rest_api/routes/change/to.rb +25 -0
  339. data/lib/jets/resource/api_gateway/rest_api/routes/change/variable.rb +35 -0
  340. data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +16 -0
  341. data/lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb +7 -0
  342. data/lib/jets/resource/api_gateway/rest_api/routes/collision.rb +121 -0
  343. data/lib/jets/resource/api_gateway/rest_api/routes.rb +7 -0
  344. data/lib/jets/resource/api_gateway/rest_api.rb +64 -0
  345. data/lib/jets/resource/associated.rb +37 -0
  346. data/lib/jets/resource/base.rb +28 -0
  347. data/lib/jets/resource/child_stack/api_deployment.rb +58 -0
  348. data/lib/jets/resource/child_stack/api_gateway.rb +23 -0
  349. data/lib/jets/resource/child_stack/api_resource/page.rb +20 -0
  350. data/lib/jets/resource/child_stack/api_resource.rb +54 -0
  351. data/lib/jets/resource/child_stack/app_class.rb +149 -0
  352. data/lib/jets/resource/child_stack/authorizer.rb +40 -0
  353. data/lib/jets/resource/child_stack/base.rb +24 -0
  354. data/lib/jets/resource/child_stack/common_parameters.rb +14 -0
  355. data/lib/jets/resource/child_stack/shared.rb +85 -0
  356. data/lib/jets/resource/config/config_rule.rb +74 -0
  357. data/lib/jets/resource/config/managed_rule.rb +15 -0
  358. data/lib/jets/resource/events/rule.rb +31 -0
  359. data/lib/jets/resource/iam/application_role.rb +27 -0
  360. data/lib/jets/resource/iam/base_role_definition.rb +47 -0
  361. data/lib/jets/resource/iam/class_role.rb +74 -0
  362. data/lib/jets/resource/iam/function_role.rb +54 -0
  363. data/lib/jets/resource/iam/managed_policy.rb +22 -0
  364. data/lib/jets/resource/iam/policy_document.rb +41 -0
  365. data/lib/jets/resource/iot/topic_rule.rb +34 -0
  366. data/lib/jets/resource/lambda/event_source_mapping.rb +31 -0
  367. data/lib/jets/resource/lambda/function/environment.rb +62 -0
  368. data/lib/jets/resource/lambda/function.rb +221 -0
  369. data/lib/jets/resource/lambda/gem_layer.rb +17 -0
  370. data/lib/jets/resource/lambda/layer_version.rb +44 -0
  371. data/lib/jets/resource/logs/subscription_filter.rb +31 -0
  372. data/lib/jets/resource/permission.rb +45 -0
  373. data/lib/jets/resource/replacer.rb +85 -0
  374. data/lib/jets/resource/route53/record_set.rb +98 -0
  375. data/lib/jets/resource/s3/bucket.rb +24 -0
  376. data/lib/jets/resource/sns/subscription.rb +29 -0
  377. data/lib/jets/resource/sns/topic.rb +35 -0
  378. data/lib/jets/resource/sns/topic_policy.rb +40 -0
  379. data/lib/jets/resource/sqs/queue.rb +21 -0
  380. data/lib/jets/resource/standardizer.rb +42 -0
  381. data/lib/jets/resource.rb +71 -0
  382. data/lib/jets/router/dsl/mount.rb +13 -0
  383. data/lib/jets/router/dsl.rb +144 -0
  384. data/lib/jets/router/error.rb +4 -0
  385. data/lib/jets/router/finder.rb +47 -0
  386. data/lib/jets/router/helpers/core_helper.rb +27 -0
  387. data/lib/jets/router/helpers/named_routes_helper.rb +8 -0
  388. data/lib/jets/router/helpers.rb +4 -0
  389. data/lib/jets/router/matcher.rb +81 -0
  390. data/lib/jets/router/method_creator/code.rb +99 -0
  391. data/lib/jets/router/method_creator/edit.rb +12 -0
  392. data/lib/jets/router/method_creator/generic.rb +11 -0
  393. data/lib/jets/router/method_creator/index.rb +48 -0
  394. data/lib/jets/router/method_creator/new.rb +12 -0
  395. data/lib/jets/router/method_creator/root.rb +15 -0
  396. data/lib/jets/router/method_creator/show.rb +12 -0
  397. data/lib/jets/router/method_creator.rb +50 -0
  398. data/lib/jets/router/resources/base.rb +7 -0
  399. data/lib/jets/router/resources/filter.rb +15 -0
  400. data/lib/jets/router/resources/options.rb +13 -0
  401. data/lib/jets/router/route/authorizer.rb +57 -0
  402. data/lib/jets/router/route.rb +230 -0
  403. data/lib/jets/router/scope.rb +95 -0
  404. data/lib/jets/router/util.rb +38 -0
  405. data/lib/jets/router.rb +180 -0
  406. data/lib/jets/rule/base.rb +19 -0
  407. data/lib/jets/rule/dsl.rb +109 -0
  408. data/lib/jets/spec_helpers/controllers/params.rb +8 -0
  409. data/lib/jets/spec_helpers/controllers/request.rb +101 -0
  410. data/lib/jets/spec_helpers/controllers/response.rb +10 -0
  411. data/lib/jets/spec_helpers/controllers.rb +47 -0
  412. data/lib/jets/spec_helpers/fixtures.rb +11 -0
  413. data/lib/jets/spec_helpers.rb +21 -0
  414. data/lib/jets/stack/builder.rb +43 -0
  415. data/lib/jets/stack/definition.rb +50 -0
  416. data/lib/jets/stack/depends/item.rb +26 -0
  417. data/lib/jets/stack/depends.rb +34 -0
  418. data/lib/jets/stack/function.rb +69 -0
  419. data/lib/jets/stack/main/dsl/base.rb +63 -0
  420. data/lib/jets/stack/main/dsl/cloudwatch.rb +19 -0
  421. data/lib/jets/stack/main/dsl/iam.rb +8 -0
  422. data/lib/jets/stack/main/dsl/kinesis.rb +15 -0
  423. data/lib/jets/stack/main/dsl/lambda.rb +83 -0
  424. data/lib/jets/stack/main/dsl/s3.rb +12 -0
  425. data/lib/jets/stack/main/dsl/sns.rb +16 -0
  426. data/lib/jets/stack/main/dsl/sqs.rb +10 -0
  427. data/lib/jets/stack/main/dsl.rb +17 -0
  428. data/lib/jets/stack/main.rb +4 -0
  429. data/lib/jets/stack/output/dsl.rb +19 -0
  430. data/lib/jets/stack/output/lookup.rb +36 -0
  431. data/lib/jets/stack/output.rb +35 -0
  432. data/lib/jets/stack/parameter/dsl.rb +42 -0
  433. data/lib/jets/stack/parameter.rb +37 -0
  434. data/lib/jets/stack/resource/dsl.rb +19 -0
  435. data/lib/jets/stack/resource.rb +31 -0
  436. data/lib/jets/stack/s3_event.rb +87 -0
  437. data/lib/jets/stack.rb +88 -0
  438. data/lib/jets/tmp_loader.rb +53 -0
  439. data/lib/jets/turbine.rb +41 -0
  440. data/lib/jets/turbo/database_yaml.rb +41 -0
  441. data/lib/jets/turbo/project/.gitignore +12 -0
  442. data/lib/jets/turbo/project/.jetskeep +1 -0
  443. data/lib/jets/turbo/project/Gemfile +16 -0
  444. data/lib/jets/turbo/project/Rakefile +2 -0
  445. data/lib/jets/turbo/project/app/controllers/application_controller.rb +2 -0
  446. data/lib/jets/turbo/project/app/helpers/application_helper.rb +2 -0
  447. data/lib/jets/turbo/project/app/jobs/application_job.rb +4 -0
  448. data/lib/jets/turbo/project/config/application.rb +5 -0
  449. data/lib/jets/turbo/project/config/routes.rb +4 -0
  450. data/lib/jets/turbo/project/config.ru +5 -0
  451. data/lib/jets/turbo/rails.rb +127 -0
  452. data/lib/jets/turbo/templates/config/database.yml +30 -0
  453. data/lib/jets/turbo.rb +56 -0
  454. data/lib/jets/util.rb +40 -0
  455. data/lib/jets/version.rb +3 -0
  456. data/lib/jets.rb +31 -0
  457. data/readme/prerelease.md +6 -0
  458. data/readme/testing.md +60 -0
  459. metadata +1105 -0
@@ -0,0 +1,16 @@
1
+ # Parent class for MountController and RackController
2
+ class Jets::BareController < Jets::Controller::Base
3
+ layout false
4
+ internal true
5
+ skip_forgery_protection
6
+
7
+ private
8
+ # Override process! so it doesnt go through the complete Jets project middleware stack which could interfer with
9
+ # the mounted Rack app.
10
+ def process!
11
+ status, headers, body = dispatch!
12
+ # Use the adapter only to convert the Rack triplet to a API Gateway hash structure
13
+ adapter = Jets::Controller::Rack::Adapter.new(event, context, meth)
14
+ adapter.convert_to_api_gateway(status, headers, body)
15
+ end
16
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Jets::MailersController < Jets::Controller::Base # :nodoc:
4
+ before_action :find_preview, only: [:preview]
5
+ before_action :set_locale, only: [:preview]
6
+ # TODO: allow multiple actions
7
+ # before_action :find_preview, :set_locale, only: :preview
8
+
9
+ # TODO: add helper_method support
10
+ # helper_method :part_query, :locale_query
11
+
12
+ # TODO: content_security_policy
13
+ # content_security_policy(false)
14
+
15
+ def index
16
+ @previews = ActionMailer::Preview.all
17
+ @page_title = "Mailer Previews"
18
+ end
19
+
20
+ def preview
21
+ if params[:path] == @preview.preview_name
22
+ @page_title = "Mailer Previews for #{@preview.preview_name}"
23
+ render :mailer
24
+ else
25
+ @email_action = File.basename(params[:path])
26
+
27
+ if @preview.email_exists?(@email_action)
28
+ @email = @preview.call(@email_action, params)
29
+
30
+ if params[:part]
31
+ part_type = Mime::Type.lookup(params[:part])
32
+
33
+ if part = find_part(part_type)
34
+ response.headers["Content-Type"] = params[:part]
35
+ render plain: part.respond_to?(:decoded) ? part.decoded : part
36
+ else
37
+ raise AbstractController::ActionNotFound, "Email part '#{part_type}' not found in #{@preview.name}##{@email_action}"
38
+ end
39
+ else
40
+ @part = find_preferred_part(Mime[:html], Mime[:text])
41
+ render :email, layout: false, formats: %w[html]
42
+ end
43
+ else
44
+ raise AbstractController::ActionNotFound, "Email '#{@email_action}' not found in #{@preview.name}"
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+ def show_previews? # :doc:
51
+ ActionMailer::Base.show_previews
52
+ end
53
+
54
+ def find_preview # :doc:
55
+ candidates = []
56
+ params[:path].to_s.scan(%r{/|$}) { candidates << $` } # ` # hack to fix syntax highlighting
57
+ preview = candidates.detect { |candidate| ActionMailer::Preview.exists?(candidate) }
58
+
59
+ if preview
60
+ @preview = ActionMailer::Preview.find(preview)
61
+ else
62
+ raise AbstractController::ActionNotFound, "Mailer preview '#{params[:path]}' not found"
63
+ end
64
+ end
65
+
66
+ def find_preferred_part(*formats) # :doc:
67
+ formats.each do |format|
68
+ if part = @email.find_first_mime_type(format)
69
+ return part
70
+ end
71
+ end
72
+
73
+ if formats.any? { |f| @email.mime_type == f }
74
+ @email
75
+ end
76
+ end
77
+
78
+ def find_part(format) # :doc:
79
+ if part = @email.find_first_mime_type(format)
80
+ part
81
+ elsif @email.mime_type == format
82
+ @email
83
+ end
84
+ end
85
+
86
+ def part_query(mime_type)
87
+ request.query_parameters.merge(part: mime_type).to_query
88
+ end
89
+
90
+ def locale_query(locale)
91
+ request.query_parameters.merge(locale: locale).to_query
92
+ end
93
+
94
+ def set_locale
95
+ I18n.locale = params[:locale] || I18n.default_locale
96
+ end
97
+ end
@@ -0,0 +1,63 @@
1
+ # routes mount support
2
+ class Jets::MountController < Jets::BareController
3
+ def call
4
+ route = find_route
5
+ # On Lambda, the route should always be found so this check on lambda is not needed.
6
+ # But this is useful when we're testing locally with the shim directly.
7
+ unless route
8
+ render json: {status: "route not found"}, status: 404
9
+ return
10
+ end
11
+
12
+ # The reason we look up the route is because it contains mounted class info
13
+ mount_class = route.mount_class # IE: RackApp
14
+ env = build_env(route.path)
15
+
16
+ status, headers, io = mount_class.call(env)
17
+ body = read_body(io)
18
+ render(
19
+ status: status,
20
+ headers: headers,
21
+ body: body,
22
+ )
23
+ end
24
+
25
+ private
26
+ # Rack response will return an IO object that responds to each. Sometimes this a Rack::BodyProxy
27
+ # Found this to be the case in Rails and Grape.
28
+ # Doing an IO#read may not work. So we'll always use the IO#each method
29
+ def read_body(io)
30
+ result = []
31
+ io.each { |body| result << body }
32
+ result.join
33
+ end
34
+
35
+ # Locally Jets::Router::Finder gets called twice because it also gets called in Jets::Controller::Middleware::Local
36
+ # On Lambda, Jets::Router::Finder only gets called once.
37
+ # TODO: Maybe add caching improvement.
38
+ def find_route
39
+ Jets::Router::Finder.new(event["path"], "ANY").run
40
+ end
41
+
42
+ def build_env(path)
43
+ env = Jets::Controller::Rack::Env.new(event, context, adapter: true).convert
44
+ # remap path info
45
+ mount_at = mount_at(path)
46
+ path_info = env["PATH_INFO"]
47
+ env["SCRIPT_NAME"] = script_name(mount_at)
48
+ env["PATH_INFO"] = path_info.sub(mount_at,'')
49
+ env["ORIGINAL_PATH_INFO"] = path_info
50
+ env
51
+ end
52
+
53
+ # Removes the wildcard: rack/*path => rack
54
+ def mount_at(path)
55
+ path.gsub(/\*.*/,'')
56
+ end
57
+
58
+ # Adding forward slash to script name, to generate proper path.
59
+ # First remove all the occurance of forward slash at the begining and then add one.
60
+ def script_name(path)
61
+ '/' + path.gsub(/^\/*/,'')
62
+ end
63
+ end
@@ -0,0 +1,31 @@
1
+ require "rack/mime"
2
+ require "mini_mime"
3
+
4
+ class Jets::PublicController < Jets::Controller::Base
5
+ layout false
6
+ internal true
7
+
8
+ def show
9
+ catchall = params[:catchall].blank? ? 'index.html' : params[:catchall]
10
+ public_path = Jets.root + "public"
11
+ catchall_path = "#{public_path}/#{catchall}"
12
+
13
+ if File.exist?(catchall_path)
14
+ content_type = Rack::Mime.mime_type(File.extname(catchall_path))
15
+ binary = !MiniMime.lookup_by_filename(catchall_path).content_type.include?("text")
16
+
17
+ # For binary support to work, the client also has to send the right Accept header.
18
+ # And the media type has been to added to api gateway.
19
+ # Cavaet: adding * to as the media type breaks regular form submission.
20
+ # All form submission gets treated as binary.
21
+ if binary
22
+ encoded_content = Base64.encode64(IO.read(catchall_path))
23
+ render plain: encoded_content, content_type: content_type, base64: true
24
+ else
25
+ render file: catchall_path, content_type: content_type
26
+ end
27
+ else
28
+ render file: "#{public_path}/404", status: 404
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ class Jets::RackController < Jets::BareController
2
+ # Megamode
3
+ def process
4
+ resp = mega_request
5
+ render(resp)
6
+ end
7
+
8
+ private
9
+ def mega_request
10
+ Jets::Mega::Request.new(event, self).proxy
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ require 'bundler/setup'
2
+ require 'cfn_response'
3
+ require 'jets/internal/app/functions/jets/base_path_mapping'
4
+
5
+ STAGE_NAME = "<%= @stage_name %>"
6
+
7
+ def lambda_handler(event:, context:)
8
+ cfn = CfnResponse.new(event, context)
9
+ cfn.response do
10
+ mapping = BasePathMapping.new(event, STAGE_NAME)
11
+ case event['RequestType']
12
+ when "Create", "Update"
13
+ mapping.update
14
+ when "Delete"
15
+ mapping.delete(true) if mapping.should_delete?
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,100 @@
1
+ require 'aws-sdk-apigateway'
2
+ require 'aws-sdk-cloudformation'
3
+
4
+ class BasePathMapping
5
+ def initialize(event, stage_name)
6
+ @event, @stage_name = event, stage_name
7
+ aws_config_update!
8
+ end
9
+
10
+ # Override the AWS retry settings. The aws-sdk-core has expondential backup with this formula:
11
+ #
12
+ # 2 ** c.retries * c.config.retry_base_delay
13
+ #
14
+ # So the max delay will be 2 ** 7 * 0.6 = 76.8s
15
+ #
16
+ # Useful links:
17
+ #
18
+ # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/retry_errors.rb
19
+ # https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
20
+ #
21
+ def aws_config_update!
22
+ Aws.config.update(
23
+ retry_limit: 7, # default: 3
24
+ retry_base_delay: 0.6, # default: 0.3
25
+ )
26
+ end
27
+
28
+ # Cannot use update_base_path_mapping to update the base_mapping because it doesnt
29
+ # allow us to change the rest_api_id. So we delete and create.
30
+ def update
31
+ delete(true)
32
+ create
33
+ end
34
+
35
+ # Dont delete the newly created base path mapping unless this is an operation
36
+ # where we're fully deleting the stack
37
+ def should_delete?
38
+ deleting_parent?
39
+ end
40
+
41
+ def delete(fail_silently=false)
42
+ apigateway.delete_base_path_mapping(
43
+ domain_name: domain_name, # required
44
+ base_path: base_path.empty? ? '(none)' : base_path,
45
+ )
46
+ # https://github.com/tongueroo/jets/issues/255
47
+ # Used to return: Aws::APIGateway::Errors::NotFoundException
48
+ # Now returns: Aws::APIGateway::Errors::InternalFailure
49
+ # So we'll use a more generic error
50
+ rescue Aws::APIGateway::Errors::ServiceError => e
51
+ raise(e) unless fail_silently
52
+ end
53
+
54
+ def create
55
+ apigateway.create_base_path_mapping(
56
+ domain_name: domain_name, # required
57
+ base_path: base_path,
58
+ rest_api_id: rest_api_id, # required
59
+ stage: @stage_name,
60
+ )
61
+ end
62
+
63
+ def deployment_stack
64
+ @deployment_stack ||= cfn.describe_stacks(stack_name: @event['StackId']).stacks.first
65
+ end
66
+
67
+ def rest_api_id
68
+ @rest_api_id ||= parameter_value('RestApi')
69
+ end
70
+
71
+ def domain_name
72
+ @domain_name ||= parameter_value('DomainName')
73
+ end
74
+
75
+ def base_path
76
+ @base_path ||= parameter_value('BasePath') || ''
77
+ end
78
+
79
+ def parameter_value(parameter_key)
80
+ param = deployment_stack[:parameters].find { |p| p.parameter_key == parameter_key }
81
+ param&.parameter_value # possible for this to be nil when removing the config: IE: config.domain.name = nil
82
+ end
83
+
84
+ def deleting_parent?
85
+ stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first
86
+ stack.stack_status == 'DELETE_IN_PROGRESS'
87
+ end
88
+
89
+ def parent_stack_name
90
+ deployment_stack[:root_id]
91
+ end
92
+
93
+ def apigateway
94
+ @apigateway ||= Aws::APIGateway::Client.new
95
+ end
96
+
97
+ def cfn
98
+ @cfn ||= Aws::CloudFormation::Client.new
99
+ end
100
+ end
@@ -0,0 +1,9 @@
1
+ module Jets::MailersHelper
2
+ def part_query(mime_type)
3
+ mime_type
4
+ end
5
+
6
+ def locale_query(locale)
7
+ locale
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ class Jets::PreheatJob < ApplicationJob
2
+ ENABLED = Jets.config.prewarm.enable
3
+ CONCURRENCY = Jets.config.prewarm.concurrency
4
+ PREWARM_RATE = Jets.config.prewarm.rate
5
+ torching = ENABLED && CONCURRENCY > 1
6
+ warming = ENABLED && CONCURRENCY == 1
7
+
8
+ class_timeout 30
9
+ class_memory 1024
10
+ class_iam_policy(
11
+ {
12
+ sid: "Statement1",
13
+ action: ["logs:*"],
14
+ effect: "Allow",
15
+ resource: "arn:aws:logs:#{Jets.aws.region}:#{Jets.aws.account}:log-group:#{Jets.config.project_namespace}-*",
16
+ },
17
+ {
18
+ sid: "Statement2",
19
+ action: ["lambda:InvokeFunction", "lambda:InvokeAsync"],
20
+ effect: "Allow",
21
+ resource: "arn:aws:lambda:#{Jets.aws.region}:#{Jets.aws.account}:function:#{Jets.config.project_namespace}-*",
22
+ }
23
+ )
24
+
25
+ rate(PREWARM_RATE) if torching
26
+ def torch
27
+ threads = []
28
+ CONCURRENCY.times do
29
+ threads << Thread.new do
30
+ # intentionally calling remote lambda for concurrency
31
+ # avoid passing the _prewarm=1 flag because we want the PreheatJob#warm
32
+ # to run it's normal workload.
33
+ # Do not use Jets::Preheat.warm(function_name) here as that passes the _prewarm=1.
34
+ function_name = "jets-preheat_job-warm"
35
+ event_json = JSON.dump(event)
36
+ options = call_options(event[:quiet])
37
+ Jets::Commands::Call.new(function_name, event_json, options).run unless Jets.env.test?
38
+ end
39
+ end
40
+ threads.each { |t| t.join }
41
+ "Finished prewarming your application with a concurrency of #{CONCURRENCY}."
42
+ end
43
+
44
+ rate(PREWARM_RATE) if warming
45
+ def warm
46
+ options = call_options(event[:quiet])
47
+ Jets::Preheat.warm_all(options)
48
+ "Finished prewarming your application."
49
+ end
50
+
51
+ class << self
52
+ # Can use this to prewarm post deploy
53
+ def prewarm!
54
+ meth = CONCURRENCY > 1 ? :torch : :warm
55
+ perform_now(meth, quiet: true)
56
+ end
57
+ end
58
+
59
+ private
60
+ def call_options(quiet)
61
+ options = {}
62
+ options.merge!(mute: true, mute_output: true) if quiet
63
+ # All the methods in this Job class leads to Jets::Commands::Call.
64
+ # This is true for the Jets::Preheat.warm_all also.
65
+ # These jobs delegate out to Lambda function calls. We do not need/want
66
+ # the invocation type: RequestResponse in this case.
67
+ options.merge!(invocation_type: "Event")
68
+ options
69
+ end
70
+ end
@@ -0,0 +1,33 @@
1
+ require 'bundler/setup'
2
+ require 'active_support/core_ext/hash'
3
+ require 'cfn_response'
4
+
5
+ def lambda_handler(event:, context:)
6
+ cfn = CfnResponse.new(event, context)
7
+ cfn.response do
8
+ case event['RequestType']
9
+ when "Create", "Update"
10
+ properties = event["ResourceProperties"].dup
11
+ # After deleting ServiceToken, the rest of the values are the bucket configuration properties.
12
+ properties.delete("ServiceToken")
13
+ configurator = BucketConfigurator.new
14
+ configurator.put(properties)
15
+ end
16
+ end
17
+ end
18
+
19
+ ########################################################
20
+ require "aws-sdk-s3"
21
+
22
+ class BucketConfigurator
23
+ def put(props={})
24
+ # all props including bucket gets passed from the Custom::S3BucketConfiguration resource
25
+ props = props.deep_transform_keys { |k| k.to_s.underscore.to_sym }
26
+ puts "props: #{JSON.dump(props)}"
27
+ s3.put_bucket_notification_configuration(props)
28
+ end
29
+
30
+ def s3
31
+ @s3 ||= Aws::S3::Client.new
32
+ end
33
+ end
@@ -0,0 +1,145 @@
1
+ <!DOCTYPE html>
2
+ <html><head>
3
+ <meta name="viewport" content="width=device-width" />
4
+ <style type="text/css">
5
+ html, body, iframe {
6
+ height: 100%;
7
+ }
8
+
9
+ body {
10
+ margin: 0;
11
+ }
12
+
13
+ header {
14
+ width: 100%;
15
+ padding: 10px 0 0 0;
16
+ margin: 0;
17
+ background: white;
18
+ font: 12px "Lucida Grande", sans-serif;
19
+ border-bottom: 1px solid #dedede;
20
+ overflow: hidden;
21
+ }
22
+
23
+ dl {
24
+ margin: 0 0 10px 0;
25
+ padding: 0;
26
+ }
27
+
28
+ dt {
29
+ width: 80px;
30
+ padding: 1px;
31
+ float: left;
32
+ clear: left;
33
+ text-align: right;
34
+ color: #7f7f7f;
35
+ }
36
+
37
+ dd {
38
+ margin-left: 90px; /* 80px + 10px */
39
+ padding: 1px;
40
+ }
41
+
42
+ dd:empty:before {
43
+ content: "\00a0"; // &nbsp;
44
+ }
45
+
46
+ iframe {
47
+ border: 0;
48
+ width: 100%;
49
+ }
50
+ </style>
51
+ </head>
52
+
53
+ <body>
54
+ <header>
55
+ <dl>
56
+ <% if @email.respond_to?(:smtp_envelope_from) && Array(@email.from) != Array(@email.smtp_envelope_from) %>
57
+ <dt>SMTP-From:</dt>
58
+ <dd><%= @email.smtp_envelope_from %></dd>
59
+ <% end %>
60
+
61
+ <% if @email.respond_to?(:smtp_envelope_to) && @email.to != @email.smtp_envelope_to %>
62
+ <dt>SMTP-To:</dt>
63
+ <dd><%= @email.smtp_envelope_to %></dd>
64
+ <% end %>
65
+
66
+ <dt>From:</dt>
67
+ <dd><%= @email.header['from'] %></dd>
68
+
69
+ <% if @email.reply_to %>
70
+ <dt>Reply-To:</dt>
71
+ <dd><%= @email.header['reply-to'] %></dd>
72
+ <% end %>
73
+
74
+ <dt>To:</dt>
75
+ <dd><%= @email.header['to'] %></dd>
76
+
77
+ <% if @email.cc %>
78
+ <dt>CC:</dt>
79
+ <dd><%= @email.header['cc'] %></dd>
80
+ <% end %>
81
+
82
+ <dt>Date:</dt>
83
+ <dd><%= Time.current.rfc2822 %></dd>
84
+
85
+ <dt>Subject:</dt>
86
+ <dd><strong><%= @email.subject %></strong></dd>
87
+
88
+ <% unless @email.attachments.nil? || @email.attachments.empty? %>
89
+ <dt>Attachments:</dt>
90
+ <dd>
91
+ <% @email.attachments.each do |a| %>
92
+ <% filename = a.respond_to?(:original_filename) ? a.original_filename : a.filename %>
93
+ <%= link_to filename, "data:application/octet-stream;charset=utf-8;base64,#{Base64.encode64(a.body.to_s)}", download: filename %>
94
+ <% end %>
95
+ </dd>
96
+ <% end %>
97
+
98
+ <dt>Format:</dt>
99
+ <% if @email.multipart? %>
100
+ <dd>
101
+ <select id="part" onchange="refreshBody(false);">
102
+ <option <%= request.format == Mime[:html] ? 'selected' : '' %> value="<%= part_query('text/html') %>">View as HTML email</option>
103
+ <option <%= request.format == Mime[:text] ? 'selected' : '' %> value="<%= part_query('text/plain') %>">View as plain-text email</option>
104
+ </select>
105
+ </dd>
106
+ <% else %>
107
+ <dd id="mime_type" data-mime-type="<%= part_query(@email.mime_type) %>"><%= @email.mime_type == 'text/html' ? 'HTML email' : 'plain-text email' %></dd>
108
+ <% end %>
109
+
110
+ <% if I18n.available_locales.count > 1 %>
111
+ <dt>Locale:</dt>
112
+ <dd>
113
+ <select id="locale" onchange="refreshBody(true);">
114
+ <% I18n.available_locales.each do |locale| %>
115
+ <option <%= I18n.locale == locale ? 'selected' : '' %> value="<%= locale_query(locale) %>"><%= locale %></option>
116
+ <% end %>
117
+ </select>
118
+ </dd>
119
+ <% end %>
120
+ </dl>
121
+ </header>
122
+
123
+ <iframe seamless name="messageBody" src="?part=<%= part_query(@part.mime_type) %>"></iframe>
124
+
125
+ <script>
126
+ function refreshBody(reload) {
127
+ var part_select = document.querySelector('select#part');
128
+ var locale_select = document.querySelector('select#locale');
129
+ var iframe = document.getElementsByName('messageBody')[0];
130
+ var part_param = part_select ?
131
+ part_select.options[part_select.selectedIndex].value :
132
+ document.querySelector('#mime_type').dataset.mimeType;
133
+ var fresh_location = '?part=' + part_param;
134
+ var doc = iframe.contentWindow.document;
135
+
136
+ doc.open();
137
+ doc.write("Loading...");
138
+ doc.close();
139
+
140
+ iframe.contentWindow.location = fresh_location;
141
+ }
142
+ </script>
143
+
144
+ </body>
145
+ </html>
@@ -0,0 +1,8 @@
1
+ <% @previews.each do |preview| %>
2
+ <h3><%= link_to(preview.preview_name.titleize, "/jets/mailers/#{preview.preview_name}") %></h3>
3
+ <ul>
4
+ <% preview.emails.each do |email| %>
5
+ <li><%= link_to(email, "/jets/mailers/#{preview.preview_name}/#{email}") %></li>
6
+ <% end %>
7
+ </ul>
8
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h3><%= @preview.preview_name.titleize %></h3>
2
+ <ul>
3
+ <% @preview.emails.each do |email| %>
4
+ <li><%= link_to(email, "/jets/mailers/#{@preview.preview_name}/#{email}") %></li>
5
+ <% end %>
6
+ </ul>
@@ -0,0 +1,52 @@
1
+ module Jets
2
+ # Reference: https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/railtie.rb
3
+ class Mailer < ::Jets::Turbine
4
+ config.action_mailer = ActiveSupport::OrderedOptions.new
5
+
6
+ initializer "action_mailer.logger" do
7
+ ActiveSupport.on_load(:action_mailer) { self.logger ||= Jets.logger }
8
+ end
9
+
10
+ initializer "action_mailer.set_configs" do |app|
11
+ app.config.action_mailer ||= ActiveSupport::OrderedOptions.new # TODO: temp fix. only happens sometimes?
12
+ options = app.config.action_mailer
13
+ options.default_url_options ||= {}
14
+ options.default_url_options[:protocol] ||= "https"
15
+ options.show_previews = false if options.show_previews.nil?
16
+ options.preview_path ||= "#{Jets.root}/app/previews" if options.show_previews
17
+ options.view_paths ||= "#{Jets.root}/app/views"
18
+
19
+ # TODO: Dont think Jets sets asset_host the same way
20
+ # make sure readers methods get compiled
21
+ # options.asset_host ||= app.config.asset_host
22
+ # options.relative_url_root ||= app.config.relative_url_root
23
+
24
+ ActiveSupport.on_load(:action_mailer) do
25
+ include AbstractController::UrlFor
26
+ # TODO: figure out rest of the helpers
27
+ # extend ::AbstractController::Railties::RoutesHelpers.with(app.routes, false)
28
+ # include app.routes.mounted_helpers
29
+
30
+ register_interceptors(options.delete(:interceptors))
31
+ register_preview_interceptors(options.delete(:preview_interceptors))
32
+ register_observers(options.delete(:observers))
33
+
34
+ options.each { |k, v| send("#{k}=", v) }
35
+ end
36
+ end
37
+
38
+ after_initializer "action_mailer.routes" do |app|
39
+ if app.config.action_mailer.show_previews
40
+ app.routes.draw do
41
+ get "jets/mailers", to: "jets/mailers#index"
42
+ get "jets/mailers/*path", to: "jets/mailers#preview"
43
+ end
44
+
45
+ ActiveSupport.on_load :action_controller do
46
+ internal_views = File.expand_path("internal/app/views", File.dirname(__FILE__))
47
+ ActionController::Base.append_view_path(internal_views)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end