startback-websocket 0.14.0 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -2
- data/README.md +64 -9
- data/lib/startback/ext/context.rb +6 -0
- data/lib/startback/ext.rb +1 -2
- data/lib/startback/websocket/app.rb +82 -0
- data/lib/startback/websocket/hub/app.rb +28 -0
- data/lib/startback/websocket/hub/builder.rb +55 -0
- data/lib/startback/websocket/hub/errors.rb +9 -0
- data/lib/startback/websocket/hub/message.rb +29 -0
- data/lib/startback/websocket/hub/middleware/command_handler.rb +34 -0
- data/lib/startback/websocket/hub/middleware/room_handler.rb +30 -0
- data/lib/startback/websocket/hub/middleware.rb +12 -0
- data/lib/startback/websocket/hub/participant.rb +16 -0
- data/lib/startback/websocket/hub/room.rb +46 -0
- data/lib/startback/websocket/hub.rb +15 -0
- data/lib/startback/websocket.rb +8 -0
- data/spec/spec_helper.rb +21 -32
- data/spec/unit/hub/test_builder.rb +141 -0
- data/spec/unit/hub/test_room.rb +27 -0
- data/spec/unit/test_app.rb +35 -0
- data/tasks/test.rake +0 -1
- metadata +20 -91
- data/lib/startback/audit/prometheus.rb +0 -87
- data/lib/startback/audit/shared.rb +0 -17
- data/lib/startback/audit/trailer.rb +0 -129
- data/lib/startback/audit.rb +0 -3
- data/lib/startback/caching/entity_cache.rb +0 -157
- data/lib/startback/caching/no_store.rb +0 -28
- data/lib/startback/caching/store.rb +0 -34
- data/lib/startback/context/h_factory.rb +0 -43
- data/lib/startback/context/middleware.rb +0 -53
- data/lib/startback/context.rb +0 -122
- data/lib/startback/errors.rb +0 -197
- data/lib/startback/event/agent.rb +0 -84
- data/lib/startback/event/bus/bunny/async.rb +0 -162
- data/lib/startback/event/bus/bunny.rb +0 -1
- data/lib/startback/event/bus/memory/async.rb +0 -45
- data/lib/startback/event/bus/memory/sync.rb +0 -35
- data/lib/startback/event/bus/memory.rb +0 -2
- data/lib/startback/event/bus.rb +0 -100
- data/lib/startback/event/engine.rb +0 -94
- data/lib/startback/event/ext/context.rb +0 -5
- data/lib/startback/event/ext/operation.rb +0 -13
- data/lib/startback/event.rb +0 -47
- data/lib/startback/ext/date_time.rb +0 -9
- data/lib/startback/ext/time.rb +0 -9
- data/lib/startback/model.rb +0 -6
- data/lib/startback/operation/error_operation.rb +0 -19
- data/lib/startback/operation/multi_operation.rb +0 -28
- data/lib/startback/operation.rb +0 -78
- data/lib/startback/services.rb +0 -11
- data/lib/startback/support/data_object.rb +0 -71
- data/lib/startback/support/env.rb +0 -41
- data/lib/startback/support/fake_logger.rb +0 -18
- data/lib/startback/support/hooks.rb +0 -48
- data/lib/startback/support/log_formatter.rb +0 -34
- data/lib/startback/support/logger.rb +0 -34
- data/lib/startback/support/operation_runner.rb +0 -150
- data/lib/startback/support/robustness.rb +0 -157
- data/lib/startback/support/transaction_manager.rb +0 -25
- data/lib/startback/support/transaction_policy.rb +0 -33
- data/lib/startback/support/world.rb +0 -54
- data/lib/startback/support.rb +0 -26
- data/lib/startback/version.rb +0 -8
- data/lib/startback/web/api.rb +0 -99
- data/lib/startback/web/auto_caching.rb +0 -85
- data/lib/startback/web/catch_all.rb +0 -52
- data/lib/startback/web/cors_headers.rb +0 -80
- data/lib/startback/web/health_check.rb +0 -49
- data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
- data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
- data/lib/startback/web/magic_assets.rb +0 -98
- data/lib/startback/web/middleware.rb +0 -13
- data/lib/startback/web/prometheus.rb +0 -16
- data/lib/startback/web/shield.rb +0 -58
- data/lib/startback.rb +0 -43
- data/spec/unit/audit/test_prometheus.rb +0 -72
- data/spec/unit/audit/test_trailer.rb +0 -105
- data/spec/unit/caching/test_entity_cache.rb +0 -136
- data/spec/unit/context/test_abstraction_factory.rb +0 -64
- data/spec/unit/context/test_dup.rb +0 -42
- data/spec/unit/context/test_fork.rb +0 -37
- data/spec/unit/context/test_h_factory.rb +0 -31
- data/spec/unit/context/test_middleware.rb +0 -45
- data/spec/unit/context/test_with_world.rb +0 -20
- data/spec/unit/context/test_world.rb +0 -17
- data/spec/unit/event/bus/memory/test_async.rb +0 -43
- data/spec/unit/event/bus/memory/test_sync.rb +0 -43
- data/spec/unit/support/hooks/test_after_hook.rb +0 -54
- data/spec/unit/support/hooks/test_before_hook.rb +0 -54
- data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
- data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
- data/spec/unit/support/test_data_object.rb +0 -156
- data/spec/unit/support/test_env.rb +0 -75
- data/spec/unit/support/test_robusteness.rb +0 -229
- data/spec/unit/support/test_transaction_manager.rb +0 -64
- data/spec/unit/support/test_world.rb +0 -72
- data/spec/unit/test_event.rb +0 -62
- data/spec/unit/test_operation.rb +0 -55
- data/spec/unit/test_support.rb +0 -40
- data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
- data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
- data/spec/unit/web/fixtures/assets/index.es6 +0 -1
- data/spec/unit/web/test_api.rb +0 -82
- data/spec/unit/web/test_auto_caching.rb +0 -81
- data/spec/unit/web/test_catch_all.rb +0 -77
- data/spec/unit/web/test_cors_headers.rb +0 -88
- data/spec/unit/web/test_healthcheck.rb +0 -59
- data/spec/unit/web/test_magic_assets.rb +0 -82
@@ -1,33 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Support
|
3
|
-
module TransactionPolicy
|
4
|
-
|
5
|
-
# Returns the operation's transaction policy
|
6
|
-
def transaction_policy
|
7
|
-
@transaction_policy || :before_call
|
8
|
-
end
|
9
|
-
|
10
|
-
# Sets the transaction policy to use. Valid values are:
|
11
|
-
# - before_call : the transaction is started by the operation
|
12
|
-
# runner, right before calling the #call method on operation
|
13
|
-
# instance
|
14
|
-
# - within_call: the transaction is started by the operation
|
15
|
-
# itself, as part of its internal logic.
|
16
|
-
def transaction_policy=(policy)
|
17
|
-
unless [:before_call, :within_call].include?(policy)
|
18
|
-
raise ArgumentError, "Unknown policy `#{policy}`"
|
19
|
-
end
|
20
|
-
@transaction_policy = policy
|
21
|
-
end
|
22
|
-
|
23
|
-
def after_commit(&bl)
|
24
|
-
after_call do
|
25
|
-
db.after_commit do
|
26
|
-
instance_exec(&bl)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end # module TransactionPolicy
|
32
|
-
end # module Support
|
33
|
-
end # module Startback
|
@@ -1,54 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Support
|
3
|
-
class World
|
4
|
-
include DataObject
|
5
|
-
|
6
|
-
attr_accessor :_factory
|
7
|
-
protected :_factory=
|
8
|
-
|
9
|
-
def factory(who, &block)
|
10
|
-
dup.tap do |x|
|
11
|
-
x._factory = (self._factory || {}).merge(who => block)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_accessor :_scope
|
16
|
-
protected :_scope=
|
17
|
-
|
18
|
-
def with_scope(scope)
|
19
|
-
dup.tap do |x|
|
20
|
-
x._scope = scope
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def with(hash)
|
25
|
-
dup.tap do |x|
|
26
|
-
x._data = to_data.merge(hash)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def _data_allow_camelize
|
33
|
-
false
|
34
|
-
end
|
35
|
-
|
36
|
-
def _data_allow_query
|
37
|
-
false
|
38
|
-
end
|
39
|
-
|
40
|
-
def _data_key_not_found(key)
|
41
|
-
raise Startback::Error, "Scope must be defined" unless s = _scope
|
42
|
-
|
43
|
-
block = (_factory || {})[key]
|
44
|
-
if block
|
45
|
-
factored = s.instance_exec(&block)
|
46
|
-
@_data = @_data.dup.merge(key => factored).freeze
|
47
|
-
[key, false]
|
48
|
-
else
|
49
|
-
nil
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end # class World
|
53
|
-
end # module Support
|
54
|
-
end # module Startback
|
data/lib/startback/support.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Support
|
3
|
-
|
4
|
-
def logger
|
5
|
-
Startback::LOGGER
|
6
|
-
end
|
7
|
-
|
8
|
-
def deep_merge(h1, h2)
|
9
|
-
h1.merge(h2){|k,v1,v2|
|
10
|
-
v1.is_a?(Hash) && v2.is_a?(Hash) ? deep_merge(v1, v2) : v2
|
11
|
-
}
|
12
|
-
end
|
13
|
-
module_function :deep_merge
|
14
|
-
|
15
|
-
end # module Support
|
16
|
-
end # module Startback
|
17
|
-
require_relative 'support/env'
|
18
|
-
require_relative 'support/log_formatter'
|
19
|
-
require_relative 'support/logger'
|
20
|
-
require_relative 'support/robustness'
|
21
|
-
require_relative 'support/hooks'
|
22
|
-
require_relative 'support/operation_runner'
|
23
|
-
require_relative 'support/transaction_policy'
|
24
|
-
require_relative 'support/transaction_manager'
|
25
|
-
require_relative 'support/data_object'
|
26
|
-
require_relative 'support/world'
|
data/lib/startback/version.rb
DELETED
data/lib/startback/web/api.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
class Api < Sinatra::Base
|
4
|
-
include Support
|
5
|
-
include Errors
|
6
|
-
|
7
|
-
set :raise_errors, true
|
8
|
-
set :show_exceptions, false
|
9
|
-
set :dump_errors, false
|
10
|
-
|
11
|
-
protected
|
12
|
-
|
13
|
-
###
|
14
|
-
### Facade over context
|
15
|
-
###
|
16
|
-
|
17
|
-
def context
|
18
|
-
env[Startback::Context::Middleware::RACK_ENV_KEY]
|
19
|
-
end
|
20
|
-
|
21
|
-
def with_context(ctx = nil)
|
22
|
-
old_context = self.context
|
23
|
-
new_context = ctx || self.context.dup
|
24
|
-
env[Startback::Context::Middleware::RACK_ENV_KEY] = new_context
|
25
|
-
result = ctx ? yield : yield(new_context)
|
26
|
-
env[Startback::Context::Middleware::RACK_ENV_KEY] = old_context
|
27
|
-
result
|
28
|
-
end
|
29
|
-
|
30
|
-
###
|
31
|
-
### Facade over third party tools
|
32
|
-
###
|
33
|
-
include Support::OperationRunner
|
34
|
-
|
35
|
-
def operation_world(op)
|
36
|
-
{ context: context }
|
37
|
-
end
|
38
|
-
|
39
|
-
###
|
40
|
-
### About the body / input
|
41
|
-
###
|
42
|
-
|
43
|
-
def loaded_body
|
44
|
-
@loaded_body ||= case ctype = request.content_type
|
45
|
-
when /json/
|
46
|
-
json_body
|
47
|
-
when /multipart\/form-data/
|
48
|
-
file = params[:file]
|
49
|
-
file_body file, Path(file[:filename]).extname
|
50
|
-
else
|
51
|
-
unsupported_media_type_error!(ctype)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def json_body(body = request.body.read)
|
56
|
-
JSON.load(body)
|
57
|
-
end
|
58
|
-
|
59
|
-
def file_body(file, ctype)
|
60
|
-
raise UnsupportedMediaTypeError, "Unable to use `#{ctype}` as input data"
|
61
|
-
end
|
62
|
-
|
63
|
-
###
|
64
|
-
### Various reusable responses
|
65
|
-
###
|
66
|
-
|
67
|
-
def serve_nothing
|
68
|
-
[ 204, {}, [] ]
|
69
|
-
end
|
70
|
-
|
71
|
-
def serve(entity_description, entity, ct = nil)
|
72
|
-
if entity.nil?
|
73
|
-
status 404
|
74
|
-
content_type :json
|
75
|
-
{ description: "#{entity_description} not found" }.to_json
|
76
|
-
elsif entity.respond_to?(:to_dto)
|
77
|
-
ct, body = entity.to_dto(context).to(env['HTTP_ACCEPT'], ct)
|
78
|
-
content_type ct
|
79
|
-
_serve(body)
|
80
|
-
elsif entity.is_a?(Path)
|
81
|
-
_serve(entity)
|
82
|
-
else
|
83
|
-
content_type ct || "application/json"
|
84
|
-
entity.to_json
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def _serve(body)
|
89
|
-
case body
|
90
|
-
when Path
|
91
|
-
send_file(body)
|
92
|
-
else
|
93
|
-
body
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
end # class Api
|
98
|
-
end # module Web
|
99
|
-
end # module Startback
|
@@ -1,85 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
#
|
4
|
-
# This rack middleware automatically mark response as non being cacheable
|
5
|
-
# in development, and being cacheble in production.
|
6
|
-
#
|
7
|
-
# The headers to set in development and production can be passed at
|
8
|
-
# construction, as well as whether the development environment must be
|
9
|
-
# forced. This class may also be configured through environment variables:
|
10
|
-
#
|
11
|
-
# - RACK_ENV: when "production" use the production headers, otherwise use
|
12
|
-
# the development ones
|
13
|
-
# - STARTBACK_AUTOCACHING_DEVELOPMENT_CACHE_CONTROL: Cache-Control header
|
14
|
-
# to use in development mode
|
15
|
-
# - STARTBACK_AUTOCACHING_PRODUCTION_CACHE_CONTROL: Cache-Control header
|
16
|
-
# to use in production mode
|
17
|
-
#
|
18
|
-
# Example:
|
19
|
-
#
|
20
|
-
# # Default configuration
|
21
|
-
# use Autocaching
|
22
|
-
#
|
23
|
-
# # Force development mode
|
24
|
-
# use Autocaching, true
|
25
|
-
#
|
26
|
-
# # Force production mode
|
27
|
-
# use Autocaching, false
|
28
|
-
#
|
29
|
-
# # Set production headers manually
|
30
|
-
# use Autocaching, { :production => "public, no-cache, no-store" }
|
31
|
-
#
|
32
|
-
class AutoCaching
|
33
|
-
|
34
|
-
# Cache-Control header to use in development mode
|
35
|
-
DEVELOPMENT_CACHE_CONTROL = ENV['STARTBACK_AUTOCACHING_DEVELOPMENT_CACHE_CONTROL'] || \
|
36
|
-
"no-cache, no-store, max-age=0, must-revalidate"
|
37
|
-
|
38
|
-
# Cache-Control header to use in produdction mode
|
39
|
-
PRODUCTION_CACHE_CONTROL = ENV['STARTBACK_AUTOCACHING_PRODUCTION_CACHE_CONTROL'] ||\
|
40
|
-
"public, must-revalidate, max-age=3600, s-max-age=3600"
|
41
|
-
|
42
|
-
def initialize(app, development = nil, cache_headers = {})
|
43
|
-
development, cache_headers = nil, development if development.is_a?(Hash)
|
44
|
-
@app = app
|
45
|
-
@development = development.nil? ? infer_is_development : development
|
46
|
-
@cache_headers = default_headers.merge(normalize_headers(cache_headers))
|
47
|
-
end
|
48
|
-
|
49
|
-
def call(env)
|
50
|
-
status, headers, body = @app.call(env)
|
51
|
-
[status, patch_response_headers(headers), body]
|
52
|
-
end
|
53
|
-
|
54
|
-
protected
|
55
|
-
|
56
|
-
def patch_response_headers(hs)
|
57
|
-
(development? ? @cache_headers[:development] : @cache_headers[:production]).merge(hs)
|
58
|
-
end
|
59
|
-
|
60
|
-
def development?
|
61
|
-
!!@development
|
62
|
-
end
|
63
|
-
|
64
|
-
def infer_is_development
|
65
|
-
ENV['RACK_ENV'] != "production"
|
66
|
-
end
|
67
|
-
|
68
|
-
def default_headers
|
69
|
-
{
|
70
|
-
development: {
|
71
|
-
"Cache-Control" => DEVELOPMENT_CACHE_CONTROL
|
72
|
-
},
|
73
|
-
production: {
|
74
|
-
"Cache-Control" => PRODUCTION_CACHE_CONTROL
|
75
|
-
}
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
def normalize_headers(h)
|
80
|
-
Hash[h.map{|k,v| [k, v.is_a?(Hash) ? v : {"Cache-Control" => v} ] }]
|
81
|
-
end
|
82
|
-
|
83
|
-
end # class AutoCaching
|
84
|
-
end # module Web
|
85
|
-
end # module Startback
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
#
|
4
|
-
# This Rack middleware catches all exceptions that are raised by sublayers
|
5
|
-
# in the Rack chain. It converts them to correct 500 Errors, with a generic
|
6
|
-
# exception message encoded in json.
|
7
|
-
#
|
8
|
-
# This class aims at being used as top level of a Rack chain. It is not
|
9
|
-
# aimed at being subclassed.
|
10
|
-
#
|
11
|
-
# Fatal error cached are also sent as a `fatal` messange, on the error
|
12
|
-
# handler provided on Context#error_handler.fatal, if any.
|
13
|
-
#
|
14
|
-
# Examples:
|
15
|
-
#
|
16
|
-
# Rack::Builder.new do
|
17
|
-
# use Startback::Web::CatchAll
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
class CatchAll < Rack::Robustness
|
21
|
-
include Errors
|
22
|
-
include Support::Robustness
|
23
|
-
|
24
|
-
FATAL_ERROR = {
|
25
|
-
code: "Startback::Errors::InternalServerError",
|
26
|
-
description: "An error occured, sorry"
|
27
|
-
}.to_json
|
28
|
-
|
29
|
-
self.catch_all
|
30
|
-
self.on(Exception)
|
31
|
-
self.status 500
|
32
|
-
self.content_type 'application/json'
|
33
|
-
self.body FATAL_ERROR
|
34
|
-
|
35
|
-
self.ensure(true) do |ex|
|
36
|
-
context = env[Context::Middleware::RACK_ENV_KEY]
|
37
|
-
begin
|
38
|
-
if context && context.respond_to?(:error_handler, true) && context.error_handler
|
39
|
-
context.error_handler.fatal(ex)
|
40
|
-
else
|
41
|
-
log(:fatal, self, "ensure", context, error: ex)
|
42
|
-
end
|
43
|
-
rescue => ex2
|
44
|
-
STDERR.puts(ex2.message)
|
45
|
-
STDERR.puts(ex2.backtrace[0..10].join("\n"))
|
46
|
-
raise
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end # class CatchAll
|
51
|
-
end # class Web
|
52
|
-
end # module Startback
|
@@ -1,80 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
#
|
4
|
-
# Sets Cross-Origin Response Headers on requests specifying an Origin
|
5
|
-
# HTTP header, according configuration passed at construction and/or
|
6
|
-
# environment variables.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
#
|
10
|
-
# # Default configuration, using environment variables when set
|
11
|
-
# use CorsHeaders
|
12
|
-
#
|
13
|
-
# # Force a bouncing of the origin, using the Origin request header
|
14
|
-
# # as Access-Control-Allow-Origin response header
|
15
|
-
# use CorsHeaders, bounce: true
|
16
|
-
#
|
17
|
-
# # Overrides a specific header
|
18
|
-
# use CorsHeaders, headers: { 'Access-Control-Allow-Methods' => 'POST' }
|
19
|
-
#
|
20
|
-
class CorsHeaders
|
21
|
-
|
22
|
-
ALLOW_ORIGIN = ENV['STARTBACK_CORS_ALLOW_ORIGIN'] || '*'
|
23
|
-
|
24
|
-
ALLOW_METHODS = ENV['STARTBACK_CORS_ALLOW_METHODS'] || 'OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE'
|
25
|
-
|
26
|
-
ALLOW_CREDENTIALS = ENV['STARTBACK_CORS_ALLOW_CREDENTIALS'] || 'true'
|
27
|
-
|
28
|
-
MAX_AGE = ENV['STARTBACK_CORS_MAX_AGE'] || '1728000'
|
29
|
-
|
30
|
-
ALLOW_HEADERS = ENV['STARTBACK_CORS_ALLOW_HEADERS'] || 'Authorization, Content-Type, Origin, Accept, If-Modified-Since, If-Match, If-None-Match'
|
31
|
-
|
32
|
-
EXPOSE_HEADERS = ENV['STARTBACK_CORS_EXPOSE_HEADERS'] || 'Location, ETag, Last-Modified, Content-Type'
|
33
|
-
|
34
|
-
DEFAULT_CORS_HEADERS = {
|
35
|
-
'Access-Control-Allow-Origin' => ALLOW_ORIGIN,
|
36
|
-
'Access-Control-Allow-Methods' => ALLOW_METHODS,
|
37
|
-
'Access-Control-Allow-Credentials' => ALLOW_CREDENTIALS,
|
38
|
-
'Access-Control-Max-Age' => MAX_AGE,
|
39
|
-
'Access-Control-Allow-Headers' => ALLOW_HEADERS,
|
40
|
-
'Access-Control-Expose-Headers' => EXPOSE_HEADERS
|
41
|
-
}
|
42
|
-
|
43
|
-
DEFAULT_OPTIONS = {
|
44
|
-
:headers => DEFAULT_CORS_HEADERS
|
45
|
-
}
|
46
|
-
|
47
|
-
def initialize(app, options = {})
|
48
|
-
@app = app
|
49
|
-
@options = Startback::Support.deep_merge(DEFAULT_OPTIONS, options)
|
50
|
-
end
|
51
|
-
|
52
|
-
def call(env)
|
53
|
-
status, headers, body = @app.call(env)
|
54
|
-
if origin = env['HTTP_ORIGIN']
|
55
|
-
headers = cors_headers(origin).merge(headers)
|
56
|
-
end
|
57
|
-
if env['REQUEST_METHOD'] == 'OPTIONS'
|
58
|
-
headers['Content-Length'] = '0'
|
59
|
-
status, headers, body = [204, headers, []]
|
60
|
-
end
|
61
|
-
[status, headers, body]
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def cors_headers(origin)
|
67
|
-
headers = @options[:headers].dup
|
68
|
-
if bounce?
|
69
|
-
headers['Access-Control-Allow-Origin'] = origin
|
70
|
-
end
|
71
|
-
headers
|
72
|
-
end
|
73
|
-
|
74
|
-
def bounce?
|
75
|
-
@options[:bounce]
|
76
|
-
end
|
77
|
-
|
78
|
-
end # class AllowCors
|
79
|
-
end # class CorsHeaders
|
80
|
-
end # module Samback
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
#
|
4
|
-
# Can be used to easily implement a HealthCheck web service inside a Startback
|
5
|
-
# application.
|
6
|
-
#
|
7
|
-
# Examples:
|
8
|
-
#
|
9
|
-
# # Returns a 204 with no body
|
10
|
-
# run Startback::Web::HealthCheck.new
|
11
|
-
#
|
12
|
-
# # Returns a 204 with no body
|
13
|
-
# run Startback::Web::HealthCheck.new { nil }
|
14
|
-
#
|
15
|
-
# # Returns a 200 with Ok in plain text
|
16
|
-
# run Startback::Web::HealthCheck.new { "Ok" }
|
17
|
-
#
|
18
|
-
# # Re-raises the exception
|
19
|
-
# run Startback::Web::HealthCheck.new { raise "Something bad" }
|
20
|
-
#
|
21
|
-
# Please note that this rack app is not 100% Rack compliant, since it raises
|
22
|
-
# any error that the block itself raises. This class aims at being backed up
|
23
|
-
# by a Shield and/or CatchAll middleware.
|
24
|
-
#
|
25
|
-
# This class is not aimed at being subclassed.
|
26
|
-
#
|
27
|
-
class HealthCheck
|
28
|
-
|
29
|
-
def initialize(&bl)
|
30
|
-
@checker = bl
|
31
|
-
end
|
32
|
-
|
33
|
-
def call(env)
|
34
|
-
if debug_msg = check!(env)
|
35
|
-
[ 200, { "Content-Type" => "text/plain" }, Array(debug_msg) ]
|
36
|
-
else
|
37
|
-
[ 204, {}, [] ]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
def check!(env)
|
44
|
-
@checker.call if @checker
|
45
|
-
end
|
46
|
-
|
47
|
-
end # class HealthCheck
|
48
|
-
end # module Web
|
49
|
-
end # module Startback
|
@@ -1,80 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
class MagicAssets
|
4
|
-
#
|
5
|
-
# Plugin for MagicAssets that compiles .html angular templates in the
|
6
|
-
# assets structure to javascript files filling angular's template cache.
|
7
|
-
#
|
8
|
-
# Heavily inspired, yet over-simplified version, of angular-rails-templates
|
9
|
-
# See https://github.com/pitr/angular-rails-templates, licensed under MIT
|
10
|
-
#
|
11
|
-
# Example:
|
12
|
-
#
|
13
|
-
# use Startback::Web::MagicAssets, {
|
14
|
-
# plugins: [Startback::Web::MagicAssets::NgHtmlTransfomer.new]
|
15
|
-
# }
|
16
|
-
#
|
17
|
-
class NgHtmlTransformer
|
18
|
-
|
19
|
-
DEFAULT_OPTIONS = {
|
20
|
-
:path => '/assets',
|
21
|
-
:ng_module => 'templates',
|
22
|
-
:mime_type => 'text/ng-html',
|
23
|
-
:extensions => [".html"]
|
24
|
-
}
|
25
|
-
|
26
|
-
def initialize(options = {})
|
27
|
-
@options = DEFAULT_OPTIONS.merge(options)
|
28
|
-
end
|
29
|
-
attr_reader :options
|
30
|
-
|
31
|
-
def install(sprockets)
|
32
|
-
sprockets.register_mime_type options[:mime_type], extensions: options[:extensions]
|
33
|
-
sprockets.register_transformer options[:mime_type], 'application/javascript', self
|
34
|
-
end
|
35
|
-
|
36
|
-
TPL = <<-EOF
|
37
|
-
angular.module("<%= ng_module %>").run(["$templateCache", function($templateCache) {
|
38
|
-
$templateCache.put("<%= angular_template_name %>", <%= html %>)
|
39
|
-
}]);
|
40
|
-
EOF
|
41
|
-
|
42
|
-
# inspired by Rails' action_view/helpers/javascript_helper.rb
|
43
|
-
JS_ESCAPE_MAP = {
|
44
|
-
'\\' => '\\\\',
|
45
|
-
"\r\n" => '\n',
|
46
|
-
"\n" => '\n',
|
47
|
-
"\r" => '\n',
|
48
|
-
'"' => '\\"',
|
49
|
-
"'" => "\\'"
|
50
|
-
}
|
51
|
-
|
52
|
-
# We want to deliver the shortist valid javascript escaped string
|
53
|
-
# Count the number of " vs '
|
54
|
-
# If more ', escape "
|
55
|
-
# If more ", escape '
|
56
|
-
# If equal, prefer to escape "
|
57
|
-
|
58
|
-
def escape_javascript(raw)
|
59
|
-
if raw
|
60
|
-
quote = raw.count(%{'}) >= raw.count(%{"}) ? %{"} : %{'}
|
61
|
-
escaped = raw.gsub(/(\\|\r\n|[\n\r#{quote}])/u) {|match| JS_ESCAPE_MAP[match] }
|
62
|
-
"#{quote}#{escaped}#{quote}"
|
63
|
-
else
|
64
|
-
'""'
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def call(input)
|
69
|
-
file_path = input[:filename]
|
70
|
-
angular_template_name = "#{options[:path]}/#{input[:name]}.html"
|
71
|
-
source_file = file_path
|
72
|
-
ng_module = options[:ng_module]
|
73
|
-
html = escape_javascript(input[:data].chomp)
|
74
|
-
ERB.new(TPL).result(binding)
|
75
|
-
end
|
76
|
-
|
77
|
-
end # class NgHtmlTransformer
|
78
|
-
end # class MagicAssets
|
79
|
-
end # module Web
|
80
|
-
end # module Startback
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module Startback
|
2
|
-
module Web
|
3
|
-
class MagicAssets
|
4
|
-
class RakeTasks
|
5
|
-
|
6
|
-
DEFAULT_OPTIONS = {
|
7
|
-
:namespace => :assets
|
8
|
-
}
|
9
|
-
|
10
|
-
def initialize(rake, options)
|
11
|
-
@rake = rake
|
12
|
-
@options = DEFAULT_OPTIONS.merge(options)
|
13
|
-
install
|
14
|
-
end
|
15
|
-
attr_reader :rake, :options
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def install
|
20
|
-
require 'securerandom'
|
21
|
-
|
22
|
-
ns = options[:namespace]
|
23
|
-
target_folder = options[:target]
|
24
|
-
assets = options[:assets]
|
25
|
-
assets = MagicAssets.new(assets) if assets.is_a?(Hash)
|
26
|
-
version = SecureRandom.urlsafe_base64
|
27
|
-
|
28
|
-
rake.instance_exec do
|
29
|
-
namespace(ns) do
|
30
|
-
|
31
|
-
desc 'Cleans generated assets'
|
32
|
-
task :clean do
|
33
|
-
FileUtils.rm_rf target_folder
|
34
|
-
end
|
35
|
-
|
36
|
-
task :prepare do
|
37
|
-
FileUtils.mkdir_p target_folder
|
38
|
-
(target_folder/"VERSION").write(version)
|
39
|
-
end
|
40
|
-
|
41
|
-
desc 'compile javascript assets'
|
42
|
-
task :compile_js do
|
43
|
-
assets['vendor.js'].write_to(target_folder/"vendor-#{version}.min.js")
|
44
|
-
assets['app.js'].write_to(target_folder/"app-#{version}.min.js")
|
45
|
-
puts "successfully compiled js assets"
|
46
|
-
end
|
47
|
-
|
48
|
-
desc 'compile css assets'
|
49
|
-
task :compile_css do
|
50
|
-
assets['vendor.css'].write_to(target_folder/"vendor-#{version}.min.css")
|
51
|
-
assets['app.css'].write_to(target_folder/"app-#{version}.min.css")
|
52
|
-
puts "successfully compiled css assets"
|
53
|
-
end
|
54
|
-
|
55
|
-
desc 'compile assets'
|
56
|
-
task :compile => [:clean, :prepare, :compile_js, :compile_css]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
end # class MagicAssets
|
63
|
-
end # module Web
|
64
|
-
end # module Startback
|