jets 5.0.0.beta1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4381b93c9ea3d4e8a1f44bbe065e85fc0c6da59cc1d59ef7cc3deb29411b107f
4
- data.tar.gz: 6afa841f9b10dcf4526179ddfe5dd9d211ce38d9117f2442b092bb1f8d2bc424
3
+ metadata.gz: 54e94ceb6d67976943a212a5ccceb71bb3e7bd6c6928775c0e7b824be127e42d
4
+ data.tar.gz: cab6dba2a8108c047daec4706e15d226e0e7f4eb46e9b6f2617465ea186b451e
5
5
  SHA512:
6
- metadata.gz: 64cc06c217190f64c0e5e446bd6aad780048c5673f64f6611bc3871ecfc295083440be55d98d222d5955d19285ba3252cb371043f679d48e74b6a676541ce3df
7
- data.tar.gz: 8be226ddfa30be1b57dca669eff636b9e07a0ab8bc63e77901a1f398e2c9ab7cbc7a9f6589a6e98135f4abffc5492777e0cda9543d5c598fda1d77dbcfb0658a
6
+ metadata.gz: c050d7738b47e826403bc383baa0b2db251246b3d3dc359135e8e1039f8404448021477b38fbfab57f2be1cd09f7ffe8aa925cff70e313a96e61735f46f4fee2
7
+ data.tar.gz: 152c89e1b3e9d124f63687181f48c13ef09e3140062665a6b11baf9a99e830869cd7c8df46a2e1e8e59c58bc08bbb76d6430d235fd296ed176bcf0628890531a
data/CHANGELOG.md CHANGED
@@ -3,7 +3,7 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
5
5
 
6
- ## [5.0.0] - Unreleased
6
+ ## [5.0.0] - 2023-12-05
7
7
  Single Lambda Function for Controllers
8
8
  * For controllers, a single Lambda function is deployed going forward.
9
9
  * APIGW serves as proxy endpoint for requests to the single Lambda function. Techniquely, there are 2 APIGW endpoints.
@@ -55,10 +55,13 @@ Breaking changes:
55
55
  * Jets.config.prewarm.concurrency option removed.
56
56
  * dynomite decoupling and integration improvements
57
57
 
58
+ ## [4.0.10] - 2023-12-04
59
+ - [#678](https://github.com/boltops-tools/jets/pull/678) handle option method or http_method from route state
58
60
 
59
61
  ## [4.0.9] - 2023-12-03
60
62
  - [#674](https://github.com/boltops-tools/jets/pull/674) Fix broken --mode jobs new project generation
61
63
  - [#675](https://github.com/boltops-tools/jets/pull/675) Add resource tags to CloudFormation stack
64
+
62
65
  ## [4.0.8] - 2023-12-03
63
66
  - [#677](https://github.com/boltops-tools/jets/pull/677) pin dynomite 1.2.7
64
67
 
data/README.md CHANGED
@@ -16,12 +16,13 @@ Please **watch/star** this repo to help grow and support the project.
16
16
 
17
17
  ## What is Ruby on Jets?
18
18
 
19
- Jets is a Ruby Serverless Framework. Jets 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.
19
+ Jets is a Ruby Serverless Framework. Jets allows you to create serverless applications with a beautiful language: Ruby. It includes everything required to build and deploy an application to AWS Lambda.
20
20
 
21
- It is key to understand AWS Lambda and API Gateway to understand Jets conceptually. Jets maps your code to Lambda functions and API Gateway resources.
21
+ Understanding AWS Lambda and API Gateway is key to understanding Jets conceptually. Jets map your code to Lambda functions and other AWS Resources like API Gateway and Event Rules.
22
22
 
23
- * **AWS Lambda** is Functions as a Service. It allows you to upload and run functions without worrying about the underlying infrastructure.
23
+ * **AWS Lambda** is functions as a service. It allows you to upload and run functions without worrying about the underlying infrastructure.
24
24
  * **API Gateway** is the routing layer for Lambda. It is used to route REST URL endpoints to Lambda functions.
25
+ * **EventBridge Rules** are events as a service. You can automatically run Lambda functions triggered from AWS services. You decide what events to catch and how to react to them.
25
26
 
26
27
  The official documentation is at [Ruby on Jets](http://rubyonjets.com).
27
28
 
@@ -42,14 +43,14 @@ end
42
43
 
43
44
  Here's the function in the Lambda console:
44
45
 
45
- ![Code Example in AWS Lambda console](https://raw.githubusercontent.com/tongueroo/jets/master/docs/img/docs/jets-simple-lambda-function-console.png)
46
+ ![Code Example in AWS Lambda console](https://img.boltops.com/tools/jets/readme/simple-lambda-function.png)
46
47
 
47
48
 
48
- Though simple functions are supported by Jets, they do not add much value as other ways to write Ruby code with Jets. Classes like [Controllers](http://rubyonjets.com/docs/controllers/) and [Jobs](http://rubyonjets.com/docs/jobs/) add many conveniences and are more powerful to use. We’ll cover them next.
49
+ Though simple functions are supported by Jets, they do not add as much value as other ways to write Ruby code with Jets. Classes like [Controllers](http://rubyonjets.com/docs/controllers/) and [Jobs](http://rubyonjets.com/docs/jobs/) add many conveniences and are more powerful to use. We’ll cover them next.
49
50
 
50
51
  ### Jets Controllers
51
52
 
52
- A Jets controller handles a web request and renders a response. Here's an example:
53
+ A Jets controller handles a web request and renders a response. Here's an example:
53
54
 
54
55
  app/controllers/posts_controller.rb:
55
56
 
@@ -69,11 +70,9 @@ class PostsController < ApplicationController
69
70
  end
70
71
  ```
71
72
 
72
- Helper methods like `params` provide the parameters from the API Gateway event. The `render` method renders a Lambda Proxy structure back that API Gateway understands.
73
+ Helper methods like `params` provide the parameters from the API Gateway event. The `render` method returns a Lambda Proxy structure that API Gateway understands.
73
74
 
74
- Jets creates Lambda functions for each public method in your controller. Here they are in the Lambda console:
75
-
76
- ![Lambda Functions for each public method in AWS Console](https://raw.githubusercontent.com/tongueroo/jets/master/docs/img/docs/demo-lambda-functions-controller.png)
75
+ Jets creates single Lambda functions to handle your Jets Controller requests. The Lambda Function handler is a shim that routes to your controller action.
77
76
 
78
77
  ### Jets Routing
79
78
 
@@ -83,23 +82,14 @@ config/routes.rb:
83
82
 
84
83
  ```ruby
85
84
  Jets.application.routes.draw do
86
- get "posts", to: "posts#index"
87
- get "posts/new", to: "posts#new"
88
- get "posts/:id", to: "posts#show"
89
- post "posts", to: "posts#create"
90
- get "posts/:id/edit", to: "posts#edit"
91
- put "posts", to: "posts#update"
92
- delete "posts", to: "posts#delete"
93
-
94
- resources :comments # expands to the RESTful routes above
95
-
85
+ resources :posts
96
86
  any "posts/hot", to: "posts#hot" # GET, POST, PUT, etc request all work
97
87
  end
98
88
  ```
99
89
 
100
90
  The `routes.rb` gets translated to API Gateway resources:
101
91
 
102
- ![API Gateway Resources generated from routes in AWS console](https://raw.githubusercontent.com/tongueroo/jets/master/docs/img/quick-start/demo-api-gateway.png)
92
+ ![API Gateway Resources generated from routes in AWS console](https://img.boltops.com/tools/jets/readme/apigw.png)
103
93
 
104
94
  Test your API Gateway endpoints with curl or postman. Note, replace the URL endpoint with the one that is created:
105
95
 
@@ -111,7 +101,7 @@ Test your API Gateway endpoints with curl or postman. Note, replace the URL endp
111
101
 
112
102
  ### Jets Jobs
113
103
 
114
- A Jets job handles asynchronous background jobs performed outside of the web request/response cycle. Here's an example:
104
+ A Jets job handles asynchronous background jobs outside the web request/response cycle. Here's an example:
115
105
 
116
106
  app/jobs/hard_job.rb:
117
107
 
@@ -129,9 +119,13 @@ class HardJob < ApplicationJob
129
119
  end
130
120
  ```
131
121
 
132
- `HardJob#dig` runs every 10 hours and `HardJob#lift` runs every 12 hours. The `rate` and `cron` methods created CloudWatch Event Rules. Example:
122
+ ![Jets Jobs in AWS Lambda Console](https://img.boltops.com/tools/jets/readme/jets-jobs.png)
123
+
124
+ `HardJob#dig` runs every 10 hours, and `HardJob#lift` runs every 12 hours. The `rate` and `cron` methods created CloudWatch Event Rules. Example:
125
+
126
+ ![CloudWatch Event Rules in AWS Console](https://img.boltops.com/tools/jets/readme/jets-jobs-event-rules.png)
133
127
 
134
- ![CloudWatch Event Rules in AWS Console](https://raw.githubusercontent.com/tongueroo/jets/master/docs/img/docs/demo-job-cloudwatch-rule.png)
128
+ This simple example uses Scheduled Events. There are many more possibilities, see the [Events Docs](https://docs.rubyonjets.com/docs/events/).
135
129
 
136
130
  ### Jets Deployment
137
131
 
@@ -141,29 +135,19 @@ You can test your application with a local server that mimics API Gateway: [Jets
141
135
 
142
136
  After deployment, you can test the Lambda functions with the AWS Lambda console or the CLI.
143
137
 
144
- ### AWS Lambda Console
145
-
146
- ![Lambda Console](https://s3.amazonaws.com/boltops-demo/images/screenshots/lambda-console-posts-controller-index.png)
147
-
148
138
  ### Live Demos
149
139
 
150
140
  Here are some demos of Jets applications:
151
141
 
152
142
  * [Quintessential CRUD Jets app](https://demo.rubyonjets.com/)
153
143
  * [API Demo](https://api.demo.rubyonjets.com/)
154
- * [Jets Afterburner: Easy Rails Support](https://afterburner.demo.rubyonjets.com/)
155
- * [Mega Mode: Jets and Rails Combined](https://mega.demo.rubyonjets.com/)
156
144
  * [Image Upload with CarrierWave](https://upload.demo.rubyonjets.com/)
157
145
 
158
- Please feel free to add your own example to the [jets-examples](https://github.com/tongueroo/jets-examples) repo.
159
-
160
- ### Rails Support
161
-
162
- [Jets Afterburner Mode](http://rubyonjets.com/docs/rails-support/) provides Rails support with little effort. This allows you to run a Rails application on AWS Lambda. Also here's a Tutorial Blog Post: [Jets Afterburner: Rails Support](https://blog.boltops.com/2018/12/21/jets-afterburner-serverless-rails-on-aws-lambda-in-5-minutes).
146
+ Please feel free to add your examples to the [rubyonjets/examples](https://github.com/rubyonjets/examples) repo.
163
147
 
164
148
  ### More Info
165
149
 
166
- For more documentation, check out the official docs: [Ruby on Jets](http://rubyonjets.com/). Here's a list of useful links:
150
+ For more documentation, check out the official docs: [Ruby on Jets](http://rubyonjets.com/). Here's a list of useful links:
167
151
 
168
152
  * [Quick Start](http://rubyonjets.com/quick-start/)
169
153
  * [Local Jets Server](http://rubyonjets.com/docs/local-server/)
@@ -233,7 +233,7 @@ module Jets::Builders
233
233
  # Checking this way because when using jets standalone for Afterburner mode we don't want to run into
234
234
  # bundler gem collisions. TODO: figure out the a better way to handle the collisions.
235
235
  lines = IO.readlines("#{Jets.root}/Gemfile")
236
- lines.detect { |l| l =~ /#{name}/ }
236
+ lines.detect { |l| l =~ /#{name}/ && l !~ /\s.*#/ }
237
237
  end
238
238
 
239
239
  # Cleans out non-cached files like code-*.zip in Jets.build_root
@@ -8,7 +8,7 @@ def lambda_handler(event:, context:)
8
8
  return
9
9
  end
10
10
 
11
- <% if @vars.process_type == "controller" -%>
11
+ <% if @vars.process_type == "controller" -%>
12
12
  route = Jets::Router.find_route_by_event(event)
13
13
  controller = route.controller_name
14
14
  action = route.action_name
@@ -14,8 +14,9 @@ class Jets::Cfn::Resource::ApiGateway::RestApi::Routes::Change
14
14
  return [] if data.nil?
15
15
 
16
16
  data.map do |item|
17
+ http_method = item.dig('options','method') || item.dig('options','http_method')
17
18
  Jets::Router::Route.new(
18
- http_method: item['http_method'],
19
+ http_method: http_method,
19
20
  path: item['path'],
20
21
  to: item['to'],
21
22
  engine: item['engine'],
@@ -5,13 +5,19 @@ class Jets::Cfn::Resource::ApiGateway::RestApi::Routes
5
5
 
6
6
  def changed?
7
7
  return false unless parent_stack_exists?
8
- return false if Jets.config.cfn.build.routes == "one_apigw_method_for_all_routes"
8
+ return true if reset?
9
+
9
10
  # Note: Variable.changed? will likely always true in one_apigw_method_for_all_routes mode
10
- # since parent variables are allowed to vary.
11
+ # since parent variables are allowed to vary in Jets v5.
12
+ if Jets.config.cfn.build.routes == "one_apigw_method_for_all_routes"
13
+ MediaTypes.changed? || To.changed?
14
+ else
15
+ MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed?
16
+ end
17
+ end
11
18
 
12
- # JETS_REPLACE_API is legacy. JETS_API_REPLACE is the new var
13
- MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed? ||
14
- ENV['JETS_RESET'] || ENV['JETS_API_REPLACE'] || ENV['JETS_REPLACE_API']
19
+ def reset?
20
+ ENV['JETS_RESET'] || ENV['JETS_API_REPLACE'] || ENV['JETS_REPLACE_API']
15
21
  end
16
22
 
17
23
  def parent_stack_exists?
@@ -1,6 +1,6 @@
1
1
  module Jets::Command
2
2
  class ReleasesCommand < Base # :nodoc:
3
- desc "history", "List deploy history"
3
+ desc "history", "List releases"
4
4
  long_desc Help.text(:history)
5
5
  paging_options(order: 'desc').call
6
6
  def perform
data/lib/jets/core.rb CHANGED
@@ -88,7 +88,13 @@ module Jets::Core
88
88
  def parsed_project_name
89
89
  lines = IO.readlines("#{Jets.root}/config/application.rb")
90
90
  project_name_line = lines.find { |l| l =~ /config\.project_name.*=/ && l !~ /^\s+#/ }
91
- project_name_line.gsub(/.*=/,'').strip.gsub(/["']/,'') if project_name_line
91
+ if project_name_line
92
+ parsed = project_name_line.gsub(/.*=/,'').strip
93
+ # The +? makes it non-greedy
94
+ # See: https://ruby-doc.org/core-2.5.1/Regexp.html#class-Regexp-label-Repetition
95
+ md = parsed.match(/['"](.+?)['"]/)
96
+ md ? md[1] : raise("Unable to parse project name from config/application.rb: #{project_name_line}")
97
+ end
92
98
  end
93
99
  memoize :parsed_project_name
94
100
 
@@ -45,6 +45,9 @@ class Jets::Dotenv
45
45
  rescue Aws::SSM::Errors::ParameterNotFound
46
46
  @missing << [key, value, name]
47
47
  ''
48
+ rescue Aws::SSM::Errors::ValidationException
49
+ puts "ERROR: Invalid SSM parameter name: #{name.inspect}".color(:red)
50
+ raise
48
51
  end
49
52
 
50
53
  def ssm_name(key, value)
@@ -56,7 +56,6 @@ module Jets::Generators::Overrides::App
56
56
  end
57
57
 
58
58
  def copy_project
59
- # directory ".", project_folder, copy_options
60
59
  directory ".", ".", copy_options
61
60
  end
62
61
 
@@ -69,9 +68,6 @@ module Jets::Generators::Overrides::App
69
68
  excludes.uniq!
70
69
 
71
70
  unless @database
72
- # Do not even generate the config/database.yml because
73
- # Jets webpacker:install bombs and tries to load the db since it sees a
74
- # config/database.yml but there's no database pg gem configured.
75
71
  excludes += %w[
76
72
  database.yml
77
73
  db
@@ -0,0 +1,10 @@
1
+ # Variables in here are available and shared across all environments: development, production, etc
2
+ # Docs: https://docs.rubyonjets.com/docs/env-files/
3
+
4
+ # Examples:
5
+ # DATABASE_URL="mysql2://user:pass@host.com/db_name?pool=5" # raw value as-is
6
+ # SSM can be use to reference a parameter store value
7
+ # DATABASE_URL=SSM # conventionally references /PROJECT_NAME/JETS_ENV/DATABASE_URL
8
+ # DATABASE_URL=SSM # /demo/development/DATABASE_URL
9
+ # DATABASE_URL=SSM:database-url # /demo/development/database-url
10
+ # DATABASE_URL=SSM:/path/to/database-url # /path/to/database-url
@@ -32,7 +32,7 @@ module Jets::Router
32
32
  # Checking the request_method_from_hidden_method_field so that handler can find the right route
33
33
  # super early in the process. Otherwise lambda routes to the wrong controller action.
34
34
  @request_method = request_method || @request.request_method_from_hidden_method_field || @request.request_method.to_s.upcase
35
- @request_path = @request.path
35
+ @request_path = strip_format(@request.path)
36
36
  route = find_route
37
37
  match_constraints(route) if route
38
38
  end
@@ -43,7 +43,7 @@ module Jets::Router
43
43
  def find_by_env(env)
44
44
  @env = env
45
45
  @request_method = env["REQUEST_METHOD"] || "GET"
46
- @request_path = env["PATH_INFO"]
46
+ @request_path = strip_format(env["PATH_INFO"])
47
47
  find_route
48
48
  end
49
49
 
@@ -87,12 +87,16 @@ module Jets::Router
87
87
  end
88
88
  memoize :mount
89
89
 
90
+ def strip_format(path)
91
+ path.sub(/\..+$/, '') # Remove format from the end of the path
92
+ end
93
+
90
94
  def match?(route)
91
95
  # Immediately stop checking when the request http_method: GET, POST, ANY, etc
92
96
  # doesnt match.
93
97
  return false if request_method != route.http_method && route.http_method != "ANY"
94
98
 
95
- route_path = route.path
99
+ route_path = strip_format(route.path)
96
100
  route_path = "#{mount.at}#{route_path}" if mount
97
101
 
98
102
  if request_path == route_path
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "5.0.0.beta1"
2
+ VERSION = "5.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jets
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta1
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-03 00:00:00.000000000 Z
11
+ date: 2023-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -962,7 +962,8 @@ files:
962
962
  - lib/jets/generators/overrides/app/USAGE
963
963
  - lib/jets/generators/overrides/app/app_generator.rb
964
964
  - lib/jets/generators/overrides/app/helpers.rb
965
- - lib/jets/generators/overrides/app/templates/.gitignore
965
+ - lib/jets/generators/overrides/app/templates/.env
966
+ - lib/jets/generators/overrides/app/templates/.gitignore.tt
966
967
  - lib/jets/generators/overrides/app/templates/.rspec
967
968
  - lib/jets/generators/overrides/app/templates/Gemfile.tt
968
969
  - lib/jets/generators/overrides/app/templates/README.md
@@ -1187,9 +1188,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
1187
1188
  version: 2.7.0
1188
1189
  required_rubygems_version: !ruby/object:Gem::Requirement
1189
1190
  requirements:
1190
- - - ">"
1191
+ - - ">="
1191
1192
  - !ruby/object:Gem::Version
1192
- version: 1.3.1
1193
+ version: '0'
1193
1194
  requirements: []
1194
1195
  rubygems_version: 3.4.20
1195
1196
  signing_key: