jets 3.1.5 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc8976a98ceaa55f97512b3b0e78cec5f28e1d0ade29d23270894cbcfa1ef5c3
4
- data.tar.gz: 149caed9e86daea3f45e745e6f32c28aa0a15b6b938237305e41bc85c774adc4
3
+ metadata.gz: 8fedba281ee9d6ac31a44184b49bbc8fe15d309a3f4d58142cfa25c4ddebc153
4
+ data.tar.gz: e73ee950202ea1786c881b43abc95c03bc4c3e7ef44b04265997eca2f4b9211b
5
5
  SHA512:
6
- metadata.gz: e9a49470b973e8b927c5921a5e373f18d66141d2af0c288fa6a2d0cac4f59fa7a534e1e52bf949d56482f8987843b9f5628d3699f0c27cf4c9cc9f271d6a33c8
7
- data.tar.gz: 43e8734b1f3e7b2a7cfb16a1c4d74957fac5e4c1deb090d816d003655775374a8e3c03d473dbd7bc2166a05412562d74f811fe6dbe944237a958c9428f76167a
6
+ metadata.gz: 57070368542b8a767fbf8553f0c627b36432e691ae07f1f41488a0d8af830bffd1ed84a71633fe971df6b45bcf79ff8862f2d4513d22e4a1981b633f36cbb8bd
7
+ data.tar.gz: 32ba83eb4d4e87a8c92b5d7ec8d573ae2b36ff558fedbae7bb33f1ebe5dbcb36baf2f64b89b2a05d2e56e52bcd2145964a0770f7a56efdb48d1a925498c7f177
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.5
1
+ 2.7.7
data/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
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
+ ## [3.2.1] - 2023-05-03
7
+ - [#637](https://github.com/boltops-tools/jets/pull/637) Readme: Replace "splat out" with "had" a baby
8
+ - [#638](https://github.com/boltops-tools/jets/pull/638) feature: update an array of reserved variables in aws lambda
9
+ - [#639](https://github.com/boltops-tools/jets/pull/639) fix assets upload during deploy
10
+
11
+ ## [3.2.0] - 2022-12-03
12
+ - [#631](https://github.com/boltops-tools/jets/pull/631) Implement vpc_endpoint_ids configuration
13
+ - [#634](https://github.com/boltops-tools/jets/pull/634) Custom domain messaging
14
+ - [#635](https://github.com/boltops-tools/jets/pull/635) smarter apigw routes paging calculation
15
+ - Introduce the storage of APIGW routes state in the jets managed s3 bucket under path jets/state/apigw/pages.json and jets/state/apigw/routes.json
16
+ - This speeds up deployment for apps with a large number of routes. Depending on the internet connection this can be minutes faster.
17
+ - Update internationalization.md
18
+ - fix domain.name check when APIGW changes
19
+ - improve change apigw endpoint change messaging
20
+
6
21
  ## [3.1.5] - 2022-08-08
7
22
  - [#628](https://github.com/boltops-tools/jets/pull/628) Multiple Databases
8
23
  - [#629](https://github.com/boltops-tools/jets/pull/629) loosen zeitwerk dependency in generated project Gemfile
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <a href="http://rubyonjets.com"><img src="http://rubyonjets.com/img/logos/jets-logo-full.png" /></a>
3
3
  </div>
4
4
 
5
- Ruby and Lambda splat out a baby and that child's name is [Jets](http://rubyonjets.com/).
5
+ Ruby and Lambda had a baby and that child's name is [Jets](http://rubyonjets.com/).
6
6
 
7
7
  ![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiZ08vK2hjOHczQUVoUDhSYnBNNUU4T0gxQWJuOTlLaXpwVGQ1NjJ3NnVDY1dSdFVXQ3d2VXVSQzRFcU1qd1JPMndFZlByRktIcTUrZm5GWlM5dHpjM1ZrPSIsIml2UGFyYW1ldGVyU3BlYyI6Imluc1Qrd25GanhUdHlidjUiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)
8
8
  [![CircleCI](https://circleci.com/gh/boltops-tools/jets.svg?style=svg)](https://circleci.com/gh/boltops-tools/jets)
@@ -16,10 +16,6 @@ Please **watch/star** this repo to help grow and support the project.
16
16
 
17
17
  **Upgrading**: If you are upgrading Jets, please check on the [Upgrading Notes](http://rubyonjets.com/docs/extras/upgrading/).
18
18
 
19
- ## Sponsors
20
-
21
- [![](https://img.boltops.com/boltops/tools/jets/sponsors/arist.png)](https://arist.co/)
22
-
23
19
  ## What is Ruby on Jets?
24
20
 
25
21
  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.
data/backers.md CHANGED
@@ -11,10 +11,5 @@ Funds donated via Patreon go directly to support Tung Nguyen's full-time work on
11
11
  <h2 align="center">Backers via Patreon</h2>
12
12
 
13
13
  <!--10 start-->
14
- - Erlend Finvåg
15
- - Nate Clark
16
- - Hirokatsu Endo
17
- - Michael Choi
18
- - Phan Lam
19
14
  - Theron Welch
20
15
  <!--10 end-->
@@ -99,6 +99,7 @@ class Jets::Application
99
99
  config.api.cors_authorization_type = nil # nil so ApiGateway::Cors#cors_authorization_type handles
100
100
  config.api.endpoint_policy = nil # required when endpoint_type is EDGE
101
101
  config.api.endpoint_type = 'EDGE' # PRIVATE, EDGE, REGIONAL
102
+ config.api.vpc_endpoint_ids = nil
102
103
 
103
104
  config.api.authorizers = ActiveSupport::OrderedOptions.new
104
105
  config.api.authorizers.default_token_source = "Auth" # method.request.header.Auth
@@ -86,10 +86,18 @@ module Jets::AwsServices
86
86
  retry_limit: 7, # default: 3
87
87
  retry_base_delay: 0.6, # default: 0.3
88
88
  }
89
+ # See debug logger. Noisy.
90
+ # Example:
91
+ # D, [2022-12-02T13:18:55.298788 #26182] DEBUG -- : [Aws::APIGateway::Client 200 0.030837 0 retries] get_method(rest_api_id:"mke40eh6l0",resource_id:"zf8w2m",http_method:"GET")
89
92
  options.merge!(
90
93
  log_level: :debug,
91
94
  logger: Logger.new($stdout),
92
95
  ) if ENV['JETS_DEBUG_AWS_SDK']
96
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/debugging.html to enable http_wire_trace
97
+ # See the HTTP headers and JSON responses. Super noisy.
98
+ options.merge!(
99
+ http_wire_trace: true,
100
+ ) if ENV['JETS_DEBUG_AWS_SDK_HTTP_WIRE_TRACE']
93
101
  options
94
102
  end
95
103
  end
@@ -49,7 +49,7 @@ module Jets::Cfn::Builders
49
49
 
50
50
  def add_route53_dns
51
51
  dns = Jets::Resource::Route53::RecordSet.new
52
- if !existing_domain_name?(dns.domain_name) or existing_dns_record_on_stack?
52
+ if !existing_domain_name?(dns.domain_name) or existing_dns_record_on_stack?
53
53
  add_resource(dns)
54
54
  add_outputs(dns.outputs)
55
55
  end
@@ -57,11 +57,11 @@ module Jets::Cfn::Builders
57
57
 
58
58
  def create_domain_name()
59
59
  resource = Jets::Resource::ApiGateway::DomainName.new
60
-
60
+
61
61
  return {
62
62
  "DomainName" => resource.domain_name
63
63
  } if (existing_domain_name?(resource) and !existing_domain_name_on_stack?)
64
-
64
+
65
65
  add_resource(resource)
66
66
  return resource.outputs
67
67
  end
@@ -114,8 +114,9 @@ module Jets::Cfn::Builders
114
114
  def add_gateway_routes
115
115
  # Reject homepage. Otherwise we have 200 - 1 resources on the first page.
116
116
  # There's a next call in ApiResources.add_gateway_resources to skip the homepage.
117
- all_paths = Jets::Router.all_paths.reject { |p| p == '' }
118
- all_paths.each_slice(PAGE_LIMIT).each_with_index do |paths, i|
117
+ page_builder = Jets::Cfn::Builders::PageBuilder.new
118
+ pages = page_builder.build
119
+ pages.each_with_index do |paths, i|
119
120
  ApiResourcesBuilder.new(@options, paths, i+1).build
120
121
  end
121
122
  end
@@ -0,0 +1,80 @@
1
+ module Jets::Cfn::Builders
2
+ class PageBuilder
3
+ extend Memoist
4
+ cattr_reader :pages
5
+
6
+ # Build page slices
7
+ def build
8
+ map = build_map
9
+ pages = []
10
+ map.each do |path, existing_page|
11
+ if existing_page
12
+ pages[existing_page] ||= []
13
+ pages[existing_page] << path
14
+ end
15
+ end
16
+
17
+ # Remove existing paths from map. Leave behind new paths
18
+ pages.each do |page|
19
+ page.each do |i|
20
+ map.delete(i)
21
+ end
22
+ end
23
+
24
+ # Fill up available space in each page so all existing pages are full
25
+ keys = map.keys
26
+ pages.each do |page|
27
+ break if keys.empty?
28
+ while page.size < page_limit
29
+ path = keys.shift
30
+ break if path.nil?
31
+ page << path
32
+ end
33
+ end
34
+
35
+ # Add remaining slices to new additional pages
36
+ pages += keys.each_slice(page_limit).to_a
37
+
38
+ @@pages = pages
39
+
40
+ pages
41
+ end
42
+
43
+ # Build map that has paths as keys and page number as value
44
+ # Example: {"a1"=>0, "a2"=>0, "b1"=>1, "b2"=>1, "c1"=>2, "c2"=>2}
45
+ def build_map
46
+ map = {}
47
+ new_paths.each do |path|
48
+ map[path] = find_page_index(path)
49
+ end
50
+ map
51
+ end
52
+
53
+ def find_page_index(new_path)
54
+ pages = old_pages || []
55
+ pages.each_with_index do |slice, i|
56
+ slice.find do |old_path|
57
+ return i if old_path == new_path
58
+ end
59
+ end
60
+ nil
61
+ end
62
+
63
+ def old_pages
64
+ state = Jets::Router::State.new
65
+ state.load("pages")
66
+ end
67
+ memoize :old_pages
68
+
69
+ def new_paths
70
+ Jets::Router.all_paths.reject { |p| p == '' }
71
+ end
72
+
73
+ # Relevant is CloudFormation Outputs limit is 200
74
+ # JETS_APIGW_PAGE_LIMIT is based on that
75
+ # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html
76
+ def page_limit
77
+ Integer(ENV['JETS_APIGW_PAGE_LIMIT'] || 200)
78
+ end
79
+ end
80
+ end
@@ -26,7 +26,26 @@ module Jets::Cfn::Builders
26
26
  add_description("Jets: #{Jets.version} Code: #{Util::Source.version}")
27
27
 
28
28
  # Initial s3 bucket, used to store code zipfile and templates Jets generates
29
+ #
30
+ # AWS changed the default behavior of s3 buckets to block public access
31
+ # https://aws.amazon.com/blogs/aws/amazon-s3-block-public-access-another-layer-of-protection-for-your-accounts-and-buckets/
32
+ # https://github.com/aws-amplify/amplify-cli/issues/12503
33
+ #
34
+ # Jets uploads assets to s3 bucket with acl: "public-read" here
35
+ # https://github.com/boltops-tools/jets/blob/c5858ec2706a606665a92c3ada3f16ae4c753372/lib/jets/cfn/upload.rb#L97
36
+ #
37
+ # Use minimal s3 bucket policy to allow public read access to assets.
38
+ # Leave the other options as comments to help document the default behavior.
29
39
  resource = Jets::Resource::S3::Bucket.new(logical_id: "s3_bucket",
40
+ PublicAccessBlockConfiguration: {
41
+ BlockPublicAcls: false,
42
+ # BlockPublicPolicy: false,
43
+ # IgnorePublicAcls: false,
44
+ # RestrictPublicBuckets: false
45
+ },
46
+ OwnershipControls: {
47
+ Rules: [{ObjectOwnership: "ObjectWriter"}]
48
+ },
30
49
  bucket_encryption: {
31
50
  server_side_encryption_configuration: [
32
51
  server_side_encryption_by_default: {
data/lib/jets/cfn/ship.rb CHANGED
@@ -42,6 +42,7 @@ module Jets::Cfn
42
42
  exit 1
43
43
  end
44
44
 
45
+ save_apigw_state
45
46
  prewarm
46
47
  clean_deploy_logs
47
48
  show_api_endpoint
@@ -88,6 +89,12 @@ module Jets::Cfn
88
89
  Jets::Cfn::Status.new(@options).wait
89
90
  end
90
91
 
92
+ def save_apigw_state
93
+ state = Jets::Router::State.new
94
+ state.save("pages", Jets::Cfn::Builders::PageBuilder.pages)
95
+ state.save("routes", Jets::Router.routes)
96
+ end
97
+
91
98
  def prewarm
92
99
  if ENV['SKIP_PREWARMING']
93
100
  puts "Skipping prewarming" # useful for testing
@@ -8,8 +8,7 @@ class Jets::Resource::ApiGateway::RestApi::LogicalId
8
8
  end
9
9
 
10
10
  def custom_domain
11
- api = Jets::Resource::ApiGateway::DomainName.new
12
- domain_name = api.domain_name
11
+ domain_name = Jets.config.domain.name
13
12
  if domain_name
14
13
  <<~EOL
15
14
  It looks like you have already set up a custom domain.
@@ -25,7 +24,18 @@ class Jets::Resource::ApiGateway::RestApi::LogicalId
25
24
  More info: custom domain docs: https://rubyonjets.com/docs/routing/custom-domain/
26
25
  EOL
27
26
  else
28
- "Please set up a custom domain https://rubyonjets.com/docs/routing/custom-domain/"
27
+ <<~EOL
28
+ To avoid this prompt in the future, you can configure:
29
+
30
+ config/application.rb
31
+
32
+ config.api.auto_replace = true
33
+
34
+ However, you should also set up a custom domain for a "stable" endpoint.
35
+
36
+ https://rubyonjets.com/docs/routing/custom-domain/
37
+
38
+ EOL
29
39
  end
30
40
  end
31
41
 
@@ -7,51 +7,22 @@ class Jets::Resource::ApiGateway::RestApi::Routes::Change
7
7
  new.changed?
8
8
  end
9
9
 
10
- # Build up deployed routes from the existing CloudFormation resources.
10
+ # Recreate routes from previously deployed stored state in s3
11
11
  def deployed_routes
12
- routes = []
13
-
14
- resources, position = [], true
15
- while position
16
- position = nil if position == true # start of loop
17
- resp = apigateway.get_resources(
18
- rest_api_id: rest_api_id,
19
- position: position,
20
- limit: 500, # default: 25 max: 500
12
+ state = Jets::Router::State.new
13
+ data = state.load("routes")
14
+ return [] if data.nil?
15
+
16
+ data.map do |item|
17
+ Jets::Router::Route.new(
18
+ path: item['path'],
19
+ method: item['options']['method'],
20
+ to: item['to'],
21
21
  )
22
- resources += resp.items
23
- position = resp.position
24
- end
25
-
26
- resources.each do |resource|
27
- resource_methods = resource.resource_methods
28
- next if resource_methods.nil?
29
-
30
- resource_methods.each do |http_verb, resource_method|
31
- # puts "#{http_verb} #{resource.path} | resource.id #{resource.id}"
32
- # puts to(resource.id, http_verb)
33
-
34
- # Test changing config.cors and CloudFormation does an in-place update
35
- # on the resource. So no need to do bluegreen deployments for OPTIONS.
36
- next if http_verb == "OPTIONS"
37
-
38
- path = recreate_path(resource.path)
39
- method = http_verb.downcase.to_sym
40
- to = to(resource.id, http_verb)
41
- route = Jets::Router::Route.new(path: path, method: method, to: to)
42
- routes << route
43
- end
44
22
  end
45
- routes
46
23
  end
47
24
  memoize :deployed_routes
48
25
 
49
- def recreate_path(path)
50
- path = path.gsub(%r{^/},'')
51
- path = path.gsub(/{([^}]*)\+}/, '*\1')
52
- path.gsub(/{([^}]*)}/, ':\1')
53
- end
54
-
55
26
  def to(resource_id, http_method)
56
27
  uri = method_uri(resource_id, http_method)
57
28
  recreate_to(uri) unless uri.nil?
@@ -5,6 +5,7 @@ module Jets::Resource::ApiGateway
5
5
  name: Jets::Naming.gateway_api_name,
6
6
  endpoint_configuration: { types: endpoint_types }
7
7
  }
8
+ properties[:endpoint_configuration][:vpc_endpoint_ids] = vpce_ids if vpce_ids
8
9
  properties[:binary_media_types] = binary_media_types if binary_media_types
9
10
  properties[:policy] = endpoint_policy if endpoint_policy
10
11
 
@@ -60,5 +61,14 @@ module Jets::Resource::ApiGateway
60
61
 
61
62
  endpoint_policy
62
63
  end
64
+
65
+ private
66
+
67
+ def vpce_ids
68
+ ids = Jets.config.api.vpc_endpoint_ids
69
+ return nil if ids.nil? || ids.empty?
70
+
71
+ ids
72
+ end
63
73
  end
64
- end
74
+ end
@@ -36,21 +36,23 @@ class Jets::Resource::Lambda::Function
36
36
  exit 1
37
37
  end
38
38
 
39
- # https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html#lambda-environment-variables
39
+ # https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html
40
40
  def reserved_variables
41
41
  %w[
42
42
  _HANDLER
43
+ AWS_DEFAULT_REGION
43
44
  AWS_REGION
44
45
  AWS_EXECUTION_ENV
45
46
  AWS_LAMBDA_FUNCTION_NAME
46
47
  AWS_LAMBDA_FUNCTION_MEMORY_SIZE
47
48
  AWS_LAMBDA_FUNCTION_VERSION
49
+ AWS_LAMBDA_INITIALIZATION_TYPE
48
50
  AWS_LAMBDA_LOG_GROUP_NAME
49
51
  AWS_LAMBDA_LOG_STREAM_NAME
52
+ AWS_ACCESS_KEY
50
53
  AWS_ACCESS_KEY_ID
51
54
  AWS_SECRET_ACCESS_KEY
52
55
  AWS_SESSION_TOKEN
53
- TZ
54
56
  LAMBDA_TASK_ROOT
55
57
  LAMBDA_RUNTIME_DIR
56
58
  AWS_LAMBDA_RUNTIME_API
@@ -191,6 +191,10 @@ class Jets::Router
191
191
  @options[:mount_class]
192
192
  end
193
193
 
194
+ def to_h
195
+ JSON.load(to_json)
196
+ end
197
+
194
198
  private
195
199
  def ensure_jets_format(path)
196
200
  path.split('/').map do |s|
@@ -0,0 +1,47 @@
1
+ class Jets::Router
2
+ class State
3
+ extend Memoist
4
+ include Jets::AwsServices
5
+
6
+ def load(filename)
7
+ resp = s3.get_object(
8
+ bucket: Jets.aws.s3_bucket,
9
+ key: s3_storage_path(filename),
10
+ )
11
+ text = resp.body.read
12
+ JSON.load(text)
13
+ rescue
14
+ end
15
+ memoize :load
16
+
17
+ # Save previously deployed APIGW routes state
18
+ def save(filename, data)
19
+ # body = Jets::Router.routes.to_json
20
+ # body = JSON.generate(Jets::Cfn::Builders::PageBuilder.pages)
21
+ body = data.respond_to?(:to_json) ? data.to_json : JSON.generate(data)
22
+ s3.put_object(
23
+ body: body,
24
+ bucket: Jets.aws.s3_bucket,
25
+ key: s3_storage_path(filename),
26
+ )
27
+ end
28
+
29
+ # Examples:
30
+ #
31
+ # jets/state/apigw/pages.json
32
+ # jets/state/apigw/routes.json
33
+ #
34
+ # Fetch or loaded in:
35
+ #
36
+ # pages.json: Jets::Cfn::Builders::PageBuilder#old_pages
37
+ # routes.json: Jets::Resource::ApiGateway::RestApi::Routes::Change::Base#deployed_routes
38
+ #
39
+ # Saved in:
40
+ #
41
+ # Jets::Cfn::Ship#save_apigw_state
42
+ #
43
+ def s3_storage_path(filename)
44
+ "jets/state/apigw/#{filename}.json"
45
+ end
46
+ end
47
+ end
data/lib/jets/router.rb CHANGED
@@ -134,6 +134,18 @@ module Jets
134
134
  drawn_router.routes
135
135
  end
136
136
 
137
+ # So we can save state in s3 post deploy. Example of structure.
138
+ #
139
+ # [
140
+ # {"scope"=>{"options"=>{"as"=>"posts", "prefix"=>"posts", "param"=>nil, "from"=>"resources"}, "parent"=>{"options"=>{}, "parent"=>nil, "level"=>1}, "level"=>2}, "options"=>{"to"=>"posts#index", "from_scope"=>true, "path"=>"posts", "method"=>"get"}, "path"=>"posts", "to"=>"posts#index", "as"=>"posts"},
141
+ # {"scope"=>{"options"=>{"as"=>"posts", "prefix"=>"posts", "param"=>nil, "from"=>"resources"}, "parent"=>{"options"=>{}, "parent"=>nil, "level"=>1}, "level"=>2}, "options"=>{"to"=>"posts#new", "from_scope"=>true, "path"=>"posts/new", "method"=>"get"}, "path"=>"posts/new", "to"=>"posts#new", "as"=>"new_post"},
142
+ # ...
143
+ # ]
144
+ #
145
+ def to_json
146
+ JSON.dump(routes.map(&:to_h))
147
+ end
148
+
137
149
  # Returns all paths including subpaths.
138
150
  # Example:
139
151
  # Input: ["posts/:id/edit"]
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "3.1.5"
2
+ VERSION = "3.2.1"
3
3
  end
data/lib/jets.rb CHANGED
@@ -17,6 +17,7 @@ require "active_support/ordered_options"
17
17
  require "cfn_camelizer"
18
18
  require "cfn_status"
19
19
  require "fileutils"
20
+ require "json"
20
21
  require "memoist"
21
22
  require "rainbow/ext/string"
22
23
  require "serverlessgems"
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: 3.1.5
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-08 00:00:00.000000000 Z
11
+ date: 2023-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -661,6 +661,7 @@ files:
661
661
  - lib/jets/cfn/builders/function_builder.rb
662
662
  - lib/jets/cfn/builders/interface.rb
663
663
  - lib/jets/cfn/builders/job_builder.rb
664
+ - lib/jets/cfn/builders/page_builder.rb
664
665
  - lib/jets/cfn/builders/parent_builder.rb
665
666
  - lib/jets/cfn/builders/parent_builder/stagger.rb
666
667
  - lib/jets/cfn/builders/rule_builder.rb
@@ -986,6 +987,7 @@ files:
986
987
  - lib/jets/router/route.rb
987
988
  - lib/jets/router/route/authorizer.rb
988
989
  - lib/jets/router/scope.rb
990
+ - lib/jets/router/state.rb
989
991
  - lib/jets/router/util.rb
990
992
  - lib/jets/rule/base.rb
991
993
  - lib/jets/rule/dsl.rb
@@ -1101,7 +1103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1101
1103
  - !ruby/object:Gem::Version
1102
1104
  version: '0'
1103
1105
  requirements: []
1104
- rubygems_version: 3.3.10
1106
+ rubygems_version: 3.4.6
1105
1107
  signing_key:
1106
1108
  specification_version: 4
1107
1109
  summary: Ruby Serverless Framework