jets 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile.lock +10 -6
  4. data/README/testing.md +5 -1
  5. data/jets.gemspec +1 -0
  6. data/lib/jets.rb +5 -1
  7. data/lib/jets/application.rb +39 -19
  8. data/lib/jets/aws_services.rb +16 -10
  9. data/lib/jets/aws_services/stack_status.rb +7 -0
  10. data/lib/jets/booter.rb +6 -2
  11. data/lib/jets/builders/code_builder.rb +14 -0
  12. data/lib/jets/builders/handler_generator.rb +15 -0
  13. data/lib/jets/builders/shim_vars/app.rb +4 -3
  14. data/lib/jets/builders/shim_vars/shared.rb +8 -4
  15. data/lib/jets/builders/templates/shim.js +7 -3
  16. data/lib/jets/camelizer.rb +2 -1
  17. data/lib/jets/cfn/builders.rb +0 -1
  18. data/lib/jets/cfn/builders/api_deployment_builder.rb +27 -0
  19. data/lib/jets/cfn/builders/api_gateway_builder.rb +22 -2
  20. data/lib/jets/cfn/ship.rb +38 -6
  21. data/lib/jets/commands/call.rb +0 -1
  22. data/lib/jets/commands/call/guesser.rb +0 -3
  23. data/lib/jets/commands/clean/log.rb +18 -0
  24. data/lib/jets/commands/console.rb +1 -1
  25. data/lib/jets/commands/import/sequence.rb +2 -3
  26. data/lib/jets/commands/runner.rb +1 -1
  27. data/lib/jets/commands/sequence.rb +0 -1
  28. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +11 -0
  29. data/lib/jets/commands/url.rb +32 -7
  30. data/lib/jets/controller/base.rb +21 -5
  31. data/lib/jets/controller/layout.rb +0 -3
  32. data/lib/jets/controller/middleware/local/api_gateway.rb +2 -5
  33. data/lib/jets/controller/middleware/local/mimic_aws_call.rb +2 -2
  34. data/lib/jets/controller/params.rb +42 -10
  35. data/lib/jets/controller/rack/adapter.rb +5 -2
  36. data/lib/jets/controller/rack/env.rb +17 -8
  37. data/lib/jets/controller/renderers/rack_renderer.rb +1 -1
  38. data/lib/jets/controller/rendering.rb +4 -1
  39. data/lib/jets/core.rb +8 -16
  40. data/lib/jets/internal/app/functions/jets/base_path.rb +153 -0
  41. data/lib/jets/klass.rb +38 -5
  42. data/lib/jets/lambda/dsl.rb +0 -2
  43. data/lib/jets/mega/request.rb +44 -13
  44. data/lib/jets/mega/request/source.rb +21 -0
  45. data/lib/jets/middleware/configurator.rb +1 -1
  46. data/lib/jets/middleware/default_stack.rb +2 -2
  47. data/lib/jets/resource.rb +1 -0
  48. data/lib/jets/resource/api_gateway.rb +5 -3
  49. data/lib/jets/resource/api_gateway/base_path.rb +5 -0
  50. data/lib/jets/resource/api_gateway/base_path/function.rb +42 -0
  51. data/lib/jets/resource/api_gateway/base_path/mapping.rb +44 -0
  52. data/lib/jets/resource/api_gateway/base_path/role.rb +76 -0
  53. data/lib/jets/resource/api_gateway/cors.rb +1 -1
  54. data/lib/jets/resource/api_gateway/deployment.rb +9 -5
  55. data/lib/jets/resource/api_gateway/domain_name.rb +56 -0
  56. data/lib/jets/resource/api_gateway/method.rb +3 -4
  57. data/lib/jets/resource/api_gateway/resource.rb +4 -3
  58. data/lib/jets/resource/api_gateway/rest_api.rb +42 -14
  59. data/lib/jets/resource/api_gateway/rest_api/change_detection.rb +42 -0
  60. data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +59 -0
  61. data/lib/jets/resource/api_gateway/rest_api/routes.rb +127 -0
  62. data/lib/jets/resource/child_stack/api_deployment.rb +5 -1
  63. data/lib/jets/resource/function.rb +3 -20
  64. data/lib/jets/resource/function/environment.rb +23 -0
  65. data/lib/jets/resource/iam/application_role.rb +1 -1
  66. data/lib/jets/resource/route53.rb +3 -0
  67. data/lib/jets/resource/route53/record_set.rb +70 -0
  68. data/lib/jets/router.rb +2 -0
  69. data/lib/jets/ruby_server.rb +6 -3
  70. data/lib/jets/stack.rb +1 -3
  71. data/lib/jets/stack/main/dsl.rb +1 -1
  72. data/lib/jets/stack/main/extensions/lambda.rb +4 -2
  73. data/lib/jets/turbine.rb +0 -3
  74. data/lib/jets/version.rb +1 -1
  75. data/vendor/jets-gems/lib/jets/gems.rb +1 -0
  76. data/vendor/jets-gems/lib/jets/gems/agree.rb +41 -0
  77. data/vendor/jets-gems/lib/jets/gems/check.rb +15 -2
  78. metadata +30 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20fa97bccfb5b99e19a2edcf301bf31e53cd433a13862114fcb9648880e11fcc
4
- data.tar.gz: 124710223a460aed3a74a7498e2d2a15e5227c820d20a59db639ce83bdf2fb73
3
+ metadata.gz: 85ff84fd12cbc8c033636dae3eb3cf3b332389a28c611353a5167837622f7fc4
4
+ data.tar.gz: 492d4d772344cf8e329d02194a52aa6490bb7e47fb5f9e494332ee498f891be7
5
5
  SHA512:
6
- metadata.gz: d6ce23cf7b443de33af876d2ac178eaaa2faca79eb5b70188cedd726861478cb030f4dbcab3d03a894f271878a7d4b1923e9bef1555db97faebc4b34aa5cfb36
7
- data.tar.gz: b415939caba3f43bd03a5c10e47263ca2cd5adb0ebd01c7e76e495b3d09d25228863f51c83b9ece4eee865a0aa6ce5b64f1de3c6ac29234f55c0cde2d3ee0581
6
+ metadata.gz: 899243a605ac1e19c670b14967947605617b86ff347edda853742c091d62b5771a12222d0f34e834d680da4066ea4363eab677ae76ee9b35a87cd596ddec34b6
7
+ data.tar.gz: db515e009cda35564ae4c7fcf757d0fbbe910494a7427867ba6df725ed3b4cddbba308b33c34bbbc54b14ed38a4d2d60a950738b9ecdf1da3895d32e464898b0
@@ -3,6 +3,13 @@
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/), even before v1.0.
5
5
 
6
+ ## [1.2.0]
7
+ - major upgrades: binary support, custom domain, bluegreen
8
+ - binary support
9
+ - custom domains support: http://rubyonjets.com/docs/routing-custom-domain/
10
+ - automated bluegreen deploy for api gateway when needed: http://rubyonjets.com/docs/blue-green-deployment/
11
+ - Merge pull request #84 from tongueroo/bluegreen
12
+
6
13
  ## [1.1.5]
7
14
  - Support multiple path parameters. Also allow path parameters to hold any value other than '/'.
8
15
  - Merge pull request #82 from adam-harwood/master
@@ -11,11 +11,12 @@ GIT
11
11
  PATH
12
12
  remote: .
13
13
  specs:
14
- jets (1.1.5)
14
+ jets (1.2.0)
15
15
  actionpack (>= 5.2.1)
16
16
  actionview (>= 5.2.1)
17
17
  activerecord (>= 5.2.1)
18
18
  activesupport (>= 5.2.1)
19
+ aws-sdk-apigateway
19
20
  aws-sdk-cloudformation
20
21
  aws-sdk-cloudwatchlogs
21
22
  aws-sdk-dynamodb
@@ -65,28 +66,31 @@ GEM
65
66
  tzinfo (~> 1.1)
66
67
  arel (9.0.0)
67
68
  aws-eventstream (1.0.1)
68
- aws-partitions (1.118.0)
69
+ aws-partitions (1.121.0)
70
+ aws-sdk-apigateway (1.23.0)
71
+ aws-sdk-core (~> 3, >= 3.39.0)
72
+ aws-sigv4 (~> 1.0)
69
73
  aws-sdk-cloudformation (1.13.0)
70
74
  aws-sdk-core (~> 3, >= 3.39.0)
71
75
  aws-sigv4 (~> 1.0)
72
76
  aws-sdk-cloudwatchlogs (1.12.0)
73
77
  aws-sdk-core (~> 3, >= 3.39.0)
74
78
  aws-sigv4 (~> 1.0)
75
- aws-sdk-core (3.41.0)
79
+ aws-sdk-core (3.42.0)
76
80
  aws-eventstream (~> 1.0)
77
81
  aws-partitions (~> 1.0)
78
82
  aws-sigv4 (~> 1.0)
79
83
  jmespath (~> 1.0)
80
- aws-sdk-dynamodb (1.17.0)
84
+ aws-sdk-dynamodb (1.18.0)
81
85
  aws-sdk-core (~> 3, >= 3.39.0)
82
86
  aws-sigv4 (~> 1.0)
83
87
  aws-sdk-kms (1.13.0)
84
88
  aws-sdk-core (~> 3, >= 3.39.0)
85
89
  aws-sigv4 (~> 1.0)
86
- aws-sdk-lambda (1.15.0)
90
+ aws-sdk-lambda (1.16.0)
87
91
  aws-sdk-core (~> 3, >= 3.39.0)
88
92
  aws-sigv4 (~> 1.0)
89
- aws-sdk-s3 (1.27.0)
93
+ aws-sdk-s3 (1.29.0)
90
94
  aws-sdk-core (~> 3, >= 3.39.0)
91
95
  aws-sdk-kms (~> 1)
92
96
  aws-sigv4 (~> 1.0)
@@ -16,7 +16,9 @@ To run the integration tests locally, you need to create a new Jets CRUD project
16
16
 
17
17
  jets new demo
18
18
  cd demo
19
+ # edit Gemfile to use the branch of jets being tested
19
20
  jets generate scaffold Post title:string
21
+ jets import:rails http://github.com/tongueroo/demo-rails.git
20
22
  jets server --no-reload
21
23
 
22
24
  Then you can run the postman tests:
@@ -40,12 +42,14 @@ Then you can deploy the jets app and test it on real AWS Lambda.
40
42
 
41
43
  Run the remote integration script:
42
44
 
45
+ eval "export $(cat demo/.env.development.remote)" # for DATABASE_URL for mega mode
43
46
  BASE_URL=xxx spec/integration/remote.sh
44
47
 
45
48
  Example:
46
49
 
50
+ eval "export $(cat demo/.env.development.remote)" # for DATABASE_URL for mega mode
47
51
  BASE_URL=https://wb5dcjc09a.execute-api.us-west-2.amazonaws.com/dev spec/integration/remote.sh
48
52
 
49
53
  ## Manual Test
50
54
 
51
- Test books create, update and delete manually until it's scripted.
55
+ Test books create, update and delete manually until it's scripted.
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "actionview", ">= 5.2.1"
32
32
  spec.add_dependency "activerecord", ">= 5.2.1"
33
33
  spec.add_dependency "activesupport", ">= 5.2.1"
34
+ spec.add_dependency "aws-sdk-apigateway"
34
35
  spec.add_dependency "aws-sdk-cloudformation"
35
36
  spec.add_dependency "aws-sdk-cloudwatchlogs"
36
37
  spec.add_dependency "aws-sdk-dynamodb"
@@ -1,8 +1,12 @@
1
1
  $:.unshift(File.expand_path("../", __FILE__))
2
2
  require "jets/version"
3
3
  require "jets/camelizer"
4
- require "active_support/core_ext/string"
4
+ require "active_support"
5
+ require "active_support/core_ext"
6
+ require "active_support/dependencies"
5
7
  require "active_support/ordered_hash"
8
+ require "active_support/ordered_options"
9
+ require "active_support/concern"
6
10
  require "colorize"
7
11
  require "fileutils"
8
12
  require "memoist"
@@ -1,4 +1,3 @@
1
- require "active_support/ordered_options"
2
1
  require "singleton"
3
2
  require "rack"
4
3
 
@@ -13,7 +12,10 @@ class Jets::Application
13
12
  end
14
13
 
15
14
  def setup!
16
- load_configs # load config object so following methods can use it
15
+ load_configs
16
+ end
17
+
18
+ def finish!
17
19
  load_inflections
18
20
  setup_auto_load_paths
19
21
  load_routes
@@ -31,14 +33,7 @@ class Jets::Application
31
33
  config = ActiveSupport::OrderedOptions.new
32
34
  config.project_name = project_name
33
35
  config.cors = true
34
- config.autoload_paths = %w[
35
- app/controllers
36
- app/models
37
- app/jobs
38
- app/rules
39
- app/helpers
40
- app/shared/resources
41
- ]
36
+ config.autoload_paths = default_autoload_paths
42
37
  config.extra_autoload_paths = []
43
38
 
44
39
  # function properties defaults
@@ -80,8 +75,14 @@ class Jets::Application
80
75
 
81
76
  config.api = ActiveSupport::OrderedOptions.new
82
77
  config.api.authorization_type = "NONE"
78
+ config.api.binary_media_types = ['multipart/form-data']
83
79
  config.api.endpoint_type = 'EDGE' # PRIVATE, EDGE, REGIONAL
84
80
 
81
+ config.domain = ActiveSupport::OrderedOptions.new
82
+ # config.domain.name = "#{Jets.project_namespace}.coolapp.com" # Default is nil
83
+ # config.domain.cert_arn = "..."
84
+ config.domain.endpoint_type = "REGIONAL" # EDGE or REGIONAL. Default to EDGE because CloudFormation update is faster
85
+
85
86
  config
86
87
  end
87
88
 
@@ -110,7 +111,14 @@ class Jets::Application
110
111
 
111
112
  def eval_app_config
112
113
  app_config = "#{Jets.root}config/application.rb"
113
- require app_config
114
+ load app_config # use load instead of require so reload_configs! works
115
+ end
116
+
117
+ # After the mimimal template gets build, we need to reload it for the full stack
118
+ # creation. This allows us to reference IAM policies configs that depend on the
119
+ # creation of the s3 bucket.
120
+ def reload_configs!
121
+ load_configs
114
122
  end
115
123
 
116
124
  def load_environments_config
@@ -129,12 +137,31 @@ class Jets::Application
129
137
 
130
138
  def setup_auto_load_paths
131
139
  autoload_paths = config.autoload_paths + config.extra_autoload_paths
132
- autoload_paths = autoload_paths.uniq.map { |p| "#{Jets.root}#{p}" }
133
140
  # internal_autoload_paths are last
134
141
  autoload_paths += internal_autoload_paths
135
142
  ActiveSupport::Dependencies.autoload_paths += autoload_paths
136
143
  end
137
144
 
145
+ # Essentially folders under app folder will be the default_autoload_paths. Example:
146
+ # app/controllers
147
+ # app/helpers
148
+ # app/jobs
149
+ # app/models
150
+ # app/rules
151
+ # app/shared/resources
152
+ def default_autoload_paths
153
+ paths = []
154
+ Dir.glob("#{Jets.root}app/*").each do |p|
155
+ p.sub!('./','')
156
+ paths << p unless exclude_autoload_path?(p)
157
+ end
158
+ paths
159
+ end
160
+
161
+ def exclude_autoload_path?(path)
162
+ path =~ %r{app/javascript} || path =~ %r{app/views}
163
+ end
164
+
138
165
  def internal_autoload_paths
139
166
  internal = File.expand_path("../internal", __FILE__)
140
167
  paths = %w[
@@ -175,13 +202,6 @@ class Jets::Application
175
202
  config.managed_policy_definitions ||= [] # default empty
176
203
  end
177
204
 
178
- # After the mimimal template gets build, we need to reload it for the full stack
179
- # creation. This allows us to reference IAM policies configs that depend on the
180
- # creation of the s3 bucket.
181
- def reload_configs!
182
- load_configs
183
- end
184
-
185
205
  def self.default_iam_policy
186
206
  project_namespace = Jets.project_namespace
187
207
  logs = {
@@ -1,3 +1,4 @@
1
+ require "aws-sdk-apigateway"
1
2
  require "aws-sdk-cloudformation"
2
3
  require "aws-sdk-cloudwatchlogs"
3
4
  require "aws-sdk-lambda"
@@ -11,21 +12,26 @@ module Jets::AwsServices
11
12
  include StackStatus
12
13
  extend Memoist
13
14
 
15
+ def apigateway
16
+ Aws::APIGateway::Client.new
17
+ end
18
+ memoize :apigateway
19
+
14
20
  def cfn
15
21
  Aws::CloudFormation::Client.new
16
22
  end
17
23
  memoize :cfn
18
24
 
19
- def logs
20
- Aws::CloudWatchLogs::Client.new
21
- end
22
- memoize :logs
23
-
24
25
  def lambda
25
26
  Aws::Lambda::Client.new
26
27
  end
27
28
  memoize :lambda
28
29
 
30
+ def logs
31
+ Aws::CloudWatchLogs::Client.new
32
+ end
33
+ memoize :logs
34
+
29
35
  def s3
30
36
  Aws::S3::Client.new
31
37
  end
@@ -36,13 +42,13 @@ module Jets::AwsServices
36
42
  end
37
43
  memoize :s3_resource
38
44
 
39
- def sts
40
- Aws::STS::Client.new
41
- end
42
- memoize :sts
43
-
44
45
  def sns
45
46
  Aws::SNS::Client.new
46
47
  end
47
48
  memoize :sns
49
+
50
+ def sts
51
+ Aws::STS::Client.new
52
+ end
53
+ memoize :sts
48
54
  end
@@ -48,5 +48,12 @@ module Jets::AwsServices
48
48
  true
49
49
  end
50
50
  end
51
+
52
+ # Lookup output value.
53
+ # Used in Jets::Resource::ApiGateway::RestApi::* andJets::Commands::Url
54
+ def lookup(outputs, key)
55
+ out = outputs.find { |o| o.output_key == key }
56
+ out&.output_value
57
+ end
51
58
  end
52
59
  end
@@ -7,10 +7,14 @@ class Jets::Booter
7
7
  confirm_jets_project!
8
8
  require_bundle_gems
9
9
  Jets::Dotenv.load!
10
- Jets.application # triggers Application.instance setup # autoload_paths, routes, etc
11
- setup_db
10
+
11
+ Jets.application.setup!
12
12
  app_initializers
13
13
  turbine_initializers
14
+ Jets.application.finish!
15
+
16
+ Jets.eager_load!
17
+ setup_db
14
18
  # build_middleware_stack # TODO: figure out how to build middleware during Jets.boot without breaking jets new and webpacker:install
15
19
 
16
20
  @booted = true
@@ -165,12 +165,26 @@ class Jets::Builders
165
165
  update_lazy_load_config # at the top, must be called before Jets.lazy_load? is used
166
166
  store_s3_base_url
167
167
  disable_webpacker_middleware
168
+ copy_internal_jets_code
168
169
  setup_tmp
169
170
  calculate_md5s # must be called before generate_node_shims and create_zip_files
170
171
  generate_node_shims
171
172
  create_zip_files
172
173
  end
173
174
 
175
+ # We copy the files into the project because we cannot require simple functions
176
+ # directly since they are wrapped by an anonymous class.
177
+ # TODO: Do this with the other files we required the same way.
178
+ def copy_internal_jets_code
179
+ files = []
180
+ files.each do |relative_path|
181
+ src = File.expand_path("../internal/#{relative_path}", File.dirname(__FILE__))
182
+ dest = "#{full(tmp_code)}/#{relative_path}"
183
+ FileUtils.mkdir_p(File.dirname(dest))
184
+ FileUtils.cp(src, dest)
185
+ end
186
+ end
187
+
174
188
  def update_lazy_load_config
175
189
  size_limit = AWS_CODE_SIZE_LIMIT
176
190
  code_size = dir_size(full(tmp_code))
@@ -18,6 +18,7 @@ class Jets::Builders
18
18
  app_ruby_shims
19
19
  poly_shims
20
20
  shared_shims
21
+ internal_shims
21
22
  end
22
23
 
23
24
  def app_ruby_shims
@@ -67,6 +68,20 @@ class Jets::Builders
67
68
  end
68
69
  end
69
70
 
71
+ def internal_shims
72
+ jets_base_path if Jets.custom_domain?
73
+ end
74
+
75
+ def jets_base_path
76
+ path = "jets/base_path.rb"
77
+ internal = File.expand_path("../internal", File.dirname(__FILE__))
78
+ src = "#{internal}/app/functions/#{path}"
79
+ result = Jets::Erb.result(src, stage_name: Jets::Resource::ApiGateway::Deployment.stage_name)
80
+ dest = "#{tmp_code}/handlers/functions/#{path}"
81
+ FileUtils.mkdir_p(File.dirname(dest))
82
+ IO.write(dest, result)
83
+ end
84
+
70
85
  # app/shared/functions/kevin.py => /tmp/jets/demo/app_root/handlers/shared/functions/kevin.py
71
86
  def copy_source_as_handler(fun)
72
87
  source_path = fun.source_file
@@ -6,9 +6,9 @@
6
6
  #
7
7
  # Implements:
8
8
  #
9
- # functions
10
- # handler_for(function_name)
11
- # js_path
9
+ # functions: IE [:index, :show]
10
+ # handler_for(function_name): IE handlers/controllers/posts_controller.index
11
+ # js_path: IE: handlers/controllers/posts_controller.js
12
12
  #
13
13
  module Jets::Builders::ShimVars
14
14
  class App < Base
@@ -61,6 +61,7 @@ module Jets::Builders::ShimVars
61
61
  end
62
62
 
63
63
  # This gets called in the node shim js template
64
+ # IE handlers/controllers/posts_controller.index
64
65
  def handler_for(meth)
65
66
  # possibly not include _function
66
67
  underscored_name = @relative_path.sub(%r{app/(\w+)/},'').sub('.rb','')
@@ -6,9 +6,9 @@
6
6
  #
7
7
  # Implements:
8
8
  #
9
- # functions
10
- # handler_for(function_name)
11
- # js_path
9
+ # functions: IE [:index, :show]
10
+ # handler_for(function_name): IE handlers/controllers/posts_controller.index
11
+ # js_path: IE: handlers/controllers/posts_controller.js
12
12
  #
13
13
  module Jets::Builders::ShimVars
14
14
  class Shared < Base
@@ -17,15 +17,19 @@ module Jets::Builders::ShimVars
17
17
  @fun = fun
18
18
  end
19
19
 
20
+ # Always only one element for shared functions
21
+ # functions: IE [:handle]
20
22
  def functions
21
23
  [@fun.meth] # function_names
22
24
  end
23
25
 
24
- # dont need function_name arg but keeping the same interface as parent class
26
+ # Dont need function_name arg but keeping the same interface as parent class
27
+ # IE handlers/shared/functions/bob.handle
25
28
  def handler_for(function_name)
26
29
  @fun.handler_dest
27
30
  end
28
31
 
32
+ # IE handlers/shared/functions/bob.js
29
33
  def js_path
30
34
  @fun.handler_dest
31
35
  end
@@ -179,23 +179,27 @@ const once = async () => {
179
179
  // currying function to make handler code prettier
180
180
  function handler(full_handler_name) {
181
181
  return function(event, context, callback) {
182
- request(event, full_handler_name, callback);
182
+ request(event, context, full_handler_name, callback);
183
183
  };
184
184
  }
185
185
 
186
186
  ////////////////////////////////////////////////////////////////////////////////
187
187
  // main logic for handler
188
- function request(event, handler, callback) {
188
+ function request(event, context, handler, callback) {
189
189
  truncate(JETS_OUTPUT);
190
190
  truncate(TMP_LOG_PATH);
191
191
 
192
192
  log("event:");
193
193
  log(event);
194
+ log("context:");
195
+ log(context);
194
196
  var client = new net.Socket();
195
197
  client.connect(8080, '127.0.0.01', function() {
196
198
  log('Connected to socket');
197
199
  client.write(JSON.stringify(event));
198
200
  client.write("\r\n"); // important: \r\n is how server knows input is done
201
+ client.write(JSON.stringify(context));
202
+ client.write("\r\n"); // important: \r\n is how server knows input is done
199
203
  client.write(handler);
200
204
  client.write("\r\n"); // important: \r\n is how server knows input is done
201
205
  });
@@ -260,7 +264,7 @@ function request(event, handler, callback) {
260
264
  truncate(TMP_LOG_PATH);
261
265
 
262
266
  log("Retrying request NOW");
263
- request(event, handler, callback);
267
+ request(event, context, handler, callback);
264
268
  }, 500);
265
269
  });
266
270
  }