├── .gitmodules ├── .ruby-version ├── .python-version ├── docs ├── CNAME ├── Procfile ├── _docs │ ├── tutorials.md │ ├── articles.md │ ├── routing │ │ ├── overview.md │ │ └── authorizers │ │ │ └── authorizer-caching.md │ ├── debugging │ │ ├── tips.md │ │ └── payloads.md │ ├── considerations.md │ ├── testing.md │ ├── crud-json-dynamodb.md │ ├── extras │ │ ├── rake-tasks.md │ │ ├── elb-override.md │ │ └── custom-inflections.md │ ├── repl-console.md │ ├── database-support.md │ ├── routing.md │ ├── events.md │ ├── app-config │ │ ├── forgery-protection.md │ │ └── filtering_params.md │ ├── rack │ │ └── cookies.md │ ├── rails-support.md │ ├── debug-ruby-errors.md │ ├── custom-resources.md │ ├── local-server.md │ ├── database │ │ └── dynamodb.md │ └── next-steps.md ├── bin │ ├── build │ ├── rerun │ └── web ├── favicon.ico ├── .gitignore ├── img │ ├── docs │ │ ├── sns-topic.png │ │ ├── sqs-queue.png │ │ ├── iot-diagram.png │ │ ├── kinesis-log.png │ │ ├── mqtt-client.png │ │ ├── dynamodb-stream.png │ │ ├── email-preview.png │ │ ├── iot-topic-rule.png │ │ ├── kinesis-lambda.png │ │ ├── prewarm-header.png │ │ ├── s3-sns-fanout.png │ │ ├── aws-config-rules.png │ │ ├── crud │ │ │ ├── posts-index.png │ │ │ └── posts-index-json.png │ │ ├── dynamodb-trigger.png │ │ ├── cloudwatch-log-group.png │ │ ├── dynamodb-event-log.png │ │ ├── iot-cloudwatch-log.png │ │ ├── minimal-iam-policy.png │ │ ├── cloudwatch-event-rule.png │ │ ├── cloudwatch-log-streams.png │ │ ├── cloudwatch-event-rule-log.png │ │ ├── cloudwatch-log-search-5m.png │ │ ├── cloudwatch-search-exclude.png │ │ ├── demo-job-cloudwatch-rule.png │ │ ├── lambda-console-ruby-error.png │ │ ├── logs-subscription-filter.png │ │ ├── cloudwatch-log-stream-click.png │ │ ├── demo-lambda-functions-jobs.png │ │ ├── cloudwatch-log-stream-single.png │ │ ├── faster-development-live-edit.png │ │ ├── poly │ │ │ ├── poly-lambda-function-node.png │ │ │ ├── poly-lambda-function-python.png │ │ │ └── poly-lambda-functions-list.png │ │ ├── routing │ │ │ ├── jets-vanity-endpoint.png │ │ │ └── jets-vanity-endpoint-cloudfront.png │ │ ├── demo-lambda-functions-controller.png │ │ ├── considerations │ │ │ ├── lambda-bootstrap-vpc.png │ │ │ ├── lambda-vpc-cold-start.png │ │ │ ├── lambda-vpc-delete-time.png │ │ │ └── vpc-config-nat-gateway.png │ │ ├── jets-simple-lambda-function-console.png │ │ ├── jets-simple-lambda-function-result.png │ │ ├── logs-subscription-filter-cloudwatch.png │ │ ├── rails │ │ │ └── mount-bootsnap-write-access.png │ │ ├── debug │ │ │ └── cloudformation-child-stack-error.png │ │ ├── extras │ │ │ └── deploy-stagger-lambda-functions.png │ │ ├── api-gateway-multiple-variables-path-error.png │ │ └── cloudformation-multiple-variables-path-error.png │ ├── logos │ │ ├── jets-logo.png │ │ ├── boltops-logo.png │ │ ├── jets-logo-full.png │ │ └── boltops-logo-full.png │ ├── support-jets │ │ ├── patreon.png │ │ └── paypal.png │ ├── quick-start │ │ ├── posts-index.png │ │ ├── demo-api-gateway.png │ │ └── demo-lambda-functions.png │ ├── home │ │ └── jets-web-architecture.png │ └── cli │ │ └── deploy-cloudformation-status.png ├── _includes │ ├── js.html │ ├── rails-update.md │ ├── reference.md │ ├── google_analytics.html │ ├── example.html │ ├── cloudformation_links.md │ └── content.html ├── vendor │ ├── font-awesome │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── less │ │ │ ├── screen-reader.less │ │ │ ├── fixed-width.less │ │ │ ├── larger.less │ │ │ ├── list.less │ │ │ ├── core.less │ │ │ ├── stacked.less │ │ │ ├── font-awesome.less │ │ │ ├── bordered-pulled.less │ │ │ └── rotated-flipped.less │ │ └── scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _larger.scss │ │ │ ├── _list.scss │ │ │ ├── _core.scss │ │ │ ├── font-awesome.scss │ │ │ ├── _stacked.scss │ │ │ └── _bordered-pulled.scss │ └── simple-line-icons │ │ └── fonts │ │ ├── Simple-Line-Icons.eot │ │ ├── Simple-Line-Icons.ttf │ │ ├── Simple-Line-Icons.woff │ │ └── Simple-Line-Icons.woff2 ├── Gemfile ├── _reference │ ├── jets-dotenv-show.md │ ├── jets-gems-sources.md │ ├── jets-dynamodb-migrate-down.md │ ├── jets-secret.md │ ├── jets-version.md │ ├── jets-middleware.md │ ├── jets-dynamodb-migrate.md │ ├── jets-url.md │ ├── jets-gems-check.md │ ├── jets-dbconsole.md │ ├── jets-upgrade.md │ ├── jets-clean-log.md │ ├── jets-db-generate.md │ ├── jets-runner.md │ ├── jets-build.md │ └── jets-clean-build.md ├── opal │ └── app.rb ├── _data │ └── video_playlists.yml ├── _sass │ ├── bootstrap-overrides.scss │ ├── table.scss │ ├── content.scss │ └── cta.scss └── css │ └── main.scss ├── lib └── jets │ ├── turbo │ └── project │ │ ├── .jetskeep │ │ ├── Rakefile │ │ ├── app │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── controllers │ │ │ └── application_controller.rb │ │ └── jobs │ │ │ └── application_job.rb │ │ ├── config │ │ ├── routes.rb │ │ └── application.rb │ │ ├── config.ru │ │ ├── .gitignore │ │ └── Gemfile │ ├── commands │ ├── templates │ │ ├── skeleton │ │ │ ├── db │ │ │ │ └── .gitkeep │ │ │ ├── .jetskeep │ │ │ ├── Rakefile │ │ │ ├── .rspec │ │ │ ├── app │ │ │ │ ├── helpers │ │ │ │ │ └── application_helper.rb │ │ │ │ ├── models │ │ │ │ │ ├── application_item.rb │ │ │ │ │ └── application_record.rb │ │ │ │ ├── controllers │ │ │ │ │ └── application_controller.rb │ │ │ │ └── jobs │ │ │ │ │ └── application_job.rb │ │ │ ├── .env.test │ │ │ ├── public │ │ │ │ └── favicon.ico │ │ │ ├── config.ru │ │ │ ├── .gitignore │ │ │ ├── .env.tt │ │ │ ├── .env.development.tt │ │ │ ├── config │ │ │ │ ├── environments │ │ │ │ │ ├── development.rb │ │ │ │ │ ├── test.rb │ │ │ │ │ └── production.rb │ │ │ │ └── routes.rb │ │ │ ├── Procfile │ │ │ ├── README.md │ │ │ └── spec │ │ │ │ └── controllers │ │ │ │ └── posts_controller_spec.rb │ │ └── webpacker │ │ │ └── app │ │ │ └── javascript │ │ │ └── packs │ │ │ └── theme.scss.tt │ ├── db │ │ ├── environment-task.rake │ │ └── tasks │ │ │ └── dummy │ │ │ ├── config.rb │ │ │ └── app.rb │ ├── help │ │ ├── dynamodb │ │ │ └── migrate.md │ │ ├── clean │ │ │ ├── log.md │ │ │ └── build.md │ │ ├── dbconsole.md │ │ ├── url.md │ │ ├── upgrade.md │ │ ├── gems │ │ │ └── check.md │ │ ├── runner.md │ │ ├── build.md │ │ ├── db │ │ │ └── generate.md │ │ ├── import │ │ │ ├── rails.md │ │ │ └── rack.md │ │ ├── console.md │ │ ├── server.md │ │ ├── degenerate.md │ │ ├── routes.md │ │ └── status.md │ ├── dotenv.rb │ ├── help.rb │ ├── markdown │ │ ├── shell.rb │ │ └── index.rb │ ├── clean │ │ ├── build.rb │ │ └── base.rb │ ├── dynamodb │ │ └── migrate.rb │ ├── console.rb │ ├── runner.rb │ ├── db.rb │ ├── import.rb │ ├── upgrade │ │ └── templates │ │ │ └── bin │ │ │ ├── webpack │ │ │ └── webpack-dev-server │ ├── gems.rb │ ├── import │ │ └── rack.rb │ └── clean.rb │ ├── version.rb │ ├── overrides │ ├── lambda.rb │ ├── rails.rb │ └── rails │ │ ├── action_controller.rb │ │ └── common_methods.rb │ ├── stack │ ├── main.rb │ ├── main │ │ ├── dsl │ │ │ ├── iam.rb │ │ │ ├── s3.rb │ │ │ ├── kinesis.rb │ │ │ ├── sns.rb │ │ │ ├── sqs.rb │ │ │ └── cloudwatch.rb │ │ └── dsl.rb │ ├── output │ │ └── dsl.rb │ └── resource │ │ └── dsl.rb │ ├── router │ ├── error.rb │ ├── helpers.rb │ ├── resources │ │ ├── base.rb │ │ ├── filter.rb │ │ └── options.rb │ ├── helpers │ │ ├── named_routes_helper.rb │ │ └── core_helper.rb │ ├── method_creator │ │ ├── generic.rb │ │ ├── root.rb │ │ ├── show.rb │ │ ├── edit.rb │ │ └── new.rb │ └── dsl │ │ └── mount.rb │ ├── camelizer.rb │ ├── controller.rb │ ├── controller │ ├── error.rb │ ├── error │ │ └── invalid_authenticity_token.rb │ ├── middleware │ │ ├── webpacker_setup.rb │ │ ├── reloader.rb │ │ └── local │ │ │ └── route_matcher.rb │ └── layout.rb │ ├── generator │ └── templates │ │ ├── erb │ │ ├── controller │ │ │ └── view.html.erb │ │ └── scaffold │ │ │ ├── new.html.erb │ │ │ ├── edit.html.erb │ │ │ └── show.html.erb │ │ ├── rails │ │ ├── helper │ │ │ └── helper.rb │ │ ├── assets │ │ │ ├── stylesheet.css │ │ │ └── javascript.js │ │ └── controller │ │ │ └── controller.rb │ │ └── active_job │ │ └── job │ │ └── templates │ │ ├── job.rb.tt │ │ └── application_job.rb.tt │ ├── resource │ ├── api_gateway │ │ └── rest_api │ │ │ ├── routes.rb │ │ │ ├── change_detection.rb │ │ │ └── routes │ │ │ ├── collision │ │ │ └── variable_exception.rb │ │ │ └── change.rb │ ├── child_stack │ │ ├── common_parameters.rb │ │ ├── api_gateway.rb │ │ └── base.rb │ ├── config │ │ └── managed_rule.rb │ ├── lambda │ │ └── gem_layer.rb │ ├── sqs │ │ └── queue.rb │ ├── s3 │ │ └── bucket.rb │ └── iam │ │ └── managed_policy.rb │ ├── builders │ ├── rackup_wrappers │ │ ├── rackup.rb │ │ └── rackup │ ├── templates │ │ └── handler.rb │ ├── shim_vars │ │ └── base.rb │ └── util.rb │ ├── internal │ └── app │ │ ├── helpers │ │ └── jets │ │ │ └── mailers_helper.rb │ │ ├── views │ │ └── jets │ │ │ └── mailers │ │ │ ├── mailer.html.erb │ │ │ └── index.html.erb │ │ ├── controllers │ │ └── jets │ │ │ ├── rack_controller.rb │ │ │ └── bare_controller.rb │ │ └── functions │ │ └── jets │ │ └── base_path.rb │ ├── poly_fun │ ├── node_error.rb │ ├── python_error.rb │ ├── lambda_executor.rb │ └── python_executor.rb │ ├── cfn │ ├── status.rb │ ├── builders │ │ ├── job_builder.rb │ │ ├── function_builder.rb │ │ ├── shared_builder.rb │ │ ├── util │ │ │ └── source.rb │ │ └── rule_builder.rb │ └── built_template.rb │ ├── dotenv │ └── show.rb │ ├── spec_helpers │ ├── fixtures.rb │ └── controllers │ │ ├── response.rb │ │ └── params.rb │ ├── core_ext │ ├── bundler.rb │ └── kernel.rb │ ├── job │ ├── helpers │ │ ├── kinesis_event_helper.rb │ │ ├── s3_event_helper.rb │ │ └── log_event_helper.rb │ └── dsl │ │ ├── event_source_mapping.rb │ │ └── log_event.rb │ ├── db.rb │ ├── spec_helpers.rb │ ├── mega │ ├── request │ │ └── source.rb │ └── hash_converter.rb │ ├── rule │ └── base.rb │ ├── logger.rb │ ├── rdoc.rb │ └── middleware │ └── layer.rb ├── spec ├── lib │ └── jets │ │ ├── stack │ │ └── depends │ │ │ └── item_spec.rb │ │ ├── naming_spec.rb │ │ ├── commands │ │ └── deploy_spec.rb │ │ ├── internal │ │ └── preheat_job_spec.rb │ │ ├── namespace_spec.rb │ │ ├── middleware │ │ ├── layer_spec.rb │ │ └── default_stack_spec.rb │ │ ├── poly_fun │ │ └── node_executor_spec.rb │ │ ├── resource │ │ ├── lambda │ │ │ └── gem_layer_spec.rb │ │ ├── child_stack │ │ │ ├── api_gateway_spec.rb │ │ │ ├── api_deployment_spec.rb │ │ │ └── shared_spec.rb │ │ ├── api_gateway │ │ │ ├── domain_name_spec.rb │ │ │ └── rest_api │ │ │ │ └── routes │ │ │ │ └── change_detection.rb │ │ └── replacer_spec.rb │ │ ├── controller │ │ └── middleware │ │ │ └── local │ │ │ └── api_gateway_spec.rb │ │ ├── cfn │ │ ├── ship_spec.rb │ │ └── builders │ │ │ ├── api_deployment_spec.rb │ │ │ ├── job_builder_spec.rb │ │ │ └── rule_builder_spec.rb │ │ ├── builders │ │ ├── tidy_spec.rb │ │ └── md5_zip_spec.rb │ │ ├── generate_spec.rb │ │ ├── middleware_spec.rb │ │ └── functions │ │ └── base_path_spec.rb ├── fixtures │ ├── apps │ │ └── franky │ │ │ ├── .jetskeep │ │ │ ├── .env │ │ │ ├── app │ │ │ ├── shared │ │ │ │ ├── functions │ │ │ │ │ ├── bob.rb │ │ │ │ │ ├── gru.rb │ │ │ │ │ ├── hello.rb │ │ │ │ │ ├── howdy.py │ │ │ │ │ ├── kevin.py │ │ │ │ │ ├── stuart.js │ │ │ │ │ ├── admin │ │ │ │ │ │ └── send_message.rb │ │ │ │ │ └── whatever.rb │ │ │ │ └── resources │ │ │ │ │ ├── alert.rb │ │ │ │ │ └── custom.rb │ │ │ ├── controllers │ │ │ │ ├── books_controller │ │ │ │ │ └── node │ │ │ │ │ │ ├── hello.js │ │ │ │ │ │ ├── node_error_test.js │ │ │ │ │ │ ├── node_async.js │ │ │ │ │ │ └── list.js │ │ │ │ ├── admin │ │ │ │ │ ├── stores_controller.rb │ │ │ │ │ ├── pages_controller.rb │ │ │ │ │ └── related_pages_controller.rb │ │ │ │ ├── application_controller.rb │ │ │ │ ├── others_controller.rb │ │ │ │ ├── related_posts_controller.rb │ │ │ │ ├── books_controller.rb │ │ │ │ ├── child_posts_controller.rb │ │ │ │ ├── comments_controller.rb │ │ │ │ ├── public_files_controller.rb │ │ │ │ └── stores_controller.rb │ │ │ ├── views │ │ │ │ ├── posts │ │ │ │ │ ├── _test.html.erb │ │ │ │ │ └── index.html.erb │ │ │ │ ├── stores │ │ │ │ │ ├── index.html.erb │ │ │ │ │ └── new.html.erb │ │ │ │ ├── toys │ │ │ │ │ ├── new.html.erb │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ └── show.html.erb │ │ │ │ └── articles │ │ │ │ │ ├── new.html.erb │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ └── show.html.erb │ │ │ ├── helpers │ │ │ │ ├── toys_helper.rb │ │ │ │ ├── articles_helper.rb │ │ │ │ └── application_helper.rb │ │ │ ├── models │ │ │ │ ├── post.rb │ │ │ │ ├── toy.rb │ │ │ │ ├── article.rb │ │ │ │ ├── comment.rb │ │ │ │ ├── application_item.rb │ │ │ │ ├── ns │ │ │ │ │ └── a.rb │ │ │ │ └── application_record.rb │ │ │ ├── jobs │ │ │ │ ├── application_job.rb │ │ │ │ ├── error_job.rb │ │ │ │ ├── temperature_job.rb │ │ │ │ ├── easy_job.rb │ │ │ │ └── security_job.rb │ │ │ ├── authorizers │ │ │ │ └── application_authorizer.rb │ │ │ ├── functions │ │ │ │ ├── hello.rb │ │ │ │ └── simple_function.rb │ │ │ ├── javascript │ │ │ │ └── packs │ │ │ │ │ ├── framework.js │ │ │ │ │ └── application.js │ │ │ └── extensions │ │ │ │ └── iot_extension.rb │ │ │ ├── .env.staging │ │ │ ├── .env.test.local │ │ │ ├── .env.test.remote │ │ │ ├── public │ │ │ ├── assets │ │ │ │ ├── a.txt │ │ │ │ ├── photo.jpg │ │ │ │ └── sample.pdf │ │ │ ├── stylesheets │ │ │ │ └── test.css │ │ │ ├── javascripts │ │ │ │ └── test.js │ │ │ └── favicon.ico │ │ │ ├── Rakefile │ │ │ ├── .env.development │ │ │ ├── bin │ │ │ ├── console │ │ │ ├── dev │ │ │ │ ├── server │ │ │ │ └── deploy │ │ │ ├── webpack │ │ │ └── webpack-dev-server │ │ │ ├── .env.test │ │ │ ├── .postcssrc.yml │ │ │ ├── config │ │ │ ├── initializers │ │ │ │ ├── 01_initializer.rb │ │ │ │ └── 02_initializer.rb │ │ │ ├── webpack │ │ │ │ ├── environment.js │ │ │ │ ├── test.js │ │ │ │ ├── staging.js │ │ │ │ ├── development.js │ │ │ │ └── production.js │ │ │ ├── environments │ │ │ │ ├── development.rb │ │ │ │ └── production.rb │ │ │ └── database.yml │ │ │ ├── payloads │ │ │ ├── hello.json │ │ │ └── create.json │ │ │ ├── config.ru │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ ├── db │ │ │ └── migrate │ │ │ │ ├── 20171114235317_create_articles.rb │ │ │ │ └── 20171127132819_create_toys.rb │ │ │ ├── Procfile │ │ │ ├── README.md │ │ │ ├── .babelrc │ │ │ └── spec │ │ │ ├── jets_helper.rb │ │ │ └── spec_helper.rb │ ├── dumps │ │ ├── lambda │ │ │ └── from_logs │ │ │ │ └── request-before.json │ │ ├── api_gateway │ │ │ └── response.json │ │ └── logs │ │ │ └── log_event.json │ ├── multipart │ │ ├── binary │ │ ├── nested │ │ ├── text │ │ └── simple_form │ ├── routes │ │ └── resources.rb │ ├── authorizers │ │ └── token.json │ ├── resource_pages │ │ ├── demo-test-api-resources-3.yml │ │ ├── demo-test-api-resources-1.yml │ │ └── demo-test-api-resources-2.yml │ └── db_configs │ │ ├── database.single.yml │ │ └── database.multi.yml └── integration │ └── fixtures │ └── postman │ └── environment.json ├── CONDUCT.md ├── CONTRIBUTING.md ├── .rspec ├── Procfile ├── .cody ├── docs │ ├── bin │ │ ├── cli_docs.sh │ │ ├── build.sh │ │ ├── bundler_setup.sh │ │ ├── git_setup.sh │ │ └── subnav.sh │ ├── buildspec.yml │ └── project.rb └── README.md ├── readme └── prerelease.md ├── bin └── release ├── exe └── jets ├── .gitignore ├── Dockerfile ├── Gemfile ├── .github ├── ISSUE_TEMPLATE.md └── ISSUE_TEMPLATE │ ├── documentation.md │ └── question.md ├── Rakefile ├── Guardfile └── backers.md /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.2 2 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.8.6 2 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | rubyonjets.com -------------------------------------------------------------------------------- /lib/jets/turbo/project/.jetskeep: -------------------------------------------------------------------------------- 1 | pack 2 | -------------------------------------------------------------------------------- /spec/lib/jets/stack/depends/item_spec.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | http://rubyonjets.com/docs/conduct/ -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/db/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.jetskeep: -------------------------------------------------------------------------------- 1 | pack 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env: -------------------------------------------------------------------------------- 1 | ENV_KEY=example1 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/bob.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/gru.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | http://rubyonjets.com/docs/contributing/ -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.jetskeep: -------------------------------------------------------------------------------- 1 | pack 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env.staging: -------------------------------------------------------------------------------- 1 | MYKEY=example1 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env.test.local: -------------------------------------------------------------------------------- 1 | ONLY_LOCAL=1 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/hello.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/howdy.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/kevin.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/stuart.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env.test.remote: -------------------------------------------------------------------------------- 1 | ONLY_REMOTE=1 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/assets/a.txt: -------------------------------------------------------------------------------- 1 | a.txt file 2 | -------------------------------------------------------------------------------- /spec/fixtures/dumps/lambda/from_logs/request-before.json: -------------------------------------------------------------------------------- 1 | [EMPTY] -------------------------------------------------------------------------------- /docs/Procfile: -------------------------------------------------------------------------------- 1 | web: bin/web --host 0.0.0.0 2 | opal: bin/rerun 3 | -------------------------------------------------------------------------------- /lib/jets/version.rb: -------------------------------------------------------------------------------- 1 | module Jets 2 | VERSION = "3.0.17" 3 | end 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/admin/send_message.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/jets/overrides/lambda.rb: -------------------------------------------------------------------------------- 1 | require "jets/overrides/lambda/marshaller" -------------------------------------------------------------------------------- /lib/jets/turbo/project/Rakefile: -------------------------------------------------------------------------------- 1 | require 'jets' 2 | Jets.load_tasks 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/Rakefile: -------------------------------------------------------------------------------- 1 | require 'jets' 2 | Jets.load_tasks 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/books_controller/node/hello.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/posts/_test.html.erb: -------------------------------------------------------------------------------- 1 | partial test 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env.development: -------------------------------------------------------------------------------- 1 | ENV_DEVELOPMENT_KEY=example1 2 | -------------------------------------------------------------------------------- /lib/jets/stack/main.rb: -------------------------------------------------------------------------------- 1 | class Jets::Stack 2 | class Main 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/helpers/toys_helper.rb: -------------------------------------------------------------------------------- 1 | module ToysHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/stores/index.html.erb: -------------------------------------------------------------------------------- 1 | stores index test page -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/Rakefile: -------------------------------------------------------------------------------- 1 | require 'jets' 2 | Jets.load_tasks 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/post.rb: -------------------------------------------------------------------------------- 1 | class Post < ApplicationItem 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/toy.rb: -------------------------------------------------------------------------------- 1 | class Toy < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /docs/_docs/tutorials.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tutorials 3 | --- 4 | 5 | {% include tutorials.md %} -------------------------------------------------------------------------------- /docs/bin/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bundle exec jekyll build 4 | bundle exec rake opal:build -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/favicon.ico -------------------------------------------------------------------------------- /lib/jets/commands/db/environment-task.rake: -------------------------------------------------------------------------------- 1 | task :environment do 2 | Jets.boot 3 | end 4 | -------------------------------------------------------------------------------- /lib/jets/router/error.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router 2 | class Error < RuntimeError 3 | end 4 | end -------------------------------------------------------------------------------- /lib/jets/turbo/project/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/helpers/articles_helper.rb: -------------------------------------------------------------------------------- 1 | module ArticlesHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/article.rb: -------------------------------------------------------------------------------- 1 | class Article < ApplicationRecord 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/comment.rb: -------------------------------------------------------------------------------- 1 | class Comment < ApplicationItem 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/bin/console: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | exec bundle exec jets console 4 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .sass-cache 3 | .jekyll-metadata 4 | .jekyll-cache 5 | Gemfile.lock 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /docs/_docs/articles.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Articles 3 | --- 4 | 5 | {% include tutorials.md %} 6 | 7 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/stylesheets/test.css: -------------------------------------------------------------------------------- 1 | /* public/assets/test.css */ 2 | body { 3 | } 4 | -------------------------------------------------------------------------------- /docs/_docs/routing/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Routing 3 | --- 4 | 5 | {% include routing.md %} 6 | 7 | -------------------------------------------------------------------------------- /docs/bin/rerun: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec bundle exec rerun -x --background --pattern 'opal/*.rb' 'rake opal:build' -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < Jets::Job::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/application_item.rb: -------------------------------------------------------------------------------- 1 | class ApplicationItem < Dynomite::Item 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/javascripts/test.js: -------------------------------------------------------------------------------- 1 | console.log("test from public/assets/test.js"); 2 | -------------------------------------------------------------------------------- /docs/img/docs/sns-topic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/sns-topic.png -------------------------------------------------------------------------------- /docs/img/docs/sqs-queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/sqs-queue.png -------------------------------------------------------------------------------- /docs/img/logos/jets-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/logos/jets-logo.png -------------------------------------------------------------------------------- /lib/jets/camelizer.rb: -------------------------------------------------------------------------------- 1 | # Wrapper to CfnCamelizer gem 2 | module Jets 3 | Camelizer = CfnCamelizer 4 | end 5 | -------------------------------------------------------------------------------- /lib/jets/controller.rb: -------------------------------------------------------------------------------- 1 | class Jets::Controller 2 | DEFAULT_CONTENT_TYPE = "text/html; charset=utf-8" 3 | end 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.env.test: -------------------------------------------------------------------------------- 1 | env_key1=env_value1 2 | env_key2=env_value2 3 | SKIP_MIGRATION_CHECK=true 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.postcssrc.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | postcss-smart-import: {} 3 | postcss-cssnext: {} 4 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --exclude-pattern spec/fixtures/apps/**/* 3 | --format documentation 4 | --require spec_helper 5 | -------------------------------------------------------------------------------- /docs/img/docs/iot-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/iot-diagram.png -------------------------------------------------------------------------------- /docs/img/docs/kinesis-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/kinesis-log.png -------------------------------------------------------------------------------- /docs/img/docs/mqtt-client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/mqtt-client.png -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/app/models/application_item.rb: -------------------------------------------------------------------------------- 1 | class ApplicationItem < Dynomite::Item 2 | end 3 | -------------------------------------------------------------------------------- /lib/jets/controller/error.rb: -------------------------------------------------------------------------------- 1 | class Jets::Controller 2 | class Error < RuntimeError #:nodoc: 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/initializers/01_initializer.rb: -------------------------------------------------------------------------------- 1 | JETS_TEST_INITIALIZER_ONE_TIME = DateTime.current 2 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/initializers/02_initializer.rb: -------------------------------------------------------------------------------- 1 | JETS_TEST_INITIALIZER_TWO_TIME = DateTime.current 2 | -------------------------------------------------------------------------------- /spec/fixtures/multipart/binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/spec/fixtures/multipart/binary -------------------------------------------------------------------------------- /docs/img/docs/dynamodb-stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/dynamodb-stream.png -------------------------------------------------------------------------------- /docs/img/docs/email-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/email-preview.png -------------------------------------------------------------------------------- /docs/img/docs/iot-topic-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/iot-topic-rule.png -------------------------------------------------------------------------------- /docs/img/docs/kinesis-lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/kinesis-lambda.png -------------------------------------------------------------------------------- /docs/img/docs/prewarm-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/prewarm-header.png -------------------------------------------------------------------------------- /docs/img/docs/s3-sns-fanout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/s3-sns-fanout.png -------------------------------------------------------------------------------- /docs/img/logos/boltops-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/logos/boltops-logo.png -------------------------------------------------------------------------------- /docs/img/logos/jets-logo-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/logos/jets-logo-full.png -------------------------------------------------------------------------------- /docs/img/support-jets/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/support-jets/patreon.png -------------------------------------------------------------------------------- /docs/img/support-jets/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/support-jets/paypal.png -------------------------------------------------------------------------------- /lib/jets/router/helpers.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Helpers 2 | include CoreHelper 3 | include NamedRoutesHelper 4 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/resources/alert.rb: -------------------------------------------------------------------------------- 1 | class Alert < Jets::Stack 2 | sns_topic "delivered" 3 | end 4 | -------------------------------------------------------------------------------- /docs/img/docs/aws-config-rules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/aws-config-rules.png -------------------------------------------------------------------------------- /docs/img/docs/crud/posts-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/crud/posts-index.png -------------------------------------------------------------------------------- /docs/img/docs/dynamodb-trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/dynamodb-trigger.png -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/payloads/hello.json: -------------------------------------------------------------------------------- 1 | { 2 | "key1": "value1", 3 | "key2": "value2", 4 | "key3": "value3" 5 | } 6 | -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-log-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-log-group.png -------------------------------------------------------------------------------- /docs/img/docs/dynamodb-event-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/dynamodb-event-log.png -------------------------------------------------------------------------------- /docs/img/docs/iot-cloudwatch-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/iot-cloudwatch-log.png -------------------------------------------------------------------------------- /docs/img/docs/minimal-iam-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/minimal-iam-policy.png -------------------------------------------------------------------------------- /docs/img/logos/boltops-logo-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/logos/boltops-logo-full.png -------------------------------------------------------------------------------- /docs/img/quick-start/posts-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/quick-start/posts-index.png -------------------------------------------------------------------------------- /lib/jets/turbo/project/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < Jets::Controller::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/authorizers/application_authorizer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationAuthorizer < Jets::Authorizer::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/admin/stores_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::StoresController < StoresController 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < Jets::Controller::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/payloads/create.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "myid", 3 | "title": "test title", 4 | "desc": "test desc" 5 | } 6 | -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-event-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-event-rule.png -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-log-streams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-log-streams.png -------------------------------------------------------------------------------- /docs/img/docs/crud/posts-index-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/crud/posts-index-json.png -------------------------------------------------------------------------------- /docs/img/home/jets-web-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/home/jets-web-architecture.png -------------------------------------------------------------------------------- /lib/jets/generator/templates/erb/controller/view.html.erb: -------------------------------------------------------------------------------- 1 |

<%= class_name %>#<%= @action %>

2 |

Find me in <%= @path %>

3 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/ns/a.rb: -------------------------------------------------------------------------------- 1 | # Test for namespace autovivification: spec/lib/jets/namespace_spec.rb 2 | class Ns::A 3 | end -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-event-rule-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-event-rule-log.png -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-log-search-5m.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-log-search-5m.png -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-search-exclude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-search-exclude.png -------------------------------------------------------------------------------- /docs/img/docs/demo-job-cloudwatch-rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/demo-job-cloudwatch-rule.png -------------------------------------------------------------------------------- /docs/img/docs/lambda-console-ruby-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/lambda-console-ruby-error.png -------------------------------------------------------------------------------- /docs/img/docs/logs-subscription-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/logs-subscription-filter.png -------------------------------------------------------------------------------- /docs/img/quick-start/demo-api-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/quick-start/demo-api-gateway.png -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.env.test: -------------------------------------------------------------------------------- 1 | # Example .env.test, meant to be updated. 2 | env_key1=env_value1 3 | env_key2=env_value2 4 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < Jets::Controller::Base 2 | end 3 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/rails/helper/helper.rb: -------------------------------------------------------------------------------- 1 | <% module_namespacing do -%> 2 | module <%= class_name %>Helper 3 | end 4 | <% end -%> 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/stores/new.html.erb: -------------------------------------------------------------------------------- 1 |

stores/new.html.erb file

2 | 3 |

Item name: <%= @item[:name] %>

4 | -------------------------------------------------------------------------------- /docs/img/cli/deploy-cloudformation-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/cli/deploy-cloudformation-status.png -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-log-stream-click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-log-stream-click.png -------------------------------------------------------------------------------- /docs/img/docs/demo-lambda-functions-jobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/demo-lambda-functions-jobs.png -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/posts/index.html.erb: -------------------------------------------------------------------------------- 1 |

app/views/index.html.erb

2 | 3 | <%= render "test" %> 4 | 5 |

test

6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/spec/fixtures/apps/franky/public/favicon.ico -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | local: dynamodb-local # port 8000 2 | admin: env AWS_ACCESS_KEY_ID=$DYNAMODB_ADMIN_AWS_ACCESS_KEY_ID PORT=8001 dynamodb-admin # port 8001 3 | -------------------------------------------------------------------------------- /docs/_includes/js.html: -------------------------------------------------------------------------------- 1 | {% if site.google_analytics and jekyll.environment == "production" %} 2 | {% include google_analytics.html %} 3 | {% endif %} 4 | -------------------------------------------------------------------------------- /docs/img/docs/cloudwatch-log-stream-single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudwatch-log-stream-single.png -------------------------------------------------------------------------------- /docs/img/docs/faster-development-live-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/faster-development-live-edit.png -------------------------------------------------------------------------------- /docs/img/docs/poly/poly-lambda-function-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/poly/poly-lambda-function-node.png -------------------------------------------------------------------------------- /docs/img/docs/routing/jets-vanity-endpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/routing/jets-vanity-endpoint.png -------------------------------------------------------------------------------- /docs/img/quick-start/demo-lambda-functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/quick-start/demo-lambda-functions.png -------------------------------------------------------------------------------- /docs/vendor/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/webpack/environment.js: -------------------------------------------------------------------------------- 1 | const { environment } = require('@rails/webpacker') 2 | 3 | module.exports = environment 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/webpack/test.js: -------------------------------------------------------------------------------- 1 | const environment = require('./environment') 2 | 3 | module.exports = environment.toWebpackConfig() 4 | -------------------------------------------------------------------------------- /spec/fixtures/dumps/api_gateway/response.json: -------------------------------------------------------------------------------- 1 | { 2 | "statusCode": 200, 3 | "body": "must be a string, even if it is json, it should be a string" 4 | } -------------------------------------------------------------------------------- /docs/img/docs/demo-lambda-functions-controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/demo-lambda-functions-controller.png -------------------------------------------------------------------------------- /docs/img/docs/poly/poly-lambda-function-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/poly/poly-lambda-function-python.png -------------------------------------------------------------------------------- /docs/img/docs/poly/poly-lambda-functions-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/poly/poly-lambda-functions-list.png -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/toys/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Toy

2 | 3 | <%= render 'form', toy: @toy %> 4 | 5 | <%= link_to 'Back', "/toys" %> 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 1536 4 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 2048 4 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/webpack/staging.js: -------------------------------------------------------------------------------- 1 | const environment = require('./environment') 2 | 3 | module.exports = environment.toWebpackConfig() 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/assets/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/spec/fixtures/apps/franky/public/assets/photo.jpg -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/public/assets/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/spec/fixtures/apps/franky/public/assets/sample.pdf -------------------------------------------------------------------------------- /docs/bin/web: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # Usage: 4 | # bin/web 5 | # bin/web -P 8888 6 | 7 | bundle exec jekyll clean 8 | exec bundle exec jekyll serve "$@" 9 | -------------------------------------------------------------------------------- /docs/img/docs/considerations/lambda-bootstrap-vpc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/considerations/lambda-bootstrap-vpc.png -------------------------------------------------------------------------------- /docs/img/docs/jets-simple-lambda-function-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/jets-simple-lambda-function-console.png -------------------------------------------------------------------------------- /docs/img/docs/jets-simple-lambda-function-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/jets-simple-lambda-function-result.png -------------------------------------------------------------------------------- /docs/img/docs/logs-subscription-filter-cloudwatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/logs-subscription-filter-cloudwatch.png -------------------------------------------------------------------------------- /docs/img/docs/rails/mount-bootsnap-write-access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/rails/mount-bootsnap-write-access.png -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /lib/jets/turbo/project/config/routes.rb: -------------------------------------------------------------------------------- 1 | Jets.application.routes.draw do 2 | root "jets/rack#process" 3 | any "*catchall", to: "jets/rack#process" 4 | end 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/webpack/development.js: -------------------------------------------------------------------------------- 1 | const environment = require('./environment') 2 | 3 | module.exports = environment.toWebpackConfig() 4 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/webpack/production.js: -------------------------------------------------------------------------------- 1 | const environment = require('./environment') 2 | 3 | module.exports = environment.toWebpackConfig() 4 | -------------------------------------------------------------------------------- /docs/img/docs/considerations/lambda-vpc-cold-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/considerations/lambda-vpc-cold-start.png -------------------------------------------------------------------------------- /docs/img/docs/considerations/lambda-vpc-delete-time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/considerations/lambda-vpc-delete-time.png -------------------------------------------------------------------------------- /docs/img/docs/considerations/vpc-config-nat-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/considerations/vpc-config-nat-gateway.png -------------------------------------------------------------------------------- /docs/vendor/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/vendor/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/lib/jets/commands/templates/skeleton/public/favicon.ico -------------------------------------------------------------------------------- /lib/jets/turbo/project/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require "jets" 4 | Jets.boot 5 | run Jets.application 6 | -------------------------------------------------------------------------------- /docs/img/docs/debug/cloudformation-child-stack-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/debug/cloudformation-child-stack-error.png -------------------------------------------------------------------------------- /docs/img/docs/extras/deploy-stagger-lambda-functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/extras/deploy-stagger-lambda-functions.png -------------------------------------------------------------------------------- /docs/img/docs/routing/jets-vanity-endpoint-cloudfront.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/routing/jets-vanity-endpoint-cloudfront.png -------------------------------------------------------------------------------- /docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /lib/jets/commands/help/dynamodb/migrate.md: -------------------------------------------------------------------------------- 1 | ## Examples 2 | 3 | jets dynamodb:migrate path/to/migration 4 | jets dynamodb:migrate db/migrate/posts_migration.rb 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require "jets" 4 | Jets.boot 5 | run Jets.application 6 | -------------------------------------------------------------------------------- /docs/img/docs/api-gateway-multiple-variables-path-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/api-gateway-multiple-variables-path-error.png -------------------------------------------------------------------------------- /docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/articles/new.html.erb: -------------------------------------------------------------------------------- 1 |

New Article

2 | 3 | <%= render 'form', article: @article %> 4 | 5 | <%= link_to 'Back', "/articles" %> 6 | -------------------------------------------------------------------------------- /docs/_docs/debugging/tips.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Debugging Tips 3 | --- 4 | 5 | The next sections provide some debugging help tips for common issues. Hopefully, they are helpful. 6 | 7 | -------------------------------------------------------------------------------- /docs/img/docs/cloudformation-multiple-variables-path-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrevorHinesley/jets/master/docs/img/docs/cloudformation-multiple-variables-path-error.png -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require "jets" 4 | Jets.boot 5 | run Jets.application 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/jobs/error_job.rb: -------------------------------------------------------------------------------- 1 | class ErrorJob < ApplicationJob 2 | rate "10 hours" # every 10 hours 3 | def break 4 | raise "break me" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/fixtures/routes/resources.rb: -------------------------------------------------------------------------------- 1 | # Example routes.rb of resources 2 | resources :posts 3 | 4 | get "landing", to: "posts#index" 5 | 6 | any "*catchall", to: "public_files#show" 7 | -------------------------------------------------------------------------------- /docs/_docs/considerations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Considerations 3 | --- 4 | 5 | The following sections cover some considerations, limits, and benefits. Hopefully they are helpful. 6 | 7 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /lib/jets/controller/error/invalid_authenticity_token.rb: -------------------------------------------------------------------------------- 1 | class Jets::Controller 2 | class Error 3 | class InvalidAuthenticityToken < Error #:nodoc: 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/jobs/temperature_job.rb: -------------------------------------------------------------------------------- 1 | class TemperatureJob < ApplicationJob 2 | thermostat_rule(:room) 3 | def record 4 | # custom business logic 5 | end 6 | end -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "html-proofer" 4 | gem "jekyll" 5 | gem "opal" 6 | gem "opal-browser" 7 | gem "opal-jquery" 8 | gem "rake" 9 | gem "rerun" 10 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /lib/jets/turbo/project/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < Jets::Job::Base 2 | # Adjust to increase the default timeout for all Job classes 3 | class_timeout 60 4 | end 5 | -------------------------------------------------------------------------------- /lib/jets/resource/api_gateway/rest_api/routes.rb: -------------------------------------------------------------------------------- 1 | class Jets::Resource::ApiGateway::RestApi 2 | class Routes 3 | def self.changed? 4 | Change.new.changed? 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /lib/jets/router/resources/base.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Resources 2 | class Base 3 | def initialize(name, options) 4 | @name, @options = name, options 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/fixtures/authorizers/token.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "TOKEN", 3 | "methodArn": "arn:aws:execute-api:us-west-2:112233445566:f0ivxw7nkl/dev/GET/posts", 4 | "authorizationToken": "test" 5 | } -------------------------------------------------------------------------------- /.cody/docs/bin/cli_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # Unsure why but setting BUNDLE_GEMFILE fixes build in the codebuild docker env 4 | export BUNDLE_GEMFILE=$(pwd)/Gemfile 5 | bundle 6 | rake docs 7 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/rails/assets/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* 2 | Place all the styles related to the matching controller here. 3 | They will automatically be included in application.css. 4 | */ 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/admin/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::PagesController < ApplicationController 2 | def index 3 | render json: {"action": "index"} 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/others_controller.rb: -------------------------------------------------------------------------------- 1 | class OthersController < ApplicationController 2 | def catchall 3 | render json: {action: "all", event: event} 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/related_posts_controller.rb: -------------------------------------------------------------------------------- 1 | class RelatedPostsController < ApplicationController 2 | def show 3 | render json: {"action": "show"} 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /.cody/docs/bin/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | .cody/docs/bin/git_setup.sh 4 | .cody/docs/bin/bundler_setup.sh 5 | .cody/docs/bin/cli_docs.sh 6 | .cody/docs/bin/subnav.sh 7 | .cody/docs/bin/git_commit.sh -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < Jets::Job::Base 2 | # Adjust to increase the default timeout for all Job classes 3 | class_timeout 60 4 | end 5 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.gem 3 | .bundle 4 | coverage 5 | pkg 6 | tmp 7 | bundled 8 | .byebug_history 9 | /public/packs 10 | /public/packs-test 11 | /node_modules 12 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/rails/assets/javascript.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /lib/jets/turbo/project/.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | .byebug_history 4 | .DS_Store 5 | .env.* 6 | /node_modules 7 | /public/packs 8 | /public/packs-test 9 | bundled 10 | coverage 11 | pkg 12 | tmp 13 | -------------------------------------------------------------------------------- /lib/jets/turbo/project/config/application.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | config.project_name = "project" 3 | config.mode = "api" 4 | config.controllers.default_protect_from_forgery = false 5 | end 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/toys/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Toy

2 | 3 | <%= render 'form', toy: @toy %> 4 | 5 | <%= link_to 'Show', "/toys/#{@toy.id}/edit" %> | 6 | <%= link_to 'Back', "/toys" %> 7 | -------------------------------------------------------------------------------- /.cody/docs/bin/bundler_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # This Docker image needs bundler 1.16.6 installed 4 | gem install bundler:1.16.6 5 | echo $BUNDLER_VERSION 6 | 7 | # Generate docs 8 | gem update --system 9 | -------------------------------------------------------------------------------- /docs/_docs/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Testing 3 | --- 4 | 5 | Jets uses rspec for its default testing framework. Jets has some light support for spec helpers. Contributions are appreciated for more spec helpers! 6 | 7 | -------------------------------------------------------------------------------- /lib/jets/builders/rackup_wrappers/rackup.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # Copied from: https://github.com/rack/rack/blob/master/bin/rackup 5 | 6 | require "rack" 7 | Rack::Server.start -------------------------------------------------------------------------------- /lib/jets/commands/help/clean/log.md: -------------------------------------------------------------------------------- 1 | Essentially removes the CloudWatch groups assocated with the app. Lambda requests re-create the log groups so this is pretty safe to do. 2 | 3 | ## Example 4 | 5 | jets log:clean -------------------------------------------------------------------------------- /lib/jets/internal/app/helpers/jets/mailers_helper.rb: -------------------------------------------------------------------------------- 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 10 | -------------------------------------------------------------------------------- /lib/jets/poly_fun/node_error.rb: -------------------------------------------------------------------------------- 1 | class Jets::PolyFun 2 | class NodeError < StandardError 3 | def initialize(message, backtrace) 4 | super(message) 5 | set_backtrace(backtrace) 6 | end 7 | end 8 | end -------------------------------------------------------------------------------- /spec/lib/jets/naming_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Naming do 2 | it "provides some names used throughout jets" do 3 | naming = Jets::Naming 4 | expect(naming.parent_stack_name).to eq "demo-test" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | .byebug_history 4 | .DS_Store 5 | .env* 6 | /node_modules 7 | /public/packs 8 | /public/packs-test 9 | bundled 10 | coverage 11 | pkg 12 | tmp 13 | -------------------------------------------------------------------------------- /lib/jets/poly_fun/python_error.rb: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/iam.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module Iam 3 | def iam_role(id, props={}) 4 | resource(id, "AWS::IAM::Role", props) 5 | output(id) # IAM Arn 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/jobs/easy_job.rb: -------------------------------------------------------------------------------- 1 | class EasyJob < ApplicationJob 2 | rate "1 day" 3 | def sleep 4 | seconds = Jets.env.test? ? 0 : 1 5 | sleep seconds 6 | {done: "sleeping"} 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /.cody/docs/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | build: 5 | commands: 6 | - .cody/docs/bin/build.sh 7 | cache: 8 | paths: 9 | - /usr/local/bundle 10 | - /usr/local/lib/ruby/gems/2.5.0 11 | -------------------------------------------------------------------------------- /docs/_includes/rails-update.md: -------------------------------------------------------------------------------- 1 | Update 5/3/2021: Rails experimental support is currently broken. Instead of investing time to fixing this experiment, will consider leveraging container image support which is a better approach. 2 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.env.tt: -------------------------------------------------------------------------------- 1 | # Example .env, meant to be updated. 2 | # Variables in here are available and shared across all environments: development, production, etc. 3 | SECRET_KEY_BASE=<%= SecureRandom.hex(64) %> -------------------------------------------------------------------------------- /readme/prerelease.md: -------------------------------------------------------------------------------- 1 | # Prerelease Checklist 2 | 3 | This is a pre-release checklist for major and minor version bumps. 4 | 5 | * Run Through tests in: [testing.md](testing.md) 6 | * Deploy CRUD app to AWS Lambda and verify it works -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/books_controller.rb: -------------------------------------------------------------------------------- 1 | class BooksController < ApplicationController 2 | python :show 3 | python :error_test 4 | 5 | node :list 6 | node :node_error_test 7 | node :node_async 8 | end -------------------------------------------------------------------------------- /docs/_docs/crud-json-dynamodb.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CRUD JSON DynamoDB 3 | --- 4 | 5 | Existing wiki: [https://github.com/boltops-tools/jets/wiki/CRUD-Curl-Jets-Tutorial](https://github.com/boltops-tools/jets/wiki/CRUD-Curl-Jets-Tutorial) -------------------------------------------------------------------------------- /docs/_reference/jets-dotenv-show.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets dotenv:show 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets dotenv:show 9 | 10 | ## Description 11 | 12 | Shows evaulated dotenv values 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/child_posts_controller.rb: -------------------------------------------------------------------------------- 1 | class ChildPostsController < PostsController 2 | def index 3 | render json: "test" 4 | end 5 | 6 | def foobar 7 | render plain: "foobar" 8 | end 9 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@rails/webpacker": "^3.0.2", 4 | "coffeescript": "1.12.7" 5 | }, 6 | "devDependencies": { 7 | "webpack-dev-server": "^2.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/_reference/jets-gems-sources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets gems:sources 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets gems:sources 9 | 10 | ## Description 11 | 12 | List pre-built Lambda gem sources 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/articles/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing Article

2 | 3 | <%= render 'form', article: @article %> 4 | 5 | <%= link_to 'Show', "/articles/#{@article.id}/edit" %> | 6 | <%= link_to 'Back', "/articles" %> 7 | -------------------------------------------------------------------------------- /lib/jets/commands/help/dbconsole.md: -------------------------------------------------------------------------------- 1 | This is like running the psql command with the `config/database.yml` values and set for you. 2 | 3 | ## Example 4 | 5 | $ jets dbconsole 6 | psql (9.2.24) 7 | Type "help" for help. 8 | 9 | demo_dev=> -------------------------------------------------------------------------------- /lib/jets/commands/help/url.md: -------------------------------------------------------------------------------- 1 | If routes have been configured and an API Gateway was created for the app, this provides the application's url. 2 | 3 | ## Example 4 | 5 | $ jets url 6 | https://v9wa7vqcia.execute-api.us-west-2.amazonaws.com/dev -------------------------------------------------------------------------------- /lib/jets/generator/templates/erb/scaffold/new.html.erb: -------------------------------------------------------------------------------- 1 |

New <%= singular_table_name.titleize %>

2 | 3 | <%%= render 'form', <%= singular_table_name %>: @<%= singular_table_name %> %> 4 | 5 | <%%= link_to 'Back', <%= index_helper %>_path %> 6 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/comments_controller.rb: -------------------------------------------------------------------------------- 1 | class CommentsController < ApplicationController 2 | def hot 3 | post = Post.find("tung") 4 | render json: {action: "hot", ruby: RUBY_VERSION, post: post} 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /docs/_reference/jets-dynamodb-migrate-down.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets dynamodb-migrate:down 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets dynamodb:migrate:down 9 | 10 | ## Description 11 | 12 | Runs migrations down 13 | 14 | 15 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/active_job/job/templates/job.rb.tt: -------------------------------------------------------------------------------- 1 | <% module_namespacing do -%> 2 | class <%= class_name %>Job < ApplicationJob 3 | rate "10 hours" # every 10 hours 4 | def dig 5 | puts "done digging" 6 | end 7 | end 8 | <% end -%> 9 | -------------------------------------------------------------------------------- /lib/jets/router/helpers/named_routes_helper.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Helpers 2 | module NamedRoutesHelper 3 | def self.clear! 4 | meths = public_instance_methods(false) 5 | meths.each { |m| remove_method(m) } 6 | end 7 | end 8 | end -------------------------------------------------------------------------------- /docs/_includes/reference.md: -------------------------------------------------------------------------------- 1 | Jets is a framework that allows you to create serverless applications with a beautiful language: Ruby. It includes everything required to build an application and deploy it to AWS Lambda. Jets makes serverless accessible to everyone. -------------------------------------------------------------------------------- /bin/release: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Wrapper release script so we don't forget to add submodules. 4 | # Should still update the CHANGELOG.md and version.rb before running this script. 5 | 6 | git submodule init 7 | git submodule update 8 | bundle update 9 | rake release -------------------------------------------------------------------------------- /lib/jets/generator/templates/active_job/job/templates/application_job.rb.tt: -------------------------------------------------------------------------------- 1 | <% module_namespacing do -%> 2 | class ApplicationJob < Jets::Job::Base 3 | # Adjust to increase the default timeout for all Job classes 4 | class_timeout 60 5 | end 6 | <% end -%> 7 | -------------------------------------------------------------------------------- /lib/jets/internal/app/views/jets/mailers/mailer.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @preview.preview_name.titleize %>

2 | 7 | -------------------------------------------------------------------------------- /lib/jets/router/method_creator/generic.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router::MethodCreator 2 | class Generic < Code 3 | def meth_name 4 | @options[:as] 5 | end 6 | 7 | def path_method 8 | super if @options[:as] 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/lib/jets/commands/deploy_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Commands::Deploy do 2 | let(:build) do 3 | Jets::Commands::Deploy.new(noop: true) 4 | end 5 | 6 | describe "Deploy" do 7 | it "#controller_paths" do 8 | end 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /lib/jets/cfn/status.rb: -------------------------------------------------------------------------------- 1 | require 'cfn_status' 2 | 3 | module Jets::Cfn 4 | class Status < CfnStatus 5 | def initialize(options={}) 6 | @stack_name = Jets::Naming.parent_stack_name 7 | super(@stack_name, options) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/.env.development.tt: -------------------------------------------------------------------------------- 1 | # Example .env.development, meant to be updated. 2 | ENV_DEVELOPMENT_KEY=example1 3 | # DATABASE_URL=<%= @database == 'mysql' ? 'mysql2' : 'postgres' %>://dbuser:dbpass@dbhost/<%= @project_name %>_development?pool=5 -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/bin/dev/server: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # export DYNAMODB_ENDPOINT=http://localhost:8000 4 | 5 | # Hacky wrapper so we dont forget to switch to local gems for quick development 6 | touch dev.mode 7 | bundle update 8 | exec bundle exec jets server 9 | -------------------------------------------------------------------------------- /docs/_reference/jets-secret.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets secret 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets secret 9 | 10 | ## Description 11 | 12 | Generates secret 13 | 14 | ## Options 15 | 16 | ``` 17 | [--noop], [--no-noop] 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /docs/_reference/jets-version.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets version 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets version 9 | 10 | ## Description 11 | 12 | Prints Jets version 13 | 14 | ## Options 15 | 16 | ``` 17 | [--noop], [--no-noop] 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /lib/jets/commands/dotenv.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands 2 | class Dotenv < Jets::Commands::Base 3 | desc "show", "Shows evaulated dotenv values" 4 | long_desc Help.text('dotenv:show') 5 | def show 6 | Jets::Dotenv::Show.list 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/resource/api_gateway/rest_api/change_detection.rb: -------------------------------------------------------------------------------- 1 | class Jets::Resource::ApiGateway::RestApi 2 | class ChangeDetection 3 | extend Memoist 4 | include Jets::AwsServices 5 | 6 | def changed? 7 | Routes.changed? 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/jets/controller/middleware/webpacker_setup.rb: -------------------------------------------------------------------------------- 1 | # Breaking all the rules to get the beautiful webpacker middleware working 2 | 3 | require "webpacker" 4 | require "webpacker/dev_server_proxy" 5 | 6 | Webpacker.bootstrap # whenever jets server is runs should Webpacker.bootstrap 7 | -------------------------------------------------------------------------------- /lib/jets/dotenv/show.rb: -------------------------------------------------------------------------------- 1 | class Jets::Dotenv 2 | class Show 3 | def self.list 4 | puts "# Env from evaluated dotenv files" 5 | vars = Jets::Dotenv.load! 6 | vars.each do |k,v| 7 | puts "#{k}=#{v}" 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 1536 4 | 5 | # config.action_mailer.raise_delivery_errors = false 6 | # Docs: http://rubyonjets.com/docs/email-sending/ 7 | end 8 | -------------------------------------------------------------------------------- /lib/jets/router/method_creator/root.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router::MethodCreator 2 | class Root < Code 3 | def meth_name 4 | "root" 5 | end 6 | 7 | def meth_args 8 | nil 9 | end 10 | 11 | def meth_result 12 | nil 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/fixtures/multipart/nested: -------------------------------------------------------------------------------- 1 | --AaB03x 2 | Content-Disposition: form-data; name="foo[submit-name]" 3 | 4 | Larry 5 | --AaB03x 6 | Content-Disposition: form-data; name="foo[files]"; filename="file1.txt" 7 | Content-Type: text/plain 8 | 9 | contents 10 | --AaB03x-- 11 | -------------------------------------------------------------------------------- /docs/_reference/jets-middleware.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets middleware 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets middleware 9 | 10 | ## Description 11 | 12 | Prints list of middleware 13 | 14 | ## Options 15 | 16 | ``` 17 | [--noop], [--no-noop] 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /lib/jets/commands/help/upgrade.md: -------------------------------------------------------------------------------- 1 | Upgrades the Jets project structure to the latest version. This command is designed to be idempotent, so it should be safe to run this command multiple times. 2 | 3 | ## Example 4 | 5 | $ jets upgrade 6 | 7 | Refer to https://rubyonjets.com/docs/extras/upgrading/ -------------------------------------------------------------------------------- /lib/jets/resource/api_gateway/rest_api/routes/collision/variable_exception.rb: -------------------------------------------------------------------------------- 1 | class Jets::Resource::ApiGateway::RestApi::Routes::Collision 2 | class VariableException < RuntimeError 3 | def initialize(message="Route variable collisions") 4 | super(message) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/admin/related_pages_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::RelatedPagesController < ApplicationController 2 | def index 3 | render json: {"action": "index"} 4 | end 5 | 6 | def list_all 7 | render json: {"action": "list_all"} 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/db/migrate/20171114235317_create_articles.rb: -------------------------------------------------------------------------------- 1 | class CreateArticles < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :articles do |t| 4 | t.string :title 5 | t.text :body 6 | t.boolean :published 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/spec_helpers/fixtures.rb: -------------------------------------------------------------------------------- 1 | module Jets::SpecHelpers 2 | module Fixtures 3 | def fixture_path(filename) 4 | "#{Jets.root}/spec/fixtures/#{filename}" 5 | end 6 | 7 | def fixture_file(filename) 8 | File.new(fixture_path(filename)) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/lib/jets/internal/preheat_job_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::PreheatJob do 2 | let(:job) do 3 | Jets::PreheatJob.new({},{},nil) 4 | end 5 | 6 | context "warm" do 7 | it "calls all lambda functions with a prewarm request" do 8 | job.warm 9 | end 10 | end 11 | end 12 | 13 | -------------------------------------------------------------------------------- /lib/jets/core_ext/bundler.rb: -------------------------------------------------------------------------------- 1 | # Bundler 2.0 does yet not have with_unbundled_env 2 | # Bundler 2.1 deprecates with_unbundled_env for with_unbundled_env 3 | 4 | require "bundler" 5 | def Bundler.with_unbundled_env(&block) 6 | with_clean_env(&block) 7 | end unless Bundler.respond_to?(:with_unbundled_env) 8 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/erb/scaffold/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing <%= singular_table_name.titleize %>

2 | 3 | <%%= render 'form', <%= singular_table_name %>: @<%= singular_table_name %> %> 4 | 5 | <%%= link_to 'Show', @<%= singular_table_name %> %> | 6 | <%%= link_to 'Back', <%= index_helper %>_path %> 7 | -------------------------------------------------------------------------------- /lib/jets/cfn/builders/job_builder.rb: -------------------------------------------------------------------------------- 1 | # Implements: 2 | # 3 | # compose 4 | # template_path 5 | # 6 | module Jets::Cfn::Builders 7 | class JobBuilder < BaseChildBuilder 8 | def compose 9 | add_common_parameters 10 | add_functions 11 | add_resources 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jets/commands/help.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands::Help 2 | class << self 3 | def text(namespaced_command) 4 | path = namespaced_command.to_s.gsub(':','/') 5 | path = File.expand_path("../help/#{path}.md", __FILE__) 6 | IO.read(path) if File.exist?(path) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/internal/app/controllers/jets/rack_controller.rb: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/db/migrate/20171127132819_create_toys.rb: -------------------------------------------------------------------------------- 1 | class CreateToys < ActiveRecord::Migration[5.1] 2 | def change 3 | create_table :toys do |t| 4 | t.string :title 5 | t.text :body 6 | t.boolean :published 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /exe/jets: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # traps: INT - ^C 4 | ['INT', 'TERM', 'QUIT'].each do |signal| 5 | trap(signal) do 6 | puts "Detected stop signal" 7 | sleep 0.2 8 | exit 9 | end 10 | end 11 | 12 | $:.unshift(File.expand_path("../../lib", __FILE__)) 13 | require "jets" 14 | Jets::CLI.start 15 | -------------------------------------------------------------------------------- /spec/lib/jets/namespace_spec.rb: -------------------------------------------------------------------------------- 1 | describe "Namespace" do 2 | it "autovivification" do 3 | Dir.chdir("spec/fixtures/apps/franky") do 4 | # Sanity check: should not raise an error 5 | # If it raises an error then module autovivification is not working 6 | Ns::A 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/overrides/rails.rb: -------------------------------------------------------------------------------- 1 | require "jets/overrides/rails/common_methods" 2 | require "jets/overrides/rails/url_helper" 3 | require "jets/overrides/rails/rendering_helper" 4 | require "jets/overrides/rails/asset_tag_helper" 5 | require "jets/overrides/rails/action_controller" 6 | require "jets/overrides/rails/migration_checker" 7 | -------------------------------------------------------------------------------- /spec/lib/jets/middleware/layer_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Middleware::Layer do 2 | context "layer" do 3 | it "build" do 4 | layer = Jets::Middleware::Layer.new(Rack::Runtime, {}, nil) 5 | middleware = layer.build(Proc.new {}) 6 | expect(middleware).to be_a(Rack::Runtime) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /docs/_docs/extras/rake-tasks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rake Tasks 3 | --- 4 | 5 | You can add custom rake tasks in the `lib/tasks` folder in your project. There's a `jets generate task` command to help you get started. 6 | 7 | $ jets generate task feeds fetch erase add 8 | create lib/tasks/feeds.rake 9 | $ 10 | 11 | -------------------------------------------------------------------------------- /lib/jets/commands/markdown/shell.rb: -------------------------------------------------------------------------------- 1 | require 'thor' 2 | 3 | module Jets::Commands::Markdown 4 | # Override stdout as an @io object so we can grab the text written normally 5 | # outputted to the shell. 6 | class Shell < Thor::Shell::Basic 7 | def stdout 8 | @io ||= StringIO.new 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/jets/spec_helpers/controllers/response.rb: -------------------------------------------------------------------------------- 1 | module Jets::SpecHelpers::Controllers 2 | class Response 3 | attr_reader :status, :headers, :body 4 | def initialize(response) 5 | @status = response['statusCode'].to_i 6 | @headers = response['headers'] 7 | @body = response['body'] 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/Procfile: -------------------------------------------------------------------------------- 1 | local: dynamodb-local # port 8000 2 | admin: env AWS_ACCESS_KEY_ID=$DYNAMODB_ADMIN_AWS_ACCESS_KEY_ID PORT=8001 dynamodb-admin # port 8001 3 | 4 | # web: jets server # port 8888 5 | 6 | # Using Procfile to just start local dynamodb services for now. 7 | # To start jets server for now use: 8 | # bin/dev/server 9 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/Procfile: -------------------------------------------------------------------------------- 1 | local: dynamodb-local # port 8000 2 | admin: env AWS_ACCESS_KEY_ID=$DYNAMODB_ADMIN_AWS_ACCESS_KEY_ID PORT=8001 dynamodb-admin # port 8001 3 | # web: jets server # port 8888 4 | 5 | # Using Procfile to just start local dynamodb services for now. 6 | # To start jets server for now use: 7 | # jets server 8 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/README.md: -------------------------------------------------------------------------------- 1 | # Jets Project 2 | 3 | This README would normally document whatever steps are necessary to get the application up and running. 4 | 5 | Things you might want to cover: 6 | 7 | * Dependencies 8 | * Configuration 9 | * Database setup 10 | * How to run the test suite 11 | * Deployment instructions 12 | -------------------------------------------------------------------------------- /lib/jets/overrides/rails/action_controller.rb: -------------------------------------------------------------------------------- 1 | ActiveSupport.on_load :action_controller do 2 | class ActionController::Base 3 | class << self 4 | @@_prefixes = nil 5 | def _prefixes 6 | @@_prefixes 7 | end 8 | def _prefixes=(v) 9 | @@_prefixes = v 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/commands/clean/build.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | class Jets::Commands::Clean 4 | class Build < Base 5 | def clean 6 | are_you_sure?("delete /tmp/jets") 7 | 8 | say "Removing /tmp/jets..." 9 | FileUtils.rm_rf("/tmp/jets") unless @options[:noop] 10 | say "Removed /tmp/jets" 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/spec_helpers/controllers/params.rb: -------------------------------------------------------------------------------- 1 | module Jets::SpecHelpers::Controllers 2 | class Params 3 | attr_accessor :path_params, :body_params, :query_params 4 | def initialize(path_params={}, body_params={}, query_params={}) 5 | @path_params, @body_params, @query_params = path_params, body_params, query_params 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/README.md: -------------------------------------------------------------------------------- 1 | # Franky Jets Project 2 | 3 | Franky is short for Frankenstein. This is a Frankenstein project that is not meant to be deployable but meant to help with specs. This project contains a lot of different usages of resources, properties, and settings. This provides a quick way to add sanity checks with the Jets DSL. 4 | 5 | -------------------------------------------------------------------------------- /.cody/README.md: -------------------------------------------------------------------------------- 1 | ## Update Project 2 | 3 | To update the CodeBuild project: 4 | 5 | Main services: 6 | 7 | AWS_PROFILE=bolt-oss cody deploy jets --type docs # mainly cli docs and subnav update 8 | 9 | ## Start a Deploy 10 | 11 | To start a CodeBuild build which kicks off a deploy: 12 | 13 | AWS_PROFILE=bolt-oss cody start jets --type docs 14 | -------------------------------------------------------------------------------- /lib/jets/internal/app/views/jets/mailers/index.html.erb: -------------------------------------------------------------------------------- 1 | <% @previews.each do |preview| %> 2 |

<%= link_to(preview.preview_name.titleize, "/jets/mailers/#{preview.preview_name}") %>

3 | 8 | <% end %> 9 | -------------------------------------------------------------------------------- /lib/jets/cfn/builders/function_builder.rb: -------------------------------------------------------------------------------- 1 | # Implements: 2 | # 3 | # compose 4 | # template_path 5 | # 6 | module Jets::Cfn::Builders 7 | class FunctionBuilder < BaseChildBuilder 8 | # compose is an interface method for Interface module 9 | def compose 10 | add_common_parameters 11 | add_functions 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jets/commands/help/gems/check.md: -------------------------------------------------------------------------------- 1 | Check if pre-built Lambda gems are available from the gems source. You can configure the gem in config/application.rb: 2 | 3 | # Sources for check for pre-compiled Lambda gems. Checks the list in order. 4 | Jets.application.configure do 5 | config.gems.source = "https://api.serverlessgems.com/api/v1" 6 | end 7 | -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/s3.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module S3 3 | def s3_bucket(id, props={}) 4 | resource(id, "AWS::S3::Bucket", props) 5 | output(id) # Bucket name 6 | end 7 | 8 | def s3_bucket_configuration(id, props={}) 9 | resource(id, "Custom::S3BucketConfiguration", props) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jets/commands/dynamodb/migrate.rb: -------------------------------------------------------------------------------- 1 | class Jets::Commands::Dynamodb::Migrate < Jets::Commands::Base 2 | desc "down", "Runs migrations down" 3 | # desc "migrate:down [path]", "Runs migrations down" 4 | # long_desc Help.migrate 5 | def down#(path) 6 | # Migrate.new(path, options).run 7 | puts "Jets::Commands::Dynamodb::Down ran" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/job/helpers/kinesis_event_helper.rb: -------------------------------------------------------------------------------- 1 | require 'base64' 2 | 3 | module Jets::Job::Helpers 4 | module KinesisEventHelper 5 | def kinesis_data 6 | records = event["Records"] 7 | records.map do |record| 8 | encoded = record["kinesis"]["data"] 9 | Base64.decode64(encoded) # data 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /docs/_docs/repl-console.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: REPL Console 3 | --- 4 | 5 | You can test things out in a REPL console: 6 | 7 | $ jets console 8 | >> Post.table_name 9 | => "posts" 10 | >> ActiveRecord::Base.connection.tables 11 | => ["schema_migrations", "ar_internal_metadata", "posts"] 12 | >> Jets.env 13 | => "development" 14 | >> 15 | 16 | -------------------------------------------------------------------------------- /docs/_reference/jets-dynamodb-migrate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets dynamodb:migrate 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets dynamodb:migrate [path] 9 | 10 | ## Description 11 | 12 | Runs migrations. 13 | 14 | ## Examples 15 | 16 | jets dynamodb:migrate path/to/migration 17 | jets dynamodb:migrate db/migrate/posts_migration.rb 18 | 19 | 20 | -------------------------------------------------------------------------------- /lib/jets/commands/console.rb: -------------------------------------------------------------------------------- 1 | class Jets::Commands::Console 2 | def self.run 3 | puts Jets::Booter.message 4 | 5 | # Thanks: https://mutelight.org/bin-console 6 | require "irb" 7 | require "irb/completion" 8 | 9 | ARGV.clear # https://stackoverflow.com/questions/33070092/irb-start-not-starting/33136762 10 | IRB.start 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /.cody/docs/project.rb: -------------------------------------------------------------------------------- 1 | github_url("https://github.com/tongueroo/jets.git") 2 | linux_image("aws/codebuild/ruby:2.5.3-1.7.0") 3 | triggers( 4 | webhook: true, 5 | filter_groups: [[{type: "HEAD_REF", pattern: "master"}, {type: "EVENT", pattern: "PUSH"}]] 6 | ) 7 | environment_variables( 8 | SSH_KEY_S3_PATH: "ssm:/codebuild/jets/ssh_key_s3_path" 9 | ) 10 | local_cache(true) -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/kinesis.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module Kinesis 3 | def kinesis_stream(id, props={}) 4 | defaults = { 5 | name: id, 6 | shard_count: 1 7 | } 8 | 9 | props = defaults.merge(props) 10 | 11 | resource(id, "AWS::Kinesis::Stream", props) 12 | output(id) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/jets/commands/help/runner.md: -------------------------------------------------------------------------------- 1 | ## Examples 2 | 3 | $ jets runner 'puts "hi"' 4 | hi 5 | $ jets runner 'puts Jets.env' 6 | development 7 | 8 | Using a script in a file. Let's say you have a script: 9 | 10 | script.rb: 11 | 12 | ```ruby 13 | puts "hello world: #{Jets.env}" 14 | ``` 15 | 16 | $ jets runner file://script.rb 17 | hello world: development -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Tell Action Mailer not to deliver emails to the real world. 3 | # The :test delivery method accumulates sent emails in the 4 | # ActionMailer::Base.deliveries array. 5 | # Docs: http://rubyonjets.com/docs/email-sending/ 6 | config.action_mailer.delivery_method = :test 7 | end 8 | -------------------------------------------------------------------------------- /lib/jets/controller/middleware/reloader.rb: -------------------------------------------------------------------------------- 1 | module Jets::Controller::Middleware 2 | class Reloader 3 | def initialize(app) 4 | @app = app 5 | end 6 | 7 | @@reload_lock = Mutex.new 8 | def call(env) 9 | @@reload_lock.synchronize do 10 | Jets::Autoloaders.main.reload 11 | @app.call(env) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/jets/commands/help/build.md: -------------------------------------------------------------------------------- 1 | Builds a zip file package to be uploaded to AWS Lambda. This allows you to build the project without deploying and inspect the zip file that gets deployed to AWS Lambda. The package contains: 2 | 3 | * your application code 4 | * generated shims 5 | 6 | If the application has no Ruby code and only uses Polymorphic functions, then gems are not bundled up. 7 | -------------------------------------------------------------------------------- /lib/jets/commands/help/clean/build.md: -------------------------------------------------------------------------------- 1 | Removes the build files that jets creates. Essentially, deletes `/tmp/jets`. This will remove all build files for all jets projects. This is safe as jets uses `/tmp/jets` merely as a cache to speed up incrementally builds. Cleaning this out can clean up cruft in the `/tmp/jets` directory that builds over time. 2 | 3 | ## Example 4 | 5 | jets clean:build -------------------------------------------------------------------------------- /lib/jets/job/helpers/s3_event_helper.rb: -------------------------------------------------------------------------------- 1 | module Jets::Job::Helpers 2 | module S3EventHelper 3 | def s3_event 4 | message = event["Records"][0]["Sns"]["Message"] 5 | h = JSON.load(message) 6 | ActiveSupport::HashWithIndifferentAccess.new(h) 7 | end 8 | 9 | def s3_object 10 | s3_event["Records"][0]["s3"]["object"] 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl.rb: -------------------------------------------------------------------------------- 1 | class Jets::Stack 2 | class Main 3 | module Dsl 4 | extend ActiveSupport::Concern 5 | 6 | class_methods do 7 | include Base 8 | include Cloudwatch 9 | include Iam 10 | include Lambda 11 | include S3 12 | include Sns 13 | include Sqs 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/toys/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Title: 3 | <%= @toy.title %> 4 |

5 | 6 |

7 | Body: 8 | <%= @toy.body %> 9 |

10 | 11 |

12 | Published: 13 | <%= @toy.published %> 14 |

15 | 16 | <%= link_to 'Edit', "/toys/#{@toy.id}/edit" %> | 17 | <%= link_to 'Back', "/toys" %> 18 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/functions/hello.rb: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | # puts "loading function" 4 | 5 | def world(event, context) 6 | # puts "value1 = #{event['key1']}" 7 | # puts "value2 = #{event['key2']}" 8 | # puts "value3 = #{event['key3']}" 9 | 10 | "hello world: #{event['key1'].inspect}" # Echo back the first key value 11 | # raise "Something went wrong" 12 | end 13 | -------------------------------------------------------------------------------- /docs/_docs/database-support.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Database Support 3 | --- 4 | 5 | Jets supports DynamoDB and ActiveRecord. Both DynamoDB and ActiveRecord can coexist in the same application. 6 | 7 | * [DynamoDB]({% link _docs/database/dynamodb.md %}) 8 | * [ActiveRecord]({% link _docs/database/activerecord.md %}) 9 | 10 | For ActiveRecord, currently MySQL and PostgreSQL is supported. 11 | 12 | -------------------------------------------------------------------------------- /lib/jets/builders/templates/handler.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "jets" 3 | Jets.once # runs once in lambda execution context 4 | 5 | <% @vars.functions.each do |function_name| 6 | handler = @vars.handler_for(function_name) 7 | meth = handler.split('.').last 8 | -%> 9 | def <%= meth -%>(event:, context:) 10 | Jets.process(event, context, "<%= handler -%>") 11 | end 12 | <% end %> -------------------------------------------------------------------------------- /lib/jets/job/dsl/event_source_mapping.rb: -------------------------------------------------------------------------------- 1 | # SqsEvent uses this module 2 | module Jets::Job::Dsl 3 | module EventSourceMapping 4 | def event_source_mapping(props={}) 5 | r = Jets::Resource::Lambda::EventSourceMapping.new(props) 6 | with_fresh_properties do 7 | resource(r.definition) # add associated resource immediately 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .byebug_history 5 | .config 6 | .yardoc 7 | _yardoc 8 | coverage 9 | doc/ 10 | InstalledFiles 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | 19 | .codebuild/definitions 20 | /html 21 | /demo 22 | Gemfile.lock 23 | spec/fixtures/apps/franky/dynamodb/migrate 24 | spec/fixtures/project/handlers 25 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/functions/simple_function.rb: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | # puts "loading function" 4 | 5 | def handler(event, context) 6 | # puts "value1 = #{event['key1']}" 7 | # puts "value2 = #{event['key2']}" 8 | # puts "value3 = #{event['key3']}" 9 | "simple handler: #{event['key1'].inspect}" # Echo back the first key value 10 | # raise "Something went wrong" 11 | end 12 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/functions/whatever.rb: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | # puts "loading function" 4 | 5 | def handle(event, context) 6 | # puts "value1 = #{event['key1']}" 7 | # puts "value2 = #{event['key2']}" 8 | # puts "value3 = #{event['key3']}" 9 | 10 | "hello world: #{event['key1'].inspect}" # Echo back the first key value 11 | # raise "Something went wrong" 12 | end 13 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/public_files_controller.rb: -------------------------------------------------------------------------------- 1 | class PublicFilesController < ApplicationController 2 | def show 3 | path = Jets.root + "public" + params[:catchall] 4 | if path.exist? 5 | # TODO: only works for text files. Add support for binary data like images 6 | render file: path 7 | else 8 | render status: 404 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /.cody/docs/bin/git_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # git push: 4 | # CODEBUILD_WEBHOOK_HEAD_REF=refs/heads/codebuild 5 | # CODEBUILD_WEBHOOK_TRIGGER=branch/codebuild 6 | # CODEBUILD_SOURCE_VERSION=f0eb542 # resolved sha 7 | # cb start: 8 | # CODEBUILD_SOURCE_VERSION=codebuild 9 | 10 | git config --global user.email "tongueroo@gmail.com" 11 | git config --global user.name "Tung Nguyen" 12 | 13 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/views/articles/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Title: 3 | <%= @article.title %> 4 |

5 | 6 |

7 | Body: 8 | <%= @article.body %> 9 |

10 | 11 |

12 | Published: 13 | <%= @article.published %> 14 |

15 | 16 | <%= link_to 'Edit', "/articles/#{@article.id}/edit" %> | 17 | <%= link_to 'Back', "/articles" %> 18 | -------------------------------------------------------------------------------- /docs/opal/app.rb: -------------------------------------------------------------------------------- 1 | # client-side require. Note: the server-side requires are in the Rakefile 2 | require "opal" 3 | require "opal-jquery" 4 | require "browser" 5 | require "browser/location" 6 | require "native" 7 | require "sidebar" 8 | require "pager" 9 | 10 | # use bin/rerun to continuously generate js/app.js from this file 11 | 12 | Document.ready? do 13 | Sidebar.setup 14 | Pager.setup 15 | end 16 | 17 | -------------------------------------------------------------------------------- /lib/jets/resource/child_stack/common_parameters.rb: -------------------------------------------------------------------------------- 1 | module Jets::Resource::ChildStack 2 | module CommonParameters 3 | def common_parameters 4 | parameters = { 5 | IamRole: "!GetAtt IamRole.Arn", 6 | S3Bucket: "!Ref S3Bucket", 7 | } 8 | parameters[:GemLayer] = "!Ref GemLayer" unless Jets.poly_only? 9 | parameters 10 | end 11 | 12 | extend self 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": "> 1%", 7 | "uglify": true 8 | }, 9 | "useBuiltIns": true 10 | }] 11 | ], 12 | 13 | "plugins": [ 14 | "syntax-dynamic-import", 15 | "transform-object-rest-spread", 16 | ["transform-class-properties", { "spec": true }] 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/spec/jets_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | require 'spec_helper' 3 | ENV['JETS_ENV'] ||= 'test' 4 | 5 | abort("The Jets environment is running in production mode!") if Jets::Config.env == "production" 6 | 7 | # Check for pending migrations 8 | # TODO: Jets::Migration.maintain_test_schema! 9 | 10 | RSpec.configure do |config| 11 | end 12 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/erb/scaffold/show.html.erb: -------------------------------------------------------------------------------- 1 | <% attributes.reject(&:password_digest?).each do |attribute| -%> 2 |

3 | <%= attribute.human_name %>: 4 | <%%= @<%= singular_table_name %>.<%= attribute.column_name %> %> 5 |

6 | 7 | <% end -%> 8 | <%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> | 9 | <%%= link_to 'Back', <%= index_helper %>_path %> 10 | -------------------------------------------------------------------------------- /lib/jets/generator/templates/rails/controller/controller.rb: -------------------------------------------------------------------------------- 1 | <% if namespaced? -%> 2 | require_dependency "<%= namespaced_path %>/application_controller" 3 | 4 | <% end -%> 5 | <% module_namespacing do -%> 6 | class <%= class_name %>Controller < ApplicationController 7 | <% actions.each do |action| -%> 8 | def <%= action %> 9 | end 10 | <%= "\n" unless action == actions.last -%> 11 | <% end -%> 12 | end 13 | <% end -%> 14 | -------------------------------------------------------------------------------- /lib/jets/router/method_creator/show.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router::MethodCreator 2 | class Show < Code 3 | def meth_name 4 | path_items = @path.to_s.split('/') 5 | if method_name_leaf && path_items.size != 2 6 | nil # fallback: do not define url method 7 | else # comes from resources 8 | join(singularize(full_as), singularize(method_name_leaf)) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jets/router/method_creator/edit.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router::MethodCreator 2 | class Edit < Code 3 | def meth_name 4 | path_items = @path.to_s.split('/') 5 | if method_name_leaf && path_items.size != 3 6 | nil # fallback: do not define url method 7 | else # comes from resources 8 | join(action, singularize(full_as), singularize(method_name_leaf)) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jets/router/method_creator/new.rb: -------------------------------------------------------------------------------- 1 | class Jets::Router::MethodCreator 2 | class New < Code 3 | def meth_name 4 | path_items = @path.to_s.split('/') 5 | if method_name_leaf && path_items.size != 2 6 | nil # fallback: do not define url method 7 | else # comes from resources 8 | join(action, singularize(full_as), singularize(method_name_leaf)) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM tongueroo/jets:base 2 | MAINTAINER Tung Nguyen 3 | 4 | # Install bundle of gems first in a layer 5 | # so if the Gemfile doesnt chagne it wont have to install gems again 6 | WORKDIR /tmp 7 | COPY Gemfile* /tmp/ 8 | RUN bundle install && rm -rf /root/.bundle/cache 9 | 10 | # Add the Rails app 11 | ENV HOME /root 12 | WORKDIR /app 13 | COPY . /app 14 | RUN bundle install 15 | 16 | CMD ["uptime"] 17 | -------------------------------------------------------------------------------- /lib/jets/cfn/built_template.rb: -------------------------------------------------------------------------------- 1 | module Jets::Cfn 2 | # Caches the built template to reduce filesystem IO calls. 3 | class BuiltTemplate 4 | class << self 5 | @@cache = {} 6 | def get(path) 7 | if @@cache[path] 8 | @@cache[path] # using cache 9 | else 10 | @@cache[path] = YAML.load_file(path) # setting and using cache 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/jets/commands/help/db/generate.md: -------------------------------------------------------------------------------- 1 | Generates migration in `db/migrate` 2 | 3 | ## Examples 4 | 5 | jets db:generate create_articles title:string user_id:integer 6 | jets db:generate AddTitleBodyToPost title:string body:text published:boolean 7 | 8 | This task delegates to Rails `rails generate migration`. For more examples, refer to the [Active Record Migrations Rails Guide](https://edgeguides.rubyonrails.org/active_record_migrations.html). -------------------------------------------------------------------------------- /lib/jets/overrides/rails/common_methods.rb: -------------------------------------------------------------------------------- 1 | module Jets::CommonMethods 2 | extend Memoist 3 | # Add API Gateway Stage Name 4 | def add_stage_name(url) 5 | Jets::Controller::Stage.add(request.host, url) 6 | end 7 | 8 | def on_aws? 9 | on_cloud9 = Jets::Controller::Stage.on_cloud9?(request.headers['HTTP_HOST']) 10 | !request.headers['HTTP_X_AMZN_TRACE_ID'].nil? && !on_cloud9 11 | end 12 | memoize :on_aws? 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/poly_fun/lambda_executor.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | class Jets::PolyFun 4 | class LambdaExecutor 5 | def initialize(task) 6 | @task = task 7 | end 8 | 9 | def run(event, context) 10 | executor_class = "Jets::PolyFun::#{@task.lang.capitalize}Executor".constantize 11 | executor = executor_class.new(@task) 12 | text = executor.run(event, context) 13 | JSON.load(text) 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Specify your gem dependencies in jets.gemspec 4 | gemspec 5 | 6 | # required here for specs 7 | # TODO: Only require webpacker in Gemfile of project if possible. 8 | # Need both because of jets/application.rb and jets/webpacker/middleware_setup.rb 9 | group :development, :test do 10 | gem "mysql2", "~> 0.5.2" 11 | gem "dynomite" 12 | gem "jetpacker" 13 | gem "rspec_junit_formatter" 14 | end 15 | -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/sns.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module Sns 3 | def sns_topic(id, props={}) 4 | resource(id, "AWS::SNS::Topic", props) 5 | output(id) # Topic Arn 6 | end 7 | 8 | def sns_topic_policy(id, props={}) 9 | resource(id, "AWS::SNS::TopicPolicy", props) 10 | end 11 | 12 | def sns_subscription(id, props={}) 13 | resource(id, "AWS::SNS::Subscription", props) 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /spec/fixtures/multipart/text: -------------------------------------------------------------------------------- 1 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 2 | Content-Disposition: form-data; name="name" 3 | 4 | Tung 5 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 6 | Content-Disposition: form-data; name="title" 7 | 8 | Mr 9 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 10 | Content-Disposition: form-data; name="files"; filename="file1.txt" 11 | Content-Type: application/octet-stream 12 | 13 | 14 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ-- 15 | -------------------------------------------------------------------------------- /spec/fixtures/resource_pages/demo-test-api-resources-3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Resources: 3 | Hi4ApiResource: 4 | Type: AWS::ApiGateway::Resource 5 | Properties: 6 | ParentId: !Ref HiApiResource 7 | PathPart: '4' 8 | RestApiId: !Ref RestApi 9 | Parameters: 10 | RestApi: 11 | Type: String 12 | Description: RestApi 13 | HiApiResource: 14 | Type: String 15 | Outputs: 16 | Hi4ApiResource: 17 | Value: !Ref Hi4ApiResource 18 | -------------------------------------------------------------------------------- /docs/_data/video_playlists.yml: -------------------------------------------------------------------------------- 1 | - url: https://www.youtube.com/watch?v=4YJstp31tkY&list=PL5Aj-dsQ8n0MrXQiJcDzZD1BjnnvGpJcb 2 | title: "Jets AWS Introductory Series Playlist" 3 | 4 | - url: https://www.youtube.com/watch?v=17Y3AJl9dw4&list=PL5Aj-dsQ8n0PuKU3mKHQSX9ckVwYq9DLl 5 | title: "Jets Ruby Serverless Framework Playlist" 6 | 7 | - url: https://www.youtube.com/watch?v=peNzpJ3HrH4&list=PL5Aj-dsQ8n0OSD4J0s0LzgReWuCpVc2wA 8 | title: "Jets Events Series Playlist" 9 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /lib/jets/commands/db/tasks/dummy/config.rb: -------------------------------------------------------------------------------- 1 | require "recursive-open-struct" 2 | 3 | module Jets::Commands::Db::Tasks::Dummy 4 | class Config < RecursiveOpenStruct 5 | def load_database_yaml # :nodoc: 6 | require "rails/application/dummy_erb_compiler" 7 | 8 | path = "#{Jets.root}/config/database.yml" 9 | yaml = Pathname.new(path) 10 | erb = DummyERB.new(yaml.read) 11 | YAML.load(erb.result) || {} 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /lib/jets/controller/layout.rb: -------------------------------------------------------------------------------- 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 18 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /lib/jets/commands/runner.rb: -------------------------------------------------------------------------------- 1 | class Jets::Commands::Runner 2 | def self.run(code) 3 | if code =~ %r{^file://} 4 | path = code.sub('file://', '') 5 | full_path = "#{Jets.root}/#{path}" 6 | if File.exist?(full_path) 7 | code = IO.read(full_path) 8 | else 9 | puts "ERROR: file not found at #{full_path}".color(:red) 10 | exit 1 11 | end 12 | end 13 | 14 | eval(code) # inline script 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Jets.application.configure do 2 | # Example: 3 | # config.function.memory_size = 2048 4 | 5 | # Ignore bad email addresses and do not raise email delivery errors. 6 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 7 | # Docs: http://rubyonjets.com/docs/email-sending/ 8 | # config.action_mailer.raise_delivery_errors = false 9 | end 10 | -------------------------------------------------------------------------------- /spec/fixtures/multipart/simple_form: -------------------------------------------------------------------------------- 1 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 2 | Content-Disposition: form-data; name="name" 3 | 4 | Tung 5 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 6 | Content-Disposition: form-data; name="title" 7 | 8 | Mr 9 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ 10 | Content-Disposition: form-data; name="avatar"; filename="" 11 | Content-Type: application/octet-stream 12 | 13 | 14 | ------WebKitFormBoundaryVCeZcQHJQlRuehAZ-- 15 | -------------------------------------------------------------------------------- /spec/lib/jets/poly_fun/node_executor_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::PolyFun::NodeExecutor do 2 | let(:fun) { Jets::PolyFun::NodeExecutor.new(task) } 3 | let(:task) { BooksController.all_public_tasks[:list] } 4 | 5 | context("python") do 6 | context("lets see the script") do 7 | let(:action) { :node } 8 | it "generates code" do 9 | code = fun.code 10 | expect(code).to include("var app = require") 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jets/router/dsl/mount.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Dsl 2 | module Mount 3 | # The mounted class must be a Rack compatiable class 4 | def mount(klass, at:) 5 | options = {to: "jets/mount#call", mount_class: klass} 6 | at = at[1..-1] if at.starts_with?('/') # be more forgiving if / accidentally included 7 | at_wildcard = at.blank? ? "*path" : "#{at}/*path" 8 | 9 | any at, options 10 | any at_wildcard, options 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/commands/help/import/rails.md: -------------------------------------------------------------------------------- 1 | Imports a Rails application into a Jets project and configures it for [Mega Mode](http://rubyonjets.com/docs/rails-support/). 2 | 3 | ## Example 4 | 5 | jets import:rails http://github.com/tongueroo/demo-rails.git 6 | 7 | ## More Examples 8 | 9 | jets import:rails tongueroo/demo-rails # expands to github 10 | jets import:rails git@github.com:tongueroo/demo-rails.git 11 | jets import:rails /path/to/folder/jets-examples-rails 12 | -------------------------------------------------------------------------------- /lib/jets/resource/config/managed_rule.rb: -------------------------------------------------------------------------------- 1 | # ManagedRule is just different enough to be a separate class vs being part of the 2 | # ConfigRule class itself. 3 | module Jets::Resource::Config 4 | class ManagedRule < ConfigRule 5 | def definition_properties 6 | { 7 | config_rule_name: config_rule_name, 8 | source: { 9 | owner: "AWS", 10 | source_identifier: @meth.upcase, 11 | }, 12 | }.deep_merge(@props) 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /lib/jets/router/resources/filter.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Resources 2 | class Filter < Base 3 | def yes?(action) 4 | return true unless @options[:only] || @options[:except] 5 | 6 | if @options[:only] 7 | only = [@options[:only]].flatten.map(&:to_s) 8 | only.include?(action.to_s) 9 | else # except 10 | except = [@options[:except]].flatten.map(&:to_s) 11 | !except.include?(action.to_s) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/bin/dev/deploy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Hacky wrapper script so I do not forget to update the jets remote gem 4 | set -eux 5 | 6 | rm -f "dev.mode" 7 | bundle update 8 | 9 | export JETS_ENV=staging 10 | 11 | yarn install 12 | bin/webpack 13 | 14 | os=`uname` 15 | if [[ "$os" == 'Darwin' ]]; then 16 | time jets deploy # possibly using hacked local version of jets 17 | else 18 | time bundle exec jets deploy # required to use bundle exec on the server 19 | fi 20 | -------------------------------------------------------------------------------- /spec/lib/jets/resource/lambda/gem_layer_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::Lambda::GemLayer do 2 | let(:resource) { Jets::Resource::Lambda::GemLayer.new } 3 | 4 | context "gems layer version" do 5 | it "builds template" do 6 | expect(resource.logical_id).to eq "GemLayer" 7 | properties = resource.properties 8 | # puts YAML.dump(properties) # uncomment to debug 9 | expect(properties["LayerName"]).to eq "test-demo-gems" 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/jets/commands/db.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands 2 | class Db < Jets::Commands::Base 3 | desc "generate", "Creates a migration to change a db table" 4 | long_desc Help.text('db:generate') 5 | def generate(*args) 6 | require "rails/generators" 7 | require "rails/generators/active_record/migration/migration_generator" 8 | 9 | generator = ActiveRecord::Generators::MigrationGenerator.new(args) 10 | generator.create_migration_file 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/core_ext/kernel.rb: -------------------------------------------------------------------------------- 1 | module Kernel 2 | module_function 3 | 4 | alias_method :jets_original_require, :require 5 | # @param path [String] 6 | # @return [Boolean] 7 | def require(path) 8 | # Hack to prevent Rails const from being defined 9 | # Actionview requires "rails-html-sanitizer" and that creates a Rails module 10 | path = "jets-html-sanitizer" if path == "rails-html-sanitizer" && !ENV['JETS_RAILS_CONST'] 11 | jets_original_require(path) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/jets/controller/middleware/local/route_matcher.rb: -------------------------------------------------------------------------------- 1 | class Jets::Controller::Middleware::Local 2 | class RouteMatcher 3 | def initialize(env) 4 | @env = env 5 | end 6 | 7 | def find_route 8 | Jets::Router::Finder.new(path, method).run 9 | end 10 | 11 | private 12 | attr_reader :env 13 | 14 | def method 15 | env["REQUEST_METHOD"] || "GET" 16 | end 17 | 18 | def path 19 | env["PATH_INFO"].sub(/^\//,'') 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/jobs/security_job.rb: -------------------------------------------------------------------------------- 1 | class SecurityJob < ApplicationJob 2 | rule_event( 3 | source: ["aws.ec2"], 4 | detail_type: ["EC2 Instance State-change Notification"], 5 | detail: { 6 | state: ["stopping"], 7 | } 8 | ) 9 | rule_event( 10 | detail_type: ["AWS API Call via CloudTrail"], 11 | detail: { 12 | userIdentity: { 13 | type: ["Root"] 14 | } 15 | } 16 | ) 17 | rate "10 hours" 18 | def lock 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/integration/fixtures/postman/environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "f50e05e5-c6dd-4707-9270-82c706b2bcef", 3 | "name": "Jets Test1", 4 | "values": [ 5 | { 6 | "key": "BASE_URL", 7 | "value": "http://localhost:8888/", 8 | "description": "", 9 | "type": "text", 10 | "enabled": true 11 | } 12 | ], 13 | "_postman_variable_scope": "environment", 14 | "_postman_exported_at": "2018-08-06T01:39:56.523Z", 15 | "_postman_exported_using": "Postman/6.2.3" 16 | } 17 | -------------------------------------------------------------------------------- /docs/_reference/jets-url.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets url 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets url 9 | 10 | ## Description 11 | 12 | App url if routes are defined. 13 | 14 | If routes have been configured and an API Gateway was created for the app, this provides the application's url. 15 | 16 | ## Example 17 | 18 | $ jets url 19 | https://v9wa7vqcia.execute-api.us-west-2.amazonaws.com/dev 20 | 21 | ## Options 22 | 23 | ``` 24 | [--noop], [--no-noop] 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /docs/_reference/jets-gems-check.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets gems:check 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets gems:check 9 | 10 | ## Description 11 | 12 | Check if pre-built Lambda gems are available from the gems source. You can configure the gem in config/application.rb: 13 | 14 | # Sources for check for pre-compiled Lambda gems. Checks the list in order. 15 | Jets.application.configure do 16 | config.gems.source = "https://api.serverlessgems.com/api/v1" 17 | end 18 | -------------------------------------------------------------------------------- /spec/lib/jets/controller/middleware/local/api_gateway_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Controller::Middleware::Local::ApiGateway do 2 | let(:route) do 3 | Jets::Controller::Middleware::Local::RouteMatcher.new(env).find_route 4 | end 5 | let(:env) do 6 | { "PATH_INFO" => "/posts/tung/edit", "REQUEST_METHOD" => "GET" } 7 | end 8 | 9 | it "call" do 10 | api_gateway = Jets::Controller::Middleware::Local::ApiGateway.new(route, env) 11 | expect(api_gateway.event).to be_a(Hash) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /docs/_reference/jets-dbconsole.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets dbconsole 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets dbconsole 9 | 10 | ## Description 11 | 12 | Starts DB REPL console. 13 | 14 | This is like running the psql command with the `config/database.yml` values and set for you. 15 | 16 | ## Example 17 | 18 | $ jets dbconsole 19 | psql (9.2.24) 20 | Type "help" for help. 21 | 22 | demo_dev=> 23 | 24 | ## Options 25 | 26 | ``` 27 | [--noop], [--no-noop] 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/config/routes.rb: -------------------------------------------------------------------------------- 1 | Jets.application.routes.draw do 2 | root "jets/public#show" 3 | 4 | # The jets/public#show controller can serve static utf8 content out of the public folder. 5 | # Note, as part of the deploy process Jets uploads files in the public folder to s3 6 | # and serves them out of s3 directly. S3 is well suited to serve static assets. 7 | # More info here: https://rubyonjets.com/docs/extras/assets-serving/ 8 | any "*catchall", to: "jets/public#show" 9 | end 10 | -------------------------------------------------------------------------------- /lib/jets/job/dsl/log_event.rb: -------------------------------------------------------------------------------- 1 | module Jets::Job::Dsl 2 | module LogEvent 3 | def log_event(log_group_name, props={}) 4 | props.merge!(log_group_name: log_group_name) 5 | declare_log_subscription_filter(props) 6 | end 7 | 8 | def declare_log_subscription_filter(props={}) 9 | r = Jets::Resource::Logs::SubscriptionFilter.new(props) 10 | with_fresh_properties do 11 | resource(r.definition) # add associated resource immediately 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/jets/resource/api_gateway/rest_api/routes/change.rb: -------------------------------------------------------------------------------- 1 | # Detects route changes 2 | class Jets::Resource::ApiGateway::RestApi::Routes 3 | class Change 4 | include Jets::AwsServices 5 | 6 | def changed? 7 | return false unless parent_stack_exists? 8 | 9 | MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed? || ENV['JETS_REPLACE_API'] 10 | end 11 | 12 | def parent_stack_exists? 13 | stack_exists?(Jets::Naming.parent_stack_name) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/jets/stack/output/dsl.rb: -------------------------------------------------------------------------------- 1 | class Jets::Stack 2 | class Output 3 | module Dsl 4 | extend ActiveSupport::Concern 5 | 6 | def outputs 7 | Output.definitions(self.class) 8 | end 9 | 10 | class_methods do 11 | def output(*definition) 12 | # self is subclass is the stack that inherits from Jets::Stack 13 | # IE: ExampleStack < Jets::Stack 14 | Output.new(self, *definition).register 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/books_controller/node/node_error_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.handler = function(event, context, callback) { 4 | INTENTIONAL_NODE_ERROR 5 | var body = {'message': 'hi from node'}; 6 | var response = { 7 | statusCode: "200", 8 | headers: { 9 | 'Content-Type': 'application/json', 10 | 'Access-Control-Allow-Origin': '*' 11 | }, 12 | body: JSON.stringify(body) 13 | }; 14 | callback(null, response); 15 | }; 16 | -------------------------------------------------------------------------------- /spec/lib/jets/cfn/ship_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Cfn::Ship do 2 | let(:ship) do 3 | Jets::Cfn::Ship.new(noop: true) 4 | end 5 | 6 | describe "Cfn::Ship" do 7 | it "adds functions to resources" do 8 | expect(ship).to receive(:stack_in_progress?) # stub 9 | expect(ship).to receive(:save_stack) # stub 10 | expect(ship).to receive(:wait_for_stack).and_return(true) # stub 11 | expect(ship).to receive(:endpoint_available?).twice # stub 12 | ship.run 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /docs/_docs/routing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Routing 3 | --- 4 | 5 | {% include routing.md %} 6 | 7 | 8 | ## Production Deployment 9 | 10 | Important: If you are deploying a production service, it is strongly recommended to use a [Custom Domain]({% link _docs/routing/custom-domain.md %}). Jets computes and figures out whether or not it needs to replace the REST API as part of deployment. When the REST API is replaced, the API Endpoint will be different. By using Custom Domain, you'll be able to keep the same endpoint. 11 | 12 | -------------------------------------------------------------------------------- /docs/_includes/google_analytics.html: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /docs/_sass/bootstrap-overrides.scss: -------------------------------------------------------------------------------- 1 | // Bootstrap overrides for this template 2 | .bg-primary { 3 | // background: $theme-primary; 4 | // background: -webkit-linear-gradient($theme-primary, darken($theme-primary, 5%)); 5 | // background: linear-gradient(#c70000, darken($theme-primary, 5%)); 6 | background-color: #730c0c !important; 7 | } 8 | 9 | .text-primary { 10 | color: $theme-primary; 11 | } 12 | 13 | .no-gutter > [class*='col-'] { 14 | padding-right: 0; 15 | padding-left: 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /lib/jets/db.rb: -------------------------------------------------------------------------------- 1 | module Jets::Db ; end 2 | 3 | # Thanks: https://makandracards.com/makandra/42521-detecting-if-a-ruby-gem-is-loaded 4 | if File.exist?("#{Jets.root}/config/database.yml") 5 | require "active_record" 6 | specs = Gem.loaded_specs 7 | require "mysql2" if specs.key?('mysql2') 8 | require "pg" if specs.key?('pg') 9 | end 10 | 11 | if File.exist?("#{Jets.root}/config/dynamodb.yml") 12 | specs = Gem.loaded_specs 13 | specs.key?('dynomite') 14 | require "dynomite" if specs.key?('dynomite') 15 | end 16 | -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/sqs.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module Sqs 3 | def sqs_queue(id, props={}) 4 | # props[:queue_name] ||= id.to_s # comment out to allow CloudFormation to generate name 5 | resource(id, "AWS::SQS::Queue", props) 6 | output(id, value: get_att("#{id}.Arn")) # normal !Ref returns the sqs url the ARN is useful for nested stacks depends_on 7 | output("#{id}_url", ref(id)) # useful for Stack.lookup method. IE: List.lookup(:waitlist_url) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /docs/_docs/events.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Events 3 | --- 4 | 5 | Jets is also a powerful Glue Serverless Framework. 6 | 7 | AWS Lambda supports many event triggers. With event triggers, you can use Lambda functions as glue. Here's a list of the events supported by Jets. 8 | 9 | 15 | 16 | The next sections cover the event triggers. 17 | 18 | -------------------------------------------------------------------------------- /lib/jets/commands/import.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands 2 | class Import < Jets::Commands::Base 3 | Jets::Commands::Import::Base.cli_options.each do |args| 4 | class_option(*args) 5 | end 6 | long_desc Help.text('import:rails') 7 | register(Jets::Commands::Import::Rails, "rails", "rails", "Imports rails project in the rack subfolder") 8 | 9 | long_desc Help.text('import:rack') 10 | register(Jets::Commands::Import::Rack, "rack", "rack", "Imports rack project in the rack subfolder") 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/jets/turbo/project/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "jets" 4 | 5 | group :development, :test do 6 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 7 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 8 | gem 'shotgun' 9 | gem 'rack' 10 | end 11 | 12 | group :test do 13 | gem 'rspec' # rspec test group only or we get the "irb: warn: can't alias context from irb_context warning" when starting jets console 14 | gem 'launchy' 15 | gem 'capybara' 16 | end 17 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/books_controller/node/node_async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.handler = async function(event, context) { 4 | var body = {'message': 'hi from node'}; 5 | var response = { 6 | statusCode: "200", 7 | headers: { 8 | 'Content-Type': 'application/json', 9 | 'Access-Control-Allow-Origin': '*' 10 | }, 11 | body: JSON.stringify(body) 12 | }; 13 | return(response); 14 | // or 15 | // throw new Error("some error type”); 16 | } 17 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/jets/cfn/builders/shared_builder.rb: -------------------------------------------------------------------------------- 1 | module Jets::Cfn::Builders 2 | class SharedBuilder < BaseChildBuilder 3 | def compose 4 | stack = @app_class.new # @app_class is subclass. IE: Alarm < Jets::Stack 5 | builder = Jets::Stack::Builder.new(stack) 6 | @template = builder.template # overwrite entire @template 7 | end 8 | 9 | # template_path is an interface method for Interface module 10 | def template_path 11 | Jets::Naming.shared_template_path(@app_class) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/jets/stack/resource/dsl.rb: -------------------------------------------------------------------------------- 1 | class Jets::Stack 2 | class Resource 3 | module Dsl 4 | extend ActiveSupport::Concern 5 | 6 | def resources 7 | Resource.definitions(self.class) 8 | end 9 | 10 | class_methods do 11 | def resource(*definition) 12 | # self is subclass is the stack that inherits from Jets::Stack 13 | # IE: ExampleStack < Jets::Stack 14 | Resource.new(self, *definition).register 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /docs/_includes/example.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Architecture

6 | 7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/jets/resource/lambda/gem_layer.rb: -------------------------------------------------------------------------------- 1 | module Jets::Resource::Lambda 2 | class GemLayer < LayerVersion 3 | def description 4 | "Jets Ruby Gems" 5 | end 6 | 7 | def layer_name 8 | # Do not include the Jets.extra_env to group the layers in same app together 9 | "#{Jets.config.short_env}-#{Jets.config.project_name}-gems" 10 | end 11 | 12 | def code_s3_key 13 | checksum = Jets::Builders::Md5.checksums["stage/opt"] 14 | "jets/code/opt-#{checksum}.zip" # s3_key 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/bin/webpack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["JETS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/webpack_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::WebpackRunner.run(ARGV) 19 | end -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please fill out one of the templates on https://github.com/tongueroo/jets/issues/new/choose 2 | 3 | If you want to ask a question please do so on the Jets Community forum: https://community.rubyonjets.com 4 | 5 | To be sensitive to everyone's time, we may close issues asking questions without comment. Posting your questions in the Jets community forum is the best place. It also benefits others by making the questions easier to find. Here are some additional options also http://rubyonjets.com/docs/support/ 👌 6 | 7 | Thank you! 8 | -------------------------------------------------------------------------------- /docs/_reference/jets-upgrade.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets upgrade 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets upgrade 9 | 10 | ## Description 11 | 12 | Upgrade Jets. 13 | 14 | Upgrades the Jets project structure to the latest version. This command is designed to be idempotent, so it should be safe to run this command multiple times. 15 | 16 | ## Example 17 | 18 | $ jets upgrade 19 | 20 | Refer to https://rubyonjets.com/docs/extras/upgrading/ 21 | 22 | ## Options 23 | 24 | ``` 25 | [--noop], [--no-noop] 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /lib/jets/resource/sqs/queue.rb: -------------------------------------------------------------------------------- 1 | # CloudFormation SQS Queue docs: https://amzn.to/2MVWk0j 2 | module Jets::Resource::Sqs 3 | class Queue < Jets::Resource::Base 4 | def initialize(props={}) 5 | @props = props # associated_properties from dsl.rb 6 | end 7 | 8 | def definition 9 | { 10 | queue_logical_id => { 11 | type: "AWS::SQS::Queue", 12 | properties: @props, 13 | } 14 | } 15 | end 16 | 17 | def queue_logical_id 18 | "{namespace}_sqs_queue" 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /docs/_includes/cloudformation_links.md: -------------------------------------------------------------------------------- 1 | For those learning CloudFormation, these resources might help: 2 | 3 | * [AWS CloudFormation Declarative Infrastructure Code Tutorial](https://blog.boltops.com/2018/02/14/aws-cloudformation-declarative-infrastructure-code-tutorial) 4 | * [A Simple Introduction to AWS CloudFormation Part 1: EC2 Instance](https://blog.boltops.com/2017/03/06/a-simple-introduction-to-aws-cloudformation-part-1-ec2-instance) 5 | * [Working with Nested Stacks](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html) -------------------------------------------------------------------------------- /lib/jets/commands/upgrade/templates/bin/webpack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["JETS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/webpack_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::WebpackRunner.run(ARGV) 19 | end -------------------------------------------------------------------------------- /lib/jets/job/helpers/log_event_helper.rb: -------------------------------------------------------------------------------- 1 | require 'base64' 2 | require 'json' 3 | require 'stringio' 4 | require 'zlib' 5 | 6 | module Jets::Job::Helpers 7 | module LogEventHelper 8 | def log_event 9 | encoded = event["awslogs"]["data"] 10 | compressed_string = Base64.decode64(encoded) 11 | gz = Zlib::GzipReader.new(StringIO.new(compressed_string)) 12 | uncompressed_string = gz.read 13 | data = JSON.load(uncompressed_string) 14 | ActiveSupport::HashWithIndifferentAccess.new(data) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /docs/_sass/table.scss: -------------------------------------------------------------------------------- 1 | table { 2 | width: 100%; 3 | max-width: 900px; 4 | margin-bottom: 20px; 5 | border: 1px solid #dfe2e5; 6 | } 7 | 8 | tr:nth-child(2n) { 9 | background-color: #f6f8fa; 10 | } 11 | 12 | td { 13 | vertical-align: top; 14 | border: 1px solid #dfe2e5; 15 | } 16 | 17 | th, td { 18 | padding: 10px; 19 | } 20 | 21 | thead th { 22 | background-color: #000000; 23 | text-transform: uppercase; 24 | color: #cdcdce; 25 | } 26 | 27 | tbody td { 28 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.1); 29 | color: black; 30 | } -------------------------------------------------------------------------------- /docs/css/main.scss: -------------------------------------------------------------------------------- 1 | --- 2 | # this ensures Jekyll reads the file to be transformed into CSS later 3 | # only Main files contain this front matter, not partials. 4 | --- 5 | 6 | // base 7 | @import "variables"; 8 | @import "mixins"; 9 | @import "default"; 10 | 11 | // structure 12 | @import "sidebar"; 13 | @import "caret"; 14 | @import "content"; 15 | @import "footer"; 16 | 17 | // theme 18 | @import "bootstrap-overrides"; 19 | @import "theme"; 20 | @import "buttons"; 21 | @import "masthead"; 22 | @import "table"; 23 | @import "syntax"; 24 | @import "cta"; 25 | -------------------------------------------------------------------------------- /lib/jets/resource/child_stack/api_gateway.rb: -------------------------------------------------------------------------------- 1 | # Implements: 2 | # 3 | # definition 4 | # template_filename 5 | # 6 | module Jets::Resource::ChildStack 7 | class ApiGateway < Base 8 | def definition 9 | { 10 | api_gateway: { 11 | type: "AWS::CloudFormation::Stack", 12 | properties: { 13 | template_url: template_url, 14 | } 15 | } 16 | } 17 | end 18 | 19 | def template_filename 20 | "#{Jets.config.project_namespace}-api-gateway.yml" 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/bin/webpack-dev-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["JETS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/dev_server_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::DevServerRunner.run(ARGV) 19 | end -------------------------------------------------------------------------------- /spec/lib/jets/builders/tidy_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Builders::Tidy do 2 | context "general" do 3 | let(:tidy) do 4 | Jets::Builders::Tidy.new(project_dir, noop: true) 5 | end 6 | 7 | context "jets app" do 8 | let(:project_dir) { ENV['JETS_ROOT'] } 9 | it "cleanup" do 10 | tidy.cleanup! 11 | end 12 | 13 | it "excludes should not include jetskeep" do 14 | expect(tidy.jetskeep).to eq [".bundle", "/public/packs", "/public/packs-test", "vendor", "pack"] 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/jets/commands/gems.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands 2 | class Gems < Jets::Commands::Base 3 | desc "check", "Check if pre-built Lambda gems are available from the sources" 4 | long_desc Help.text("gems:check") 5 | option :verbose, type: :boolean, desc: "Verbose mode" 6 | def check 7 | check = Jets::Gems::Check.new(@options) 8 | check.run! # exits early if missing gems found 9 | # If reach here, means all gems are ok. 10 | puts "Congrats! All gems are available in as pre-built Lambda gems 👍" 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/commands/help/console.md: -------------------------------------------------------------------------------- 1 | ## Example 2 | 3 | $ jets console 4 | >> Post.table_name 5 | => "posts" 6 | >> ActiveRecord::Base.connection.tables 7 | => ["schema_migrations", "ar_internal_metadata", "posts"] 8 | >> Jets.env 9 | => "development" 10 | >> 11 | 12 | ## Use .env.development.remote 13 | 14 | To use the remote values also in the `jets console` you can use the `JETS_ENV_REMOTE=1` env variable. Example: 15 | 16 | JETS_ENV_REMOTE=1 jets console 17 | 18 | More info at [Env Files](http://rubyonjets.com/docs/env-files/) -------------------------------------------------------------------------------- /lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | # Example: 2 | # describe PostsController, type: :controller do 3 | # it "index returns a success response" do 4 | # get '/posts' 5 | # expect(response.status).to eq 200 6 | # pp response.body 7 | # end 8 | # 9 | # it "show returns a success response" do 10 | # Post.create(id: 1) unless Post.find_by(id: 1) # TODO: set up factory_bot 11 | # get '/posts/:id', id: 1 12 | # expect(response.status).to eq 200 13 | # pp response.body 14 | # end 15 | # end 16 | -------------------------------------------------------------------------------- /spec/lib/jets/resource/child_stack/api_gateway_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::ChildStack::ApiGateway do 2 | let(:resource) do 3 | Jets::Resource::ChildStack::ApiGateway.new("s3-bucket") 4 | end 5 | 6 | describe "resource" do 7 | it "contains child stack info" do 8 | expect(resource.logical_id).to eq "ApiGateway" 9 | properties = resource.properties 10 | expect(properties["TemplateURL"]).to eq "https://s3.amazonaws.com/s3-bucket/jets/cfn-templates/#{Jets.config.project_namespace}-api-gateway.yml" 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/commands/upgrade/templates/bin/webpack-dev-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["JETS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "rubygems" 11 | require "bundler/setup" 12 | 13 | require "webpacker" 14 | require "webpacker/dev_server_runner" 15 | 16 | APP_ROOT = File.expand_path("..", __dir__) 17 | Dir.chdir(APP_ROOT) do 18 | Webpacker::DevServerRunner.run(ARGV) 19 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/stores_controller.rb: -------------------------------------------------------------------------------- 1 | class StoresController < ApplicationController 2 | layout false # for specs to pass 3 | 4 | class_properties(memory_size: 768) 5 | class_env(my_test: "data") 6 | 7 | # timeout 30 8 | properties(timeout: 20, memory_size: 1000) 9 | def index 10 | response.headers["Set-Cookie"] = "foo=bar" 11 | end 12 | 13 | timeout 35 14 | def new 15 | @item = {name: "soda"} 16 | end 17 | 18 | environment(key1: "value1", key2: "value2") 19 | memory_size(1024) 20 | def show 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /docs/_docs/app-config/forgery-protection.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Forgery Protection 3 | --- 4 | 5 | By default, csrf forgery protection is enabled in html mode and disabled in api mode. You can override the setting with `default_protect_from_forgery`. 6 | 7 | ```ruby 8 | Jets.application.configure do 9 | config.controllers.default_protect_from_forgery = false 10 | end 11 | ``` 12 | 13 | You can also skip the before_action filter on a per-controller basis. 14 | 15 | ```ruby 16 | class PostsController < ApplicationController 17 | skip_forgery_protection 18 | end 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /docs/_sass/content.scss: -------------------------------------------------------------------------------- 1 | // https://www.w3schools.com/howto/howto_css_menu_icon.asp 2 | .menu-top-bar { 3 | padding: 15px; // to match with .container-fluid 15px 4 | } 5 | #menu-toggle { 6 | .bar1, .bar2, .bar3 { 7 | width: 24px; 8 | height: 2px; 9 | background-color: #333; 10 | margin: 6px 0; 11 | transition: 0.4s; 12 | } 13 | } 14 | 15 | #content { 16 | width: 100%; 17 | max-width: 900px; 18 | padding: 5px; // .container-fluid has 15px already 19 | min-height: 85vh; // not 100vh so footer shows a little bit 20 | transition: all 0.3s; 21 | } 22 | -------------------------------------------------------------------------------- /lib/jets/builders/shim_vars/base.rb: -------------------------------------------------------------------------------- 1 | module Jets::Builders::ShimVars 2 | class Base 3 | include Jets::AwsServices 4 | extend Memoist 5 | 6 | def s3_bucket 7 | Jets.aws.s3_bucket 8 | end 9 | 10 | def rack_zip 11 | checksum_zip(:rack) 12 | end 13 | 14 | def bundled_zip 15 | checksum_zip(:bundled) 16 | end 17 | 18 | private 19 | def checksum_zip(name) 20 | checksum = Jets::Builders::Md5.checksums["stage/#{name}"] 21 | return unless checksum 22 | "#{name}-#{checksum}.zip" 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/jets/cfn/builders/util/source.rb: -------------------------------------------------------------------------------- 1 | module Jets::Cfn::Builders::Util 2 | class Source 3 | class << self 4 | def version 5 | return '' unless git_installed? 6 | sha = sh "git rev-parse HEAD 2>/dev/null" 7 | return '' if sha == '' # if its not a git repo, it'll be an empty string 8 | sha[0..7] 9 | end 10 | 11 | private 12 | def git_installed? 13 | system("type git > /dev/null 2>&1") 14 | end 15 | 16 | def sh(command) 17 | `#{command}`.strip 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt: -------------------------------------------------------------------------------- 1 | // This file is automatically generated by Jets. It is meant to be modified 2 | // for your needs. 3 | 4 | <% if @bootstrap -%> 5 | @import '~bootstrap/dist/css/bootstrap'; 6 | <% end -%> 7 | // Simple starter css generated by Jets, meant to be overriden 8 | .starter { 9 | padding: 20px; 10 | 11 | td:first-child { 12 | min-width: 300px; 13 | } 14 | td { 15 | padding-left: 6px; 16 | } 17 | 18 | label { 19 | min-width: 200px; 20 | } 21 | input { 22 | padding: 5px; 23 | } 24 | } -------------------------------------------------------------------------------- /lib/jets/commands/import/rack.rb: -------------------------------------------------------------------------------- 1 | class Jets::Commands::Import 2 | class Rack < Base 3 | def install 4 | bundle_install 5 | end 6 | 7 | def finish_message 8 | puts <<~EOL 9 | #{"="*30} 10 | Congrats! The Rack project from #{@source} has been imported to the rack folder. 11 | 12 | Note, generic rack projects will likely need some adjustments to take into account API Gateway stages and logging. For more info refer to [Mega Mode Considerations](http://rubyonjets.com//megamode-details/). 13 | EOL 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/jets/internal/app/functions/jets/base_path.rb: -------------------------------------------------------------------------------- 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 19 | -------------------------------------------------------------------------------- /lib/jets/spec_helpers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'base64' 4 | 5 | module Jets 6 | module SpecHelpers 7 | include Fixtures 8 | include Controllers 9 | end 10 | end 11 | 12 | if File.exist?("#{Jets.root}/config/database.yml") && !ENV["SKIP_MIGRATION_CHECK"] 13 | ActiveRecord::Tasks::DatabaseTasks.db_dir = "#{Jets.root}/db" 14 | ActiveRecord::Migration.extend ActiveRecord::MigrationChecker 15 | ActiveRecord::Migration.prepare_test_db 16 | end 17 | 18 | require "rspec" 19 | RSpec.configure do |c| 20 | c.include Jets::SpecHelpers 21 | end 22 | -------------------------------------------------------------------------------- /docs/_docs/rack/cookies.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cookies 3 | --- 4 | 5 | You can set cookies with the `cookies` helper. Example: 6 | 7 | ```ruby 8 | class PostsController < ApplicationController 9 | def index 10 | cookies[:favorite] = "chocolate" 11 | render json: {message: "yummy cookies set"} 12 | end 13 | 14 | def show 15 | cookies.merge! 'foo' => 'bar', 'bar' => 'baz' 16 | cookies.keep_if { |key, value| key.start_with? 'b' } 17 | puts "cookies.size: #{cookies.size}" 18 | render json: {message: "cookies behave like a hash"} 19 | end 20 | end 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /docs/_includes/content.html: -------------------------------------------------------------------------------- 1 | {% if page.sidebar == false %} 2 | 3 | {{ content }} 4 | 5 | {% else %} 6 | 7 |
8 | {% include sidebar.html %} 9 |
10 | 17 | 18 |
19 |

{{ page.title }}

20 | {{ content }} 21 |
22 |
23 |
24 | 25 | {% endif %} 26 | -------------------------------------------------------------------------------- /lib/jets/builders/rackup_wrappers/rackup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | export JETS_MEGA=1 6 | 7 | # Figure out where this script is located. 8 | PROJECTDIR="`dirname \"$0\"`" 9 | PROJECTDIR="`cd \"$PROJECTDIR/..\" && pwd`" 10 | 11 | unset BUNDLE_IGNORE_CONFIG 12 | # When jets packages the app code it creates .bundle/config in the project root. 13 | # We want that to be used. 14 | 15 | # Drop a pidfile 16 | # echo $$ > /tmp/jets-rackup.pid 17 | 18 | # Run the actual app using the bundled Ruby interpreter, with Bundler activated. 19 | exec ruby -rbundler/setup bin/rackup.rb "$@" 20 | -------------------------------------------------------------------------------- /lib/jets/commands/db/tasks/dummy/app.rb: -------------------------------------------------------------------------------- 1 | require "recursive-open-struct" 2 | 3 | module Jets::Commands::Db::Tasks::Dummy 4 | class App 5 | def config 6 | Config.new( 7 | active_record: { 8 | belongs_to_required_by_default: true 9 | }, 10 | paths: { 11 | db: ["db"], 12 | "db/migrate": ["db/migrate"] 13 | } 14 | ) 15 | end 16 | 17 | def paths 18 | RecursiveOpenStruct.new( 19 | paths: { 20 | "db/migrate": ["db/migrate"] 21 | } 22 | ) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/lib/jets/resource/child_stack/api_deployment_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::ChildStack::ApiDeployment do 2 | let(:resource) do 3 | Jets::Resource::ChildStack::ApiDeployment.new("s3-bucket") 4 | end 5 | 6 | describe "resource" do 7 | it "contains child stack info" do 8 | expect(resource.logical_id).to match(/ApiDeployment(\d+)/) 9 | properties = resource.properties 10 | expect(properties["TemplateURL"]).to eq "https://s3.amazonaws.com/s3-bucket/jets/cfn-templates/#{Jets.config.project_namespace}-api-deployment.yml" 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/lib/jets/resource/api_gateway/domain_name_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::ApiGateway::DomainName do 2 | 3 | context 'default' do 4 | let(:domain_name) do 5 | Jets::Resource::ApiGateway::DomainName.new 6 | end 7 | 8 | it "domain_name" do 9 | allow(Jets.config.domain).to receive(:name).and_return("test.com") 10 | expect(domain_name.logical_id).to eq "DomainName" 11 | properties = domain_name.properties 12 | # pp properties # uncomment to debug 13 | expect(properties["DomainName"]).to eq "test.com" 14 | end 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /lib/jets/mega/request/source.rb: -------------------------------------------------------------------------------- 1 | class Jets::Mega::Request 2 | class Source 3 | def initialize(event) 4 | @event = event 5 | env = Jets::Controller::Rack::Env.new(@event, {}).convert # convert to Rack env 6 | @source_request = Rack::Request.new(env) 7 | end 8 | 9 | def body 10 | if @source_request.body.respond_to?(:read) 11 | body = @source_request.body.read 12 | @source_request.body.rewind 13 | end 14 | body 15 | end 16 | 17 | def content_length 18 | @source_request.content_length.to_i 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/jets/rule/base.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | # Base public methods get turned into Lambda functions. 4 | # 5 | # Jets::Rule::Base < Jets::Lambda::Functions 6 | # Both Jets::Rule::Base and Jets::Lambda::Functions have Dsl modules included. 7 | # So the Jets::Rule::Dsl overrides some of the Jets::Lambda::Functions behavior. 8 | module Jets::Rule 9 | class Base < Jets::Lambda::Functions 10 | include Dsl 11 | 12 | class << self 13 | def process(event, context, meth) 14 | job = new(event, context, meth) 15 | job.send(meth) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/lib/jets/generate_spec.rb: -------------------------------------------------------------------------------- 1 | describe "jets generate" do 2 | describe "migration" do 3 | it "creates a migration file" do 4 | command = "exe/jets dynamodb:generate create_posts --partition-key id:string" 5 | out = execute(command) 6 | # pp out # uncomment to debug 7 | expect(out).to include("Generating migration") 8 | migration_path = Dir.glob("#{Dynomite.app_root}dynamodb/migrate/*").first 9 | migration_exist = File.exist?(migration_path) 10 | expect(migration_exist).to be true 11 | FileUtils.rm_f(migration_path) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | Bundler.setup 3 | require "bundler/gem_tasks" 4 | require "rspec/core/rake_task" 5 | 6 | task :default => :spec 7 | 8 | RSpec::Core::RakeTask.new 9 | 10 | require_relative "lib/jets" 11 | desc "Generates cli reference docs as markdown" 12 | task :docs do 13 | Jets::Autoloaders.once.eager_load 14 | Jets::Commands::Markdown::Creator.create_all 15 | end 16 | 17 | # Thanks: https://docs.ruby-lang.org/en/2.1.0/RDoc/Task.html 18 | require 'rdoc/task' 19 | require 'jets/rdoc' 20 | 21 | RDoc::Task.new do |rdoc| 22 | rdoc.options += Jets::Rdoc.options 23 | end 24 | 25 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /lib/jets/stack/main/dsl/cloudwatch.rb: -------------------------------------------------------------------------------- 1 | module Jets::Stack::Main::Dsl 2 | module Cloudwatch 3 | def cloudwatch_alarm(id, hash={}) 4 | if hash.key?(:depends_on) 5 | attributes = hash # leave structure alone and add type only 6 | attributes[:type] = "AWS::CloudWatch::Alarm" 7 | else 8 | # the attributes are properties 9 | properties = hash 10 | attributes = { 11 | type: "AWS::CloudWatch::Alarm", 12 | properties: properties, 13 | } 14 | end 15 | resource(id, attributes) 16 | output(id) 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/javascript/packs/framework.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console:0 */ 2 | // This file is automatically compiled by Webpack, along with any other files 3 | // present in this directory. You're encouraged to place your actual framework logic in 4 | // a relevant structure within app/javascript and only use these pack files to reference 5 | // that code so it'll be compiled. 6 | // 7 | // To reference this file, add <%= javascript_pack_tag 'framework' %> to the appropriate 8 | // layout file, like app/views/layouts/framework.html.erb 9 | 10 | import '../src/framework' 11 | import './delete-item' 12 | -------------------------------------------------------------------------------- /spec/lib/jets/middleware/default_stack_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Middleware::DefaultStack do 2 | let(:default_stack) { Jets::Middleware::DefaultStack.new(Jets.application, Jets.config) } 3 | context "default_stack" do 4 | it "build_stack" do 5 | stack = default_stack.build_stack 6 | middlewares = stack.instance_variable_get(:@middlewares) 7 | expect(middlewares).to include(Rack::Runtime) 8 | end 9 | 10 | it "session store" do 11 | session_store = default_stack.send(:session_store) 12 | expect(session_store).to eq Rack::Session::Cookie 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /docs/_reference/jets-clean-log.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets clean:log 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets clean:log 9 | 10 | ## Description 11 | 12 | Cleans CloudWatch log groups assocated with app. 13 | 14 | Essentially removes the CloudWatch groups assocated with the app. Lambda requests re-create the log groups so this is pretty safe to do. 15 | 16 | ## Example 17 | 18 | jets log:clean 19 | 20 | ## Options 21 | 22 | ``` 23 | [--noop], [--no-noop] # noop or dry-run mode 24 | [--mute], [--no-mute] # mute output 25 | [--sure], [--no-sure] # bypass are you sure prompt 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /lib/jets/router/resources/options.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Resources 2 | class Options < Base 3 | def build(action) 4 | controller = @options[:singular_resource] ? @name.to_s.pluralize : @name 5 | options = @options.merge(to: "#{controller}##{action}") # important to create a copy of the options 6 | # remove special options from getting to create_route. For some reason .slice! doesnt work 7 | options.delete(:only) 8 | options.delete(:except) 9 | options[:from_scope] = true # flag to drop the prefix later in Route#compute_path 10 | options 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/jets/logger.rb: -------------------------------------------------------------------------------- 1 | require 'logger' 2 | 3 | module Jets 4 | class Logger < ::Logger 5 | # Only need to override the add method as the other calls all lead to it. 6 | def add(severity, message = nil, progname = nil) 7 | # Taken from Logger#add source 8 | # https://ruby-doc.org/stdlib-2.5.1/libdoc/logger/rdoc/Logger.html#method-i-add 9 | if message.nil? 10 | if block_given? 11 | message = yield 12 | else 13 | message = progname 14 | progname = @progname 15 | end 16 | end 17 | 18 | super # original logical 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /spec/lib/jets/resource/replacer_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::Replacer do 2 | let(:replacer) { Jets::Resource::Replacer.new(replacements) } 3 | let(:attributes) do 4 | { 5 | k: "{namespace}-value", 6 | a: { 7 | b: "{namespace}-value" 8 | } 9 | } 10 | end 11 | let(:replacements) { { namespace: "FooBar" } } 12 | 13 | context "raw cloudformation definition" do 14 | it "replace_placeholders" do 15 | result = replacer.replace_placeholders(attributes) 16 | # pp result 17 | expect(result).to eq(a: {b: "FooBar-value"}, k: "FooBar-value") 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /lib/jets/commands/clean/base.rb: -------------------------------------------------------------------------------- 1 | class Jets::Commands::Clean 2 | class Base 3 | def initialize(options={}) 4 | @options = options 5 | end 6 | 7 | private 8 | def say(message) 9 | prefix = 'NOOP ' if @options[:noop] 10 | puts "#{prefix}#{message}" unless @options[:mute] 11 | end 12 | 13 | def are_you_sure?(message) 14 | return true if @options[:yes] 15 | 16 | puts "Are you sure that you want to #{message}? (y/N)" 17 | yes = $stdin.gets.strip 18 | unless yes =~ /^y/ 19 | puts "Phew that was close!" 20 | exit 0 21 | end 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/controllers/books_controller/node/list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.handler = function(event, context, callback) { 4 | var body = {'message': 'hi from node'}; 5 | var response = { 6 | statusCode: "200", 7 | headers: { 8 | 'Content-Type': 'application/json', 9 | 'Access-Control-Allow-Origin': '*' 10 | }, 11 | body: JSON.stringify(body) 12 | }; 13 | callback(null, response); 14 | }; 15 | 16 | // if (require.main === module) { 17 | // console.log('called directly'); 18 | // } else { 19 | // console.log('required as a module'); 20 | // } -------------------------------------------------------------------------------- /spec/lib/jets/resource/child_stack/shared_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::ChildStack::Shared do 2 | let(:resource) do 3 | path = "/tmp/jets/demo/templates/demo-test-shared-custom.yml" 4 | Jets::Resource::ChildStack::Shared.new("s3-bucket", path: path) 5 | end 6 | 7 | describe "resource" do 8 | it "contains child stack info" do 9 | expect(resource.logical_id).to eq "Custom" 10 | properties = resource.properties 11 | expect(properties["TemplateURL"]).to eq "https://s3.amazonaws.com/s3-bucket/jets/cfn-templates/#{Jets.config.project_namespace}-shared-custom.yml" 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | guard "bundler", cmd: "bundle" do 2 | watch("Gemfile") 3 | watch(/^.+\.gemspec/) 4 | end 5 | 6 | guard :rspec, cmd: "bundle exec rspec" do 7 | require "guard/rspec/dsl" 8 | dsl = Guard::RSpec::Dsl.new(self) 9 | 10 | # RSpec files 11 | rspec = dsl.rspec 12 | watch(rspec.spec_helper) { rspec.spec_dir } 13 | watch(rspec.spec_support) { rspec.spec_dir } 14 | watch(rspec.spec_files) 15 | 16 | # Ruby files 17 | ruby = dsl.ruby 18 | puts "ruby.lib_files #{ruby.lib_files.inspect}" 19 | dsl.watch_spec_files_for(ruby.lib_files) 20 | 21 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } 22 | end 23 | -------------------------------------------------------------------------------- /docs/_docs/routing/authorizers/authorizer-caching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Authorizer Caching 3 | --- 4 | 5 | You can cache the authorizer with the `ttl` convenience property. This means the Authorizer lambda function will not be called again until the ttl expires. Example: 6 | 7 | ```ruby 8 | authorizer( 9 | name: "MainProtect", # required 10 | ttl: 60, 11 | ) 12 | ``` 13 | 14 | The `ttl` option is shorthand for the `authorizer_result_ttl_in_seconds` property associated with the CloudFormation [ApiGateway::Authorizer](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html) properties. 15 | 16 | -------------------------------------------------------------------------------- /lib/jets/commands/help/server.md: -------------------------------------------------------------------------------- 1 | The local server for mimics API Gateway and provides a way to test your app locally without deploying to AWS. 2 | 3 | ## Examples 4 | 5 | $ jets server 6 | => bundle exec shotgun --port 8888 --host 127.0.0.1 7 | Jets booting up in development mode! 8 | == Shotgun/WEBrick on http://127.0.0.1:8888/ 9 | [2018-08-17 05:31:33] INFO WEBrick 1.4.2 10 | [2018-08-17 05:31:33] INFO ruby 2.5.1 (2018-03-29) [x86_64-linux] 11 | [2018-08-17 05:31:33] INFO WEBrick::HTTPServer#start: pid=27433 port=8888 12 | 13 | Start up server binding to host `0.0.0.0`: 14 | 15 | jets server --host 0.0.0.0 16 | -------------------------------------------------------------------------------- /lib/jets/poly_fun/python_executor.rb: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /lib/jets/resource/child_stack/base.rb: -------------------------------------------------------------------------------- 1 | # Inheriting classes should implement: 2 | # 3 | # definition 4 | # template_filename 5 | # 6 | module Jets::Resource::ChildStack 7 | class Base < Jets::Resource::Base 8 | def initialize(s3_bucket, options={}) 9 | @s3_bucket = s3_bucket 10 | @options = options 11 | end 12 | 13 | def outputs 14 | { 15 | logical_id => "!Ref #{logical_id}", 16 | } 17 | end 18 | 19 | def template_url 20 | basename = File.basename(template_filename) 21 | "https://s3.amazonaws.com/#{@s3_bucket}/jets/cfn-templates/#{basename}" 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/config/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: mysql2 3 | encoding: utf8mb4 4 | pool: <%= ENV["DB_POOL"] || 5 %> 5 | database: <%= ENV['DB_NAME'] || 'demo_dev' %> 6 | username: <%= ENV['DB_USER'] || 'tung' %> 7 | password: <%= ENV['DB_PASS'] %> 8 | host: <%= ENV["DB_HOST"] %> 9 | 10 | development: 11 | <<: *default 12 | database: demo_dev 13 | 14 | test: 15 | <<: *default 16 | database: demo_test 17 | 18 | staging: 19 | <<: *default 20 | url: <%= ENV['DB_URL'] %> 21 | 22 | production: 23 | <<: *default 24 | # TODO: remove hardcode of test database url 25 | url: <%= ENV['DB_URL'] %> 26 | -------------------------------------------------------------------------------- /docs/_docs/extras/elb-override.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ELB Server Override Flag for jets server 3 | --- 4 | 5 | ## Background 6 | 7 | While the goal of Jets is to create and deploy serverless services, there is often a need to run Jets in the server mode to debug your applications. 8 | This may include hosting it on AWS and having it reachable through a load balancer such as an Application Load Balancer. 9 | 10 | In the event you have a need to run it through an Elastic Load Balancer while running `jets server`, setting `JETS_ELB=1` will guarantee `jets server` behaviour even when behind an ELB. Context [#584](https://github.com/boltops-tools/jets/pull/584) 11 | -------------------------------------------------------------------------------- /lib/jets/commands/clean.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands 2 | class Clean < Jets::Commands::Base 3 | class_option :noop, type: :boolean, desc: "noop or dry-run mode" 4 | class_option :mute, type: :boolean, desc: "mute output" 5 | class_option :yes, type: :boolean, desc: "bypass are you sure prompt" 6 | 7 | desc "log", "Cleans CloudWatch log groups assocated with app" 8 | long_desc Help.text('clean:log') 9 | def log 10 | Log.new(options).clean 11 | end 12 | 13 | desc "build", "Cleans jets build" 14 | long_desc Help.text('clean:build') 15 | def build 16 | Build.new(options).clean 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /docs/_docs/rails-support.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rails Support 3 | --- 4 | 5 | {% include rails-update.md %} 6 | 7 | Jets supports deploying Rails applications with a few approaches that are experimental. 8 | 9 | 1. [Jets Afterburner Mode]({% link _docs/rails/afterburner.md %}) 10 | 2. [Jets Mega Mode]({% link _docs/rails/megamode.md %}) 11 | 12 | ## Mount Rails App? 13 | 14 | Rails is also rack compatible, so you may wonder if you can mount a Rails app with Jets [routes mount]({% link _docs/routing/mount.md %}) support. Mounting a Rails app is not currently recommended. Some thoughts on this here: [Mounting Rails Apps]({% link _docs/rails/mount.md %}) 15 | 16 | -------------------------------------------------------------------------------- /docs/_docs/debug-ruby-errors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Debugging Ruby Errors 3 | --- 4 | 5 | Ruby stack trace errors surface up to the Lambda Console. 6 | 7 | ## Example 8 | 9 | Here's an example of Ruby code throwing an intentional error: 10 | 11 | ```ruby 12 | class PostsController < ApplicationController 13 | # ... 14 | def ruby_example_error 15 | INTENTIONAL_RUBY_ERROR 16 | render json: {message: "hello from ruby #{RUBY_VERSION}"} 17 | end 18 | end 19 | ``` 20 | 21 | Here's what the stack trace appears like in the Lambda Console. 22 | 23 | ![](/img/docs/lambda-console-ruby-error.png) 24 | 25 | You keep your mental context in Ruby land the entire time 😁 -------------------------------------------------------------------------------- /docs/_reference/jets-db-generate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets db:generate 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets db:generate 9 | 10 | ## Description 11 | 12 | Creates a migration to change a db table. 13 | 14 | Generates migration in `db/migrate` 15 | 16 | ## Examples 17 | 18 | jets db:generate create_articles title:string user_id:integer 19 | jets db:generate AddTitleBodyToPost title:string body:text published:boolean 20 | 21 | This task delegates to Rails `rails generate migration`. For more examples, refer to the [Active Record Migrations Rails Guide](https://edgeguides.rubyonrails.org/active_record_migrations.html). 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/_reference/jets-runner.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets runner 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets runner 9 | 10 | ## Description 11 | 12 | Run Ruby code in the context of Jets app non-interactively. 13 | 14 | ## Examples 15 | 16 | $ jets runner 'puts "hi"' 17 | hi 18 | $ jets runner 'puts Jets.env' 19 | development 20 | 21 | Using a script in a file. Let's say you have a script: 22 | 23 | script.rb: 24 | 25 | ```ruby 26 | puts "hello world: #{Jets.env}" 27 | ``` 28 | 29 | $ jets runner file://script.rb 30 | hello world: development 31 | 32 | ## Options 33 | 34 | ``` 35 | [--noop], [--no-noop] 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /spec/lib/jets/builders/md5_zip_spec.rb: -------------------------------------------------------------------------------- 1 | require "active_support/number_helper" 2 | 3 | describe Jets::Builders::Md5Zip do 4 | include ActiveSupport::NumberHelper 5 | 6 | let(:instance) { described_class.new(folder) } 7 | let(:folder) { 'test-folder' } 8 | 9 | describe 'initialize' do 10 | it { expect(instance.instance_variable_get(:@path)).to eq("#{Jets.build_root}/#{folder}") } 11 | end 12 | 13 | describe '#number_to_human_size' do 14 | it 'converts file size to human readable number' do 15 | file_size = 25000 16 | expect(instance.send(:number_to_human_size, file_size)).to eq(number_to_human_size(file_size)) 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /lib/jets/resource/s3/bucket.rb: -------------------------------------------------------------------------------- 1 | module Jets::Resource::S3 2 | class Bucket < Jets::Resource::Base 3 | attr_reader :bucket_logical_id 4 | def initialize(props={}) 5 | @props = props # associated_properties from dsl.rb 6 | @bucket_logical_id = props.delete(:logical_id) || "{namespace}_s3_bucket" 7 | end 8 | 9 | def definition 10 | { 11 | bucket_logical_id => { 12 | type: "AWS::S3::Bucket", 13 | properties: @props, 14 | } 15 | } 16 | end 17 | 18 | def outputs 19 | { 20 | bucket_logical_id => "!Ref #{bucket_logical_id.to_s.camelize}", 21 | } 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console:0 */ 2 | // This file is automatically compiled by Webpack and Jets, along with any other files 3 | // present in this directory. You're encouraged to place your actual application logic in 4 | // a relevant structure within app/javascript and only use these pack files to reference 5 | // that code so it'll be compiled. 6 | // 7 | // To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate 8 | // layout file, like app/views/layouts/application.html.erb 9 | 10 | import '../src/application' 11 | import './delete-item' 12 | console.log('Hello World from Webpacker') 13 | -------------------------------------------------------------------------------- /docs/_docs/app-config/filtering_params.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Filtering Params 3 | --- 4 | 5 | By default, all params and event payload will be logged to CloudWatch in every request. You can override this setting with `filtered_parameters` to 6 | filter out sensitive information and mask it as FILTERED within the request log. 7 | 8 | ```ruby 9 | Jets.application.configure do 10 | config.controllers.filtered_parameters += [:password, :credit_card] 11 | end 12 | ``` 13 | 14 | You can also use dot notation for nested parameters 15 | 16 | ```ruby 17 | class PostsController < ApplicationController 18 | config.controllers.filtered_parameters += ["user.password"] 19 | end 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['JETS_TEST'] = "1" 2 | # Ensures aws api never called. Fixture home folder does not contain ~/.aws/credentails 3 | ENV['HOME'] = "spec/fixtures/home" 4 | ENV['JETS_ENV'] = "test" 5 | 6 | # require "simplecov" 7 | # SimpleCov.start 8 | 9 | require "pp" 10 | require "byebug" 11 | require "fileutils" 12 | 13 | require "jets" 14 | Jets.boot 15 | 16 | module Helpers 17 | def payload(name) 18 | JSON.load(IO.read("spec/fixtures/payloads/#{name}.json")) 19 | end 20 | end 21 | 22 | RSpec.configure do |c| 23 | c.before(:suite) do 24 | Aws.config.update(stub_responses: true) 25 | end 26 | c.include Helpers 27 | end 28 | 29 | -------------------------------------------------------------------------------- /lib/jets/resource/iam/managed_policy.rb: -------------------------------------------------------------------------------- 1 | module Jets::Resource::Iam 2 | class ManagedPolicy 3 | extend Memoist 4 | 5 | attr_reader :definitions 6 | def initialize(*definitions) 7 | @definitions = definitions.flatten.compact 8 | end 9 | 10 | def arns 11 | definitions.map { |definition| standardize(definition) } 12 | end 13 | memoize :arns # only process arns once 14 | 15 | # AmazonEC2ReadOnlyAccess => arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess 16 | def standardize(definition) 17 | return definition if definition.include?('iam::aws:policy') 18 | 19 | "arn:aws:iam::aws:policy/#{definition}" 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/fixtures/db_configs/database.single.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: mysql2 3 | encoding: utf8mb4 4 | pool: <%= ENV["DB_POOL"] || 5 %> 5 | database: <%= ENV['DB_NAME'] || 'demo_development' %> 6 | username: <%= ENV['DB_USER'] || 'root' %> 7 | password: <%= ENV['DB_PASS'] %> 8 | host: <%= ENV["DB_HOST"] %> 9 | url: <%= ENV['DATABASE_URL'] %> # takes higher precedence than other settings 10 | 11 | development: 12 | <<: *default 13 | database: <%= ENV['DB_NAME'] || 'demo_development' %> 14 | 15 | test: 16 | <<: *default 17 | database: demo_test 18 | 19 | production: 20 | <<: *default 21 | database: demo_production 22 | url: <%= ENV['DATABASE_URL'] %> 23 | -------------------------------------------------------------------------------- /spec/fixtures/resource_pages/demo-test-api-resources-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Resources: 3 | HiApiResource: 4 | Type: AWS::ApiGateway::Resource 5 | Properties: 6 | ParentId: !Ref RootResourceId 7 | PathPart: hi 8 | RestApiId: !Ref RestApi 9 | Hi1ApiResource: 10 | Type: AWS::ApiGateway::Resource 11 | Properties: 12 | ParentId: !Ref HiApiResource 13 | PathPart: '1' 14 | RestApiId: !Ref RestApi 15 | Parameters: 16 | RestApi: 17 | Type: String 18 | Description: RestApi 19 | RootResourceId: 20 | Type: String 21 | Outputs: 22 | HiApiResource: 23 | Value: !Ref HiApiResource 24 | Hi1ApiResource: 25 | Value: !Ref Hi1ApiResource 26 | -------------------------------------------------------------------------------- /spec/fixtures/resource_pages/demo-test-api-resources-2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Resources: 3 | Hi2ApiResource: 4 | Type: AWS::ApiGateway::Resource 5 | Properties: 6 | ParentId: !Ref HiApiResource 7 | PathPart: '2' 8 | RestApiId: !Ref RestApi 9 | Hi3ApiResource: 10 | Type: AWS::ApiGateway::Resource 11 | Properties: 12 | ParentId: !Ref HiApiResource 13 | PathPart: '3' 14 | RestApiId: !Ref RestApi 15 | Parameters: 16 | RestApi: 17 | Type: String 18 | Description: RestApi 19 | HiApiResource: 20 | Type: String 21 | Outputs: 22 | Hi2ApiResource: 23 | Value: !Ref Hi2ApiResource 24 | Hi3ApiResource: 25 | Value: !Ref Hi3ApiResource 26 | -------------------------------------------------------------------------------- /lib/jets/cfn/builders/rule_builder.rb: -------------------------------------------------------------------------------- 1 | # Implements: 2 | # 3 | # compose 4 | # template_path 5 | # 6 | module Jets::Cfn::Builders 7 | class RuleBuilder < BaseChildBuilder 8 | def compose 9 | add_common_parameters 10 | add_functions 11 | add_resources 12 | add_managed_rules 13 | end 14 | 15 | # Handle config_rules associated with aws managed rules. 16 | # List of AWS Config Managed Rules: https://amzn.to/2BOt9KN 17 | def add_managed_rules 18 | @app_class.managed_rules.each do |rule| 19 | resource = Jets::Resource.new(rule[:definition], rule[:replacements]) 20 | add_resource(resource) 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/extensions/iot_extension.rb: -------------------------------------------------------------------------------- 1 | module IotExtension 2 | def thermostat_rule(logical_id, props={}) 3 | logical_id = "#{logical_id}_topic_rule" 4 | defaults = { 5 | topic_rule_payload: { 6 | sql: "select * from TemperatureTopic where temperature > 60" 7 | }, 8 | actions: [ 9 | lambda: { function_arn: "!Ref {namespace}LambdaFunction" } 10 | ] 11 | } 12 | props = defaults.deep_merge(props) 13 | resource(logical_id, "AWS::Iot::TopicRule", props) 14 | # resource( 15 | # logical_id => { 16 | # type: "AWS::Iot::TopicRule", 17 | # properites: props 18 | # } 19 | # ) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/jets/commands/help/degenerate.md: -------------------------------------------------------------------------------- 1 | This piggy backs off of the [rails scaffold destroy](https://guides.rubyonrails.org/command_line.html#rails-destroy). 2 | 3 | ## Example 4 | 5 | $ jets degenerate scaffold post title:string body:text published:boolean 6 | invoke active_record 7 | remove db/migrate/20190225231821_create_posts.rb 8 | remove app/models/post.rb 9 | invoke resource_route 10 | route resources :posts 11 | invoke scaffold_controller 12 | remove app/controllers/posts_controller.rb 13 | invoke erb 14 | invoke helper 15 | remove app/helpers/posts_helper.rb 16 | $ 17 | -------------------------------------------------------------------------------- /lib/jets/commands/help/import/rack.md: -------------------------------------------------------------------------------- 1 | Imports a generic Rack application into a Jets project and configures it for [Mega Mode](http://rubyonjets.com/docs/megamode/). 2 | 3 | Note, generic rack projects will likely need some adjustments to take into account API Gateway stages and logging. For more info refer to [Mega Mode Considerations](http://rubyonjets.com//megamode-details/). 4 | 5 | ## Example 6 | 7 | jets import:rack http://github.com/tongueroo/jets-mega-rails.git 8 | 9 | ## More Examples 10 | 11 | jets import:rack tongueroo/jets-mega-rails # expands to github 12 | jets import:rack git@github.com:tongueroo/jets-mega-rails.git 13 | jets import:rack /path/to/folder/jets-mega-rails 14 | -------------------------------------------------------------------------------- /lib/jets/internal/app/controllers/jets/bare_controller.rb: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /lib/jets/rdoc.rb: -------------------------------------------------------------------------------- 1 | module Jets 2 | module Rdoc 3 | # Use for both jets.gemspec and rake rdoc task 4 | def options 5 | exclude = %w[ 6 | docs 7 | spec 8 | vendor 9 | core.rb 10 | .js 11 | templates 12 | commands 13 | internal 14 | support 15 | Dockerfile 16 | Dockerfile.base 17 | Gemfile 18 | Gemfile.lock 19 | Guardfile 20 | LICENSE 21 | Procfile 22 | Rakefile 23 | bin 24 | ] 25 | exclude = exclude.map { |word| ['-x', word] }.flatten 26 | ["-m", "README.md", "--markup", "tomdoc"] + exclude 27 | end 28 | extend self 29 | end 30 | end -------------------------------------------------------------------------------- /spec/lib/jets/cfn/builders/api_deployment_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Cfn::Builders::ApiDeploymentBuilder do 2 | let(:builder) do 3 | Jets::Cfn::Builders::ApiDeploymentBuilder.new 4 | end 5 | 6 | describe "ApiDeploymentBuilder" do 7 | it "builds a child stack the deployment" do 8 | builder.compose 9 | # puts builder.text # uncomment to see template text 10 | 11 | resources = builder.template["Resources"] 12 | resource_types = resources.values.map { |i| i["Type"] } 13 | expect(resource_types).to include("AWS::ApiGateway::Deployment") 14 | 15 | expect(builder.template_path).to eq "#{Jets.build_root}/templates/demo-test-api-deployment.yml" 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/fixtures/apps/franky/app/shared/resources/custom.rb: -------------------------------------------------------------------------------- 1 | class Custom < Jets::Stack 2 | resource(:howdy, 3 | type: "AWS::Lambda::Function", 4 | properties: { 5 | function_name: "howdy", 6 | code: { 7 | s3_bucket: "!Ref S3Bucket", 8 | s3_key: code_s3_key 9 | }, 10 | description: "Hello world", 11 | handler: handler("howdy.lambda_handler"), 12 | memory_size: 128, 13 | role: "!Ref IamRole", 14 | runtime: "python3.6", 15 | timeout: 20, 16 | } 17 | ) 18 | 19 | function(:gru, runtime: :ruby, handler: "gru.handle") 20 | 21 | ruby_function(:bob) 22 | python_function(:kevin) 23 | node_function(:stuart) 24 | 25 | output("test") 26 | end 27 | -------------------------------------------------------------------------------- /docs/_docs/custom-resources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Resources 3 | --- 4 | 5 | You can create any custom AWS resources with Jets as a first-class citizen. There are 2 types of custom resources: 6 | 7 | 1. **Associated Custom Resources**: You define these resources above your methods, and they are meant to be associated with the Lambda function below it. 8 | 2. **Shared Custom Resources**: You define these resources in the `app/shared/resources` folder, and they are standalone resources. 9 | 10 | The custom resources are added to the generated AWS CloudFormation templates as part of the build process. The next sections provide an introduction to the core resource modeling behind Jets and examples of the custom resources. 11 | 12 | -------------------------------------------------------------------------------- /lib/jets/builders/util.rb: -------------------------------------------------------------------------------- 1 | module Jets::Builders 2 | module Util 3 | private 4 | def sh(command) 5 | puts "=> #{command}".color(:green) 6 | success = system(command) 7 | unless success 8 | puts "#{command} failed to run.".color(:red) 9 | puts caller[0] 10 | exit 1 11 | end 12 | success 13 | end 14 | 15 | def headline(message) 16 | puts "=> #{message}".color(:cyan) 17 | end 18 | 19 | def build_area 20 | Jets.build_root 21 | end 22 | 23 | def stage_area 24 | "#{build_area}/stage" 25 | end 26 | 27 | def cache_area 28 | "#{build_area}/cache" # cleaner to use full path for this setting 29 | end 30 | end 31 | end -------------------------------------------------------------------------------- /docs/_docs/local-server.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Local Server 3 | --- 4 | 5 | To speed up development, you can run a local server which mimics API Gateway. Test your application code locally and then deploy to AWS when ready. 6 | 7 | jets server 8 | 9 | You can test your app at [http://localhost:8888](http://localhost:8888). Here's a curl command to create a post: 10 | 11 | curl -X POST http://localhost:8888/posts \ 12 | -H 'Content-Type: application/json' \ 13 | -d '{ 14 | "post": { 15 | "title": "My Test Post 1", 16 | "desc": "test desc", 17 | } 18 | } 19 | ' 20 | 21 | You can find examples of all the CRUD actions at [Jets CRUD Tutorials]({% link _docs/tutorials.md %}). 22 | 23 | -------------------------------------------------------------------------------- /docs/_sass/cta.scss: -------------------------------------------------------------------------------- 1 | // Styling for the call to action section 2 | section.cta { 3 | padding: 50px 0; 4 | text-align: center; 5 | margin: 0 auto; 6 | background-position: center; 7 | background-color: #730c0c; 8 | @include background-cover; 9 | .cta-content { 10 | h2 { 11 | text-align: center; 12 | margin: 0 auto 25px auto; 13 | font-size: 50px; 14 | font-weight: 200; 15 | max-width: 450px; 16 | color: white; 17 | border: none; 18 | } 19 | @media (min-width: 768px) { 20 | h2 { 21 | text-align: center; 22 | margin: 0 auto; 23 | font-size: 80px; 24 | border: none; 25 | font-weight: 200; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/jets/commands/markdown/index.rb: -------------------------------------------------------------------------------- 1 | module Jets::Commands::Markdown 2 | class Index 3 | def path 4 | "docs/reference.md" 5 | end 6 | 7 | def command_list 8 | commands = Jets::Commands::Base.namespaced_commands.sort.reject {|c| c.include?('help') } 9 | commands.map do |full_command| 10 | # Example: [jets deploy]({% link _reference/jets-deploy.md %}) 11 | link = full_command.gsub(':','-') 12 | "* [jets #{full_command}]({% link _reference/jets-#{link}.md %})" 13 | end.join("\n") 14 | end 15 | 16 | def doc 17 | <<-EOL 18 | --- 19 | title: CLI Reference 20 | --- 21 | {% include reference.md %} 22 | 23 | #{command_list} 24 | EOL 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/lib/jets/cfn/builders/job_builder_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Cfn::Builders::JobBuilder do 2 | let(:builder) do 3 | Jets::Cfn::Builders::JobBuilder.new(HardJob) 4 | end 5 | 6 | describe "compose" do 7 | it "builds a child stack with the scheduled events" do 8 | builder.compose 9 | # puts builder.text # uncomment to see template text 10 | 11 | resources = builder.template["Resources"] 12 | expect(resources).to include("DigLambdaFunction") 13 | expect(resources).to include("DigPermission") 14 | expect(resources).to include("LiftEventsRule") 15 | 16 | expect(builder.template_path).to eq "#{Jets.build_root}/templates/demo-test-app-hard_job.yml" 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /spec/lib/jets/middleware_spec.rb: -------------------------------------------------------------------------------- 1 | class MiddlewareTestClass 2 | include Jets::Middleware 3 | end 4 | 5 | describe Jets::Middleware do 6 | let(:env) do 7 | event = json_file("spec/fixtures/dumps/api_gateway/posts/index.json") 8 | context = nil 9 | env = Jets::Controller::Rack::Env.new(event, context).convert 10 | route = Jets::Controller::Middleware::Local::RouteMatcher.new(env).find_route 11 | mimic = Jets::Controller::Middleware::Local::MimicAwsCall.new(route, env) 12 | env.merge!(mimic.vars) 13 | env 14 | end 15 | 16 | context "middleware" do 17 | it "call" do 18 | status, headers, body = MiddlewareTestClass.new.call(env) 19 | expect(status).to eq "200" 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/jets/middleware/layer.rb: -------------------------------------------------------------------------------- 1 | module Jets::Middleware 2 | class Layer 3 | attr_reader :args, :block, :klass 4 | 5 | def initialize(klass, args, block) 6 | @klass = klass 7 | @args = args 8 | @block = block 9 | end 10 | 11 | def name; klass.name; end 12 | 13 | def ==(middleware) 14 | case middleware 15 | when Layer 16 | klass == middleware.klass 17 | when Class 18 | klass == middleware 19 | end 20 | end 21 | 22 | def inspect 23 | if klass.is_a?(Class) 24 | klass.to_s 25 | else 26 | klass.class.to_s 27 | end 28 | end 29 | 30 | def build(app) 31 | klass.new(app, *args, &block) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /spec/fixtures/dumps/logs/log_event.json: -------------------------------------------------------------------------------- 1 | { 2 | "awslogs": { 3 | "data": "H4sIAGPuZFwAA61SXY/SQBT9K83ER2pn7nzzVkJdVwEN7WYftsRM6YCNLcW2gEj4705xN2yiJms083Jzzsy55565J1TZtjVrmxy3Fg3ROEzCT9MojsObCA1QfdjYxsGEAFDKGOdCOLis1zdNvds6JjCHNihNleUm+GzLsv5Jx11jTeV4wEQHGALCgodXkzCJ4mRBLcYYhMkwFWy5IgYruTKgNNF5JlbaSbS7rF02xbYr6s2bouxs06LhA8ptVfu53fuTev2uznx+f/8ez2AKah76c7utmy7+5aWfjKaT8I7g2W3yFi0u/qK93XS95AkVubNJGRdKcglSUCw0BayIdEdJLbFkkmJGGFZUc0LdRAyUFFzoPoyucBF2pnJpEM4xIaJXInLwFK2TvyTjHeqmzNMNOg/+rat8YVfbD+mdUvTFHkmKhinam3JnXTm4YHDF4AmjV8yV59+71UpLygFzJRQWRIEW3LGcSQWOUFoDEPedgoCQ7E9uhVTP3UazsTe3X3fu4m0+9NiSaMUw9YnRzGcgM1/nyvqMG8BLt1YA5j+44y90N48+fpgnf22wG+8a06/i0COSvpbUq9q0GxVlaXPvygHGjvDSbuoWvDl6cfHduhegvOnIgeab90jctda15vyC9+Mvzj8ACHlavMMDAAA=" 4 | } 5 | } -------------------------------------------------------------------------------- /spec/lib/jets/functions/base_path_spec.rb: -------------------------------------------------------------------------------- 1 | require "ostruct" 2 | require "render_me_pretty" 3 | 4 | code = RenderMePretty.result("./lib/jets/internal/app/functions/jets/base_path.rb", stage_name: "test") 5 | # Hack to mimic lambda 6 | eval %Q{ 7 | class MainScope 8 | #{code} 9 | end 10 | } 11 | 12 | describe "base_path" do 13 | before do 14 | allow(CfnResponse).to receive(:new).and_return(null) 15 | end 16 | let(:event) { null } 17 | let(:context) { null } 18 | let(:null) { double(:null).as_null_object } 19 | 20 | let(:main) do 21 | MainScope.new 22 | end 23 | 24 | # mainly test for silly syntax errors 25 | it "BasePathMapping" do 26 | main.lambda_handler(event: event, context: context) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /docs/vendor/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /spec/lib/jets/cfn/builders/rule_builder_spec.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Cfn::Builders::RuleBuilder do 2 | let(:builder) do 3 | Jets::Cfn::Builders::RuleBuilder.new(GameRule) 4 | end 5 | 6 | describe "compose" do 7 | it "builds a child stack with the scheduled events" do 8 | builder.compose 9 | # puts builder.text # uncomment to see template text 10 | 11 | resources = builder.template["Resources"] 12 | expect(resources).to include("ProtectLambdaFunction") 13 | expect(resources).to include("ProtectPermission") 14 | expect(resources).to include("ProtectConfigRule") 15 | 16 | expect(builder.template_path).to eq "#{Jets.build_root}/templates/demo-test-app-game_rule.yml" 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /docs/_docs/database/dynamodb.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Database DynamoDB 3 | --- 4 | 5 | Jets supports DynamoDB via [Dynomite](https://github.com/tongueroo/dynomite). 6 | 7 | ## Migrations 8 | 9 | Here's an example of creating migrations: 10 | 11 | jets dynamodb:generate create_posts # generates migration 12 | jets dynamodb:migrate dynamodb/migrate/20171112194549-create_posts_migration.rb # run migration. replace with your timestamp 13 | 14 | If you are using DynamoDB it can be useful to use DynamoDB Local, just like you would use a local SQL server. It's simply a jar file you download and run. Here's a [DynamoDB Local Setup Walkthrough](https://github.com/boltops-tools/jets/wiki/Dynamodb-Local-Setup-Walkthrough) that takes about 5 minutes. 15 | 16 | -------------------------------------------------------------------------------- /docs/_docs/next-steps.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Next Steps 3 | --- 4 | 5 | Hopefully, you have a good feel for how Jets works now. From here, there are a few resources that can help you continue along: 6 | 7 | * Check out the [Jets](https://github.com/boltops-tools/jets) repo on GitHub 8 | * ⭐️ the Jets project on GitHub 9 | * Write a blog post about Jets 10 | * Post on your favorite discussion about Jets 11 | * Contribute a pull request 12 | 13 | Everyone can contribute to making jets better, including the documentation. These docs are the jets repo located the [docs folder](https://github.com/boltops-tools/jets/tree/master/docs). Please fork the project and open a pull request! We love your pull requests. Contributions are encouraged and welcomed! 14 | 15 | -------------------------------------------------------------------------------- /spec/fixtures/db_configs/database.multi.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: mysql2 3 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 4 | timeout: 5000 5 | encoding: utf8mb4 6 | 7 | test: 8 | primary: 9 | <<: *default 10 | database: my_primary_database 11 | user: root 12 | primary_replica: 13 | <<: *default 14 | database: my_primary_database 15 | user: root # user: root_readonly 16 | replica: true 17 | animals: 18 | <<: *default 19 | database: my_animals_database 20 | user: root # user: animals_root 21 | migrations_paths: db/animals_migrate 22 | animals_replica: 23 | <<: *default 24 | database: my_animals_database 25 | user: root # user: animals_readonly 26 | replica: true 27 | -------------------------------------------------------------------------------- /lib/jets/commands/help/routes.md: -------------------------------------------------------------------------------- 1 | ## Example 2 | 3 | $ jets routes 4 | +--------+----------------+--------------------+ 5 | | Verb | Path | Controller#action | 6 | +--------+----------------+--------------------+ 7 | | GET | posts | posts#index | 8 | | GET | posts/new | posts#new | 9 | | GET | posts/:id | posts#show | 10 | | POST | posts | posts#create | 11 | | GET | posts/:id/edit | posts#edit | 12 | | PUT | posts/:id | posts#update | 13 | | DELETE | posts/:id | posts#delete | 14 | | ANY | *catchall | jets/public#show | 15 | +--------+----------------+--------------------+ 16 | $ -------------------------------------------------------------------------------- /spec/lib/jets/resource/api_gateway/rest_api/routes/change_detection.rb: -------------------------------------------------------------------------------- 1 | describe Jets::Resource::ApiGateway::RestApi do 2 | let(:detection) { Jets::Resource::ApiGateway::RestApi::ChangeDetection.new } 3 | 4 | context "general" do 5 | it "default binary media type" do 6 | expect(detection.new_binary_media_types).to eq ["multipart/form-data"] 7 | end 8 | end 9 | 10 | # TODO: have a spec in place right now for basic syntax checking. Eventually add 11 | # more specs in the future. 12 | # context "changes detected" do 13 | # it "reuses the existing rest api logical id" do 14 | # end 15 | # end 16 | 17 | # context "no changes detected" do 18 | # it "updates the rest api logical id" do 19 | # end 20 | # end 21 | end 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | about: Found a typo or something that isn't crystal clear in the docs? 4 | title: '' 5 | labels: docs 6 | assignees: '' 7 | 8 | --- 9 | 10 | 17 | 18 | ## Motivation 19 | 20 | 21 | 22 | 23 | ## Suggestion 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /backers.md: -------------------------------------------------------------------------------- 1 |

Backers

2 | 3 | [Jets](http://rubyonjets.com/) is an MIT-licensed open source project. It's an independent project with its ongoing development made possible entirely thanks to the support by these awesome [backers](https://github.com/tongueroo/jets/blob/master/backers.md). If you'd like to join them, please consider: 4 | 5 | - [Become a backer or sponsor on Patreon](https://www.patreon.com/tongueroo). 6 | 7 | Funds donated via Patreon go directly to support Tung Nguyen's full-time work on Jets. 8 | 9 |

10 | 11 |

Backers via Patreon

12 | 13 | 14 | - Erlend Finvåg 15 | - Nate Clark 16 | - Hirokatsu Endo 17 | - Michael Choi 18 | - Phan Lam 19 | - Theron Welch 20 | 21 | -------------------------------------------------------------------------------- /docs/_docs/debugging/payloads.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Debugging Event Payloads 3 | --- 4 | 5 | Here are examples of event payloads for a typical CRUD controller. You must always specify the `path` key. 6 | 7 | Action | Payload | Notes 8 | --- | --- | --- 9 | posts#index | `{"path": "/posts"}` | Path is always required. 10 | posts#new | `{"path": "/posts/new"}` | The new action uses the path to generate the new form. 11 | posts#show | `{"path": "/posts/123"}` | The post id must be provided and exist in the database or you'll get a "Couldn't find Post without an ID" error. 123 is an example. 12 | posts#edit | `{"path": "/posts/123/edit", "pathParameters": {"id": "123"}}` | You will also need pathParameters because that's how the controller gets the id parameter. 13 | 14 | -------------------------------------------------------------------------------- /docs/_reference/jets-build.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets build 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets build 9 | 10 | ## Description 11 | 12 | Builds and packages project for AWS Lambda. 13 | 14 | Builds a zip file package to be uploaded to AWS Lambda. This allows you to build the project without deploying and inspect the zip file that gets deployed to AWS Lambda. The package contains: 15 | 16 | * your application code 17 | * generated shims 18 | 19 | If the application has no Ruby code and only uses Polymorphic functions, then gems are not bundled up. 20 | 21 | ## Options 22 | 23 | ``` 24 | [--templates], [--no-templates] # Only build the CloudFormation templates. Skip code building 25 | [--noop], [--no-noop] 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Have any questions about how Jets works? 4 | title: '' 5 | labels: 'question' 6 | assignees: '' 7 | 8 | --- 9 | 10 | The Jets issue tracker IS NOT for usage questions! Please post your question on our dedicated forum at https://community.rubyonjets.com 11 | 12 | To be sensitive to everyone's time, we may close issues asking questions without comment. If you repeatedly post questions in the issues tracker, you may be blocked from ever submitting issues to Jets again. Please use your best judgment. 👍 13 | 14 | Posting your questions in the Jets community forum benefits others by grouping questions in a dedicated place. Here are some additional options also http://rubyonjets.com/docs/support/ 😁 15 | -------------------------------------------------------------------------------- /docs/_reference/jets-clean-build.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: jets clean:build 3 | reference: true 4 | --- 5 | 6 | ## Usage 7 | 8 | jets clean:build 9 | 10 | ## Description 11 | 12 | Cleans jets build. 13 | 14 | Removes the build files that jets creates. Essentially, deletes `/tmp/jets`. This will remove all build files for all jets projects. This is safe as jets uses `/tmp/jets` merely as a cache to speed up incrementally builds. Cleaning this out can clean up cruft in the `/tmp/jets` directory that builds over time. 15 | 16 | ## Example 17 | 18 | jets clean:build 19 | 20 | ## Options 21 | 22 | ``` 23 | [--noop], [--no-noop] # noop or dry-run mode 24 | [--mute], [--no-mute] # mute output 25 | [--sure], [--no-sure] # bypass are you sure prompt 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /lib/jets/router/helpers/core_helper.rb: -------------------------------------------------------------------------------- 1 | module Jets::Router::Helpers 2 | module CoreHelper 3 | extend ActiveSupport::Concern 4 | 5 | # Used for form_for helper 6 | def polymorphic_path(record, _) 7 | url_for(record) 8 | end 9 | 10 | # override helper delegates to point to jets controller 11 | # TODO: params is weird 12 | CONTROLLER_DELEGATES = %w[session response headers] 13 | CONTROLLER_DELEGATES.each do |meth| 14 | define_method meth do 15 | @_jets[:controller].send(meth) 16 | end 17 | end 18 | 19 | class_methods do 20 | def define_helper_method(name) 21 | define_method(name) do 22 | @_jets[:controller].send(name) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /docs/_docs/extras/custom-inflections.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Inflections 3 | --- 4 | 5 | Jets lookups folders, files, and classes based on naming conventions. It singularizes or pluralizes words as a part of this naming convention. For example: 6 | 7 | controller | model | views folder 8 | --- | --- | --- 9 | PostsController | Post | app/views/posts 10 | ToysController | Toy | app/views/toys 11 | 12 | Sometimes you might want to override the grammatical inflections. You can do this by configuring a `config/inflections.yml` with your own custom inflections. Example: 13 | 14 | config/inflections.yml: 15 | 16 | ```yaml 17 | octopus: octopi 18 | person: people 19 | hi: hi 20 | ``` 21 | 22 | This changes the singularization and pluralization of words to fit your needs. 23 | 24 | -------------------------------------------------------------------------------- /.cody/docs/bin/subnav.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | cd docs 4 | # Unsure why but if cli_docs.sh runs bundle first, then bundle wont use the right bundler file 5 | export BUNDLE_GEMFILE=$(pwd)/Gemfile 6 | bundle 7 | bundle exec jekyll serve --detach 8 | 9 | # Error: front_matter_parser-0.2.1/lib/front_matter_parser/syntax_parser/multi_line_comment.rb:19:in `match': invalid byte sequence in US-ASCII (ArgumentError) 10 | # Workaround: https://stackoverflow.com/questions/17031651/invalid-byte-sequence-in-us-ascii-argument-error-when-i-run-rake-dbseed-in-ra 11 | export RUBYOPT="-KU -E utf-8:utf-8" # fixes front_matter_parser error within the `jekyll-sort reorder` call 12 | 13 | gem install jekyll-sort 14 | jekyll-sort reorder # Updates nav_order front matter of pages that are in the nav 15 | -------------------------------------------------------------------------------- /lib/jets/mega/hash_converter.rb: -------------------------------------------------------------------------------- 1 | # Thanks https://mensfeld.pl/2012/01/converting-nested-hash-into-http-url-params-hash-version-in-ruby/ 2 | module Jets::Mega 3 | module HashConverter 4 | def self.encode(value, key = nil, out_hash = {}) 5 | case value 6 | when Hash then 7 | value.each { |k,v| encode(v, append_key(key,k), out_hash) } 8 | out_hash 9 | when Array then 10 | value.each { |v| encode(v, "#{key}[]", out_hash) } 11 | out_hash 12 | when nil then '' 13 | else 14 | out_hash[key] = value 15 | out_hash 16 | end 17 | end 18 | 19 | private 20 | 21 | def self.append_key(root_key, key) 22 | root_key.nil? ? :"#{key}" : :"#{root_key}[#{key.to_s}]" 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /lib/jets/commands/help/status.md: -------------------------------------------------------------------------------- 1 | The CloudFormation stack status info. Essentially the events of the CloudFormation stack since the last update. If the CloudFormation stack is currently updating, this will live tail the events logs. 2 | 3 | ## Example 4 | 5 | $ jets status 6 | The current status for the stack demo-dev is UPDATE_COMPLETE 7 | Stack events: 8 | 05:21:42AM UPDATE_IN_PROGRESS AWS::CloudFormation::Stack demo-dev User Initiated 9 | 05:21:45AM CREATE_IN_PROGRESS AWS::CloudFormation::Stack ApiGateway 10 | ... 11 | 05:23:22AM CREATE_COMPLETE AWS::CloudFormation::Stack JetsPreheatJob 12 | 05:23:25AM UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack demo-dev 13 | 05:23:25AM UPDATE_COMPLETE AWS::CloudFormation::Stack demo-dev 14 | $ --------------------------------------------------------------------------------