serviceworker-rails 0.5.5 → 0.7.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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +66 -0
- data/.github/workflows/release.yml +31 -0
- data/.gitignore +4 -3
- data/.node-version +1 -0
- data/.rubocop.yml +18 -91
- data/.ruby-version +1 -0
- data/.standard.yml +1 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +8 -6
- data/Gemfile.lock +355 -0
- data/Guardfile +5 -3
- data/README.md +6 -5
- data/Rakefile +19 -5
- data/bin/_guard-core +2 -1
- data/bin/console +1 -0
- data/bin/guard +2 -1
- data/bin/rake +3 -1
- data/bin/rubocop +3 -1
- data/bin/setup +4 -1
- data/bin/standardrb +29 -0
- data/gemfiles/rails_7.0.gemfile +12 -0
- data/gemfiles/rails_7.0.gemfile.lock +324 -0
- data/gemfiles/rails_7.1.gemfile +12 -0
- data/gemfiles/rails_7.1.gemfile.lock +348 -0
- data/gemfiles/rails_8.0.gemfile +12 -0
- data/gemfiles/rails_8.0.gemfile.lock +479 -0
- data/gemfiles/rails_8.1.gemfile +12 -0
- data/gemfiles/rails_8.1.gemfile.lock +486 -0
- data/gemfiles/rails_8.1_rack3.gemfile +20 -0
- data/gemfiles/rails_8.1_rack3.gemfile.lock +485 -0
- data/lib/assets/images/convert.rb +4 -0
- data/lib/assets/images/serviceworker-rails/heart-144x144.png +0 -0
- data/lib/assets/images/serviceworker-rails/heart-384x384.png +0 -0
- data/lib/generators/serviceworker/install_generator.rb +4 -20
- data/lib/generators/serviceworker/templates/serviceworker-companion.js +10 -5
- data/lib/generators/serviceworker/templates/serviceworker.js +3 -3
- data/lib/generators/serviceworker/templates/serviceworker.rb +2 -0
- data/lib/service_worker.rb +2 -0
- data/lib/serviceworker/engine.rb +3 -2
- data/lib/serviceworker/handlers/rack_handler.rb +35 -0
- data/lib/serviceworker/{rails/handler.rb → handlers/sprockets_handler.rb} +14 -5
- data/lib/serviceworker/handlers.rb +64 -0
- data/lib/serviceworker/middleware.rb +16 -14
- data/lib/serviceworker/rails/version.rb +2 -1
- data/lib/serviceworker/rails.rb +2 -1
- data/lib/serviceworker/route.rb +28 -23
- data/lib/serviceworker/router.rb +9 -9
- data/lib/serviceworker-rails.rb +2 -1
- data/lib/serviceworker.rb +2 -0
- data/serviceworker-rails.gemspec +28 -19
- metadata +163 -41
- data/.travis.yml +0 -10
- data/Appraisals +0 -12
- data/bin/appraisal +0 -17
- data/gemfiles/rails_3.gemfile +0 -15
- data/gemfiles/rails_4.gemfile +0 -14
- data/gemfiles/rails_5.gemfile +0 -14
- data/lib/serviceworker/handler.rb +0 -22
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require "rack/file"
|
|
3
2
|
|
|
4
3
|
module ServiceWorker
|
|
5
|
-
module
|
|
6
|
-
class
|
|
4
|
+
module Handlers
|
|
5
|
+
class SprocketsHandler
|
|
7
6
|
def call(env)
|
|
8
7
|
path_info = env.fetch("serviceworker.asset_name")
|
|
9
8
|
|
|
@@ -14,14 +13,24 @@ module ServiceWorker
|
|
|
14
13
|
end
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
private
|
|
18
17
|
|
|
19
18
|
def sprockets_server
|
|
20
19
|
::Rails.application.assets
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def file_server
|
|
24
|
-
@file_server ||=
|
|
23
|
+
@file_server ||= rack_files_class.new(::Rails.public_path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def rack_files_class
|
|
27
|
+
@rack_files_class ||= begin
|
|
28
|
+
require "rack/files"
|
|
29
|
+
::Rack::Files
|
|
30
|
+
rescue LoadError
|
|
31
|
+
require "rack/file"
|
|
32
|
+
::Rack::File
|
|
33
|
+
end
|
|
25
34
|
end
|
|
26
35
|
|
|
27
36
|
def config
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "serviceworker/handlers/rack_handler"
|
|
4
|
+
|
|
5
|
+
module ServiceWorker
|
|
6
|
+
module Handlers
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def build(handler)
|
|
10
|
+
resolve_handler(handler) || default_handler
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def handler_for_route_match(route_match)
|
|
14
|
+
options = route_match.options
|
|
15
|
+
return sprockets_handler if Route.sprockets?(options)
|
|
16
|
+
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ===(other)
|
|
21
|
+
other.respond_to?(:call)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def handler_for_name(name)
|
|
25
|
+
available_handlers = %w[sprockets rack]
|
|
26
|
+
if available_handlers.include?(name.to_s)
|
|
27
|
+
send(:"#{name}_handler")
|
|
28
|
+
else
|
|
29
|
+
raise ServiceWorker::Error,
|
|
30
|
+
"Unknown handler #{name.inspect}. Please use one of #{available_handlers.inspect}"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def resolve_handler(handler)
|
|
35
|
+
case handler
|
|
36
|
+
when Handlers
|
|
37
|
+
handler
|
|
38
|
+
when Symbol, String
|
|
39
|
+
handler_for_name(handler)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sprockets_handler
|
|
44
|
+
require "serviceworker/handlers/sprockets_handler"
|
|
45
|
+
ServiceWorker::Handlers::SprocketsHandler.new
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def rack_handler
|
|
49
|
+
ServiceWorker::Handlers::RackHandler.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def default_handler
|
|
53
|
+
if sprockets?
|
|
54
|
+
sprockets_handler
|
|
55
|
+
else
|
|
56
|
+
rack_handler
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def sprockets?
|
|
61
|
+
defined?(::Rails) && ::Rails.configuration.assets
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "serviceworker/handlers"
|
|
4
|
+
|
|
2
5
|
module ServiceWorker
|
|
3
6
|
class Middleware
|
|
4
|
-
REQUEST_METHOD = "REQUEST_METHOD"
|
|
5
|
-
GET = "GET"
|
|
6
|
-
HEAD = "HEAD"
|
|
7
|
+
REQUEST_METHOD = "REQUEST_METHOD"
|
|
8
|
+
GET = "GET"
|
|
9
|
+
HEAD = "HEAD"
|
|
7
10
|
|
|
8
11
|
# Initialize the Rack middleware for responding to serviceworker asset
|
|
9
12
|
# requests
|
|
@@ -17,14 +20,14 @@ module ServiceWorker
|
|
|
17
20
|
def initialize(app, opts = {})
|
|
18
21
|
@app = app
|
|
19
22
|
@opts = opts
|
|
20
|
-
@headers = opts.fetch(:headers, {})
|
|
23
|
+
@headers = default_headers.merge(opts.fetch(:headers, {}))
|
|
21
24
|
@router = opts.fetch(:routes, ServiceWorker::Router.new)
|
|
22
|
-
@handler = @opts.fetch(:handler,
|
|
25
|
+
@handler = Handlers.build(@opts.fetch(:handler, nil))
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def call(env)
|
|
26
29
|
case env[REQUEST_METHOD]
|
|
27
|
-
|
|
30
|
+
when GET, HEAD
|
|
28
31
|
route_match = @router.match_route(env)
|
|
29
32
|
return respond_to_match(route_match, env) if route_match
|
|
30
33
|
end
|
|
@@ -32,7 +35,7 @@ module ServiceWorker
|
|
|
32
35
|
@app.call(env)
|
|
33
36
|
end
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
private
|
|
36
39
|
|
|
37
40
|
def default_headers
|
|
38
41
|
{
|
|
@@ -43,22 +46,21 @@ module ServiceWorker
|
|
|
43
46
|
def respond_to_match(route_match, env)
|
|
44
47
|
env = env.merge("serviceworker.asset_name" => route_match.asset_name)
|
|
45
48
|
|
|
46
|
-
status, headers, body =
|
|
49
|
+
status, headers, body = handler_for_route_match(route_match).call(env)
|
|
47
50
|
|
|
48
51
|
[status, headers.merge(@headers).merge(route_match.headers), body]
|
|
49
52
|
end
|
|
50
53
|
|
|
54
|
+
def handler_for_route_match(route_match)
|
|
55
|
+
Handlers.handler_for_route_match(route_match) || @handler
|
|
56
|
+
end
|
|
57
|
+
|
|
51
58
|
def info(msg)
|
|
52
59
|
logger.info "[#{self.class}] - #{msg}"
|
|
53
60
|
end
|
|
54
61
|
|
|
55
62
|
def logger
|
|
56
|
-
@logger ||= @opts.fetch(:logger, Logger.new(
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def default_handler
|
|
60
|
-
require "serviceworker/handler"
|
|
61
|
-
ServiceWorker::Handler.new
|
|
63
|
+
@logger ||= @opts.fetch(:logger, Logger.new($stdout))
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
end
|
data/lib/serviceworker/rails.rb
CHANGED
data/lib/serviceworker/route.rb
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module ServiceWorker
|
|
3
4
|
class Route
|
|
4
5
|
attr_reader :path_pattern, :asset_pattern, :options
|
|
5
6
|
|
|
6
|
-
RouteMatch = Struct.new(:path, :asset_name, :headers) do
|
|
7
|
+
RouteMatch = Struct.new(:path, :asset_name, :headers, :options) do
|
|
7
8
|
def to_s
|
|
8
9
|
asset_name
|
|
9
10
|
end
|
|
10
11
|
end
|
|
11
12
|
|
|
13
|
+
def self.sprockets?(options)
|
|
14
|
+
options.key?(:asset)
|
|
15
|
+
end
|
|
16
|
+
|
|
12
17
|
def initialize(path_pattern, asset_pattern = nil, options = {})
|
|
13
18
|
if asset_pattern.is_a?(Hash)
|
|
14
19
|
options = asset_pattern
|
|
@@ -16,16 +21,16 @@ module ServiceWorker
|
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
@path_pattern = path_pattern
|
|
19
|
-
@asset_pattern = asset_pattern || options
|
|
24
|
+
@asset_pattern = asset_pattern || options.fetch(:asset, path_pattern)
|
|
20
25
|
@options = options
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def match(path)
|
|
24
29
|
raise ArgumentError, "path is required" if path.to_s.strip.empty?
|
|
25
30
|
|
|
26
|
-
asset = resolver.call(path)
|
|
31
|
+
(asset = resolver.call(path)) || (return nil)
|
|
27
32
|
|
|
28
|
-
RouteMatch.new(path, asset, headers)
|
|
33
|
+
RouteMatch.new(path, asset, headers, options)
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
def headers
|
|
@@ -39,14 +44,14 @@ module ServiceWorker
|
|
|
39
44
|
end
|
|
40
45
|
|
|
41
46
|
class AssetResolver
|
|
42
|
-
PATH_INFO = "PATH_INFO"
|
|
47
|
+
PATH_INFO = "PATH_INFO"
|
|
43
48
|
DEFAULT_WILDCARD_NAME = :paths
|
|
44
|
-
WILDCARD_PATTERN = %r{
|
|
45
|
-
NAMED_SEGMENTS_PATTERN = %r{
|
|
46
|
-
LEADING_SLASH_PATTERN = %r{
|
|
49
|
+
WILDCARD_PATTERN = %r{/\*([^/]*)}
|
|
50
|
+
NAMED_SEGMENTS_PATTERN = %r{/([^/]*):([^:$/]+)}
|
|
51
|
+
LEADING_SLASH_PATTERN = %r{^/}
|
|
47
52
|
INTERPOLATION_PATTERN = Regexp.union(
|
|
48
53
|
/%%/,
|
|
49
|
-
/%\{(\w+)\}
|
|
54
|
+
/%\{(\w+)\}/ # matches placeholders like "%{foo}"
|
|
50
55
|
)
|
|
51
56
|
|
|
52
57
|
attr_reader :path_pattern, :asset_pattern
|
|
@@ -59,7 +64,7 @@ module ServiceWorker
|
|
|
59
64
|
def call(path)
|
|
60
65
|
raise ArgumentError, "path is required" if path.to_s.strip.empty?
|
|
61
66
|
|
|
62
|
-
captures = path_captures(regexp, path)
|
|
67
|
+
(captures = path_captures(regexp, path)) || (return nil)
|
|
63
68
|
|
|
64
69
|
interpolate_captures(asset_pattern, captures)
|
|
65
70
|
end
|
|
@@ -79,28 +84,28 @@ module ServiceWorker
|
|
|
79
84
|
pattern_match = pattern.match(WILDCARD_PATTERN)
|
|
80
85
|
if pattern_match
|
|
81
86
|
@wildcard_name = if pattern_match[1].to_s.strip.empty?
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
DEFAULT_WILDCARD_NAME
|
|
88
|
+
else
|
|
89
|
+
pattern_match[1].to_sym
|
|
90
|
+
end
|
|
86
91
|
pattern.gsub(WILDCARD_PATTERN, "(?:/(.*)|)")
|
|
87
92
|
else
|
|
88
93
|
p = if pattern.match(NAMED_SEGMENTS_PATTERN)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^.$/]+)')
|
|
95
|
+
else
|
|
96
|
+
pattern
|
|
97
|
+
end
|
|
93
98
|
p + '(?:\.(?<format>.*))?'
|
|
94
99
|
end
|
|
95
100
|
end
|
|
96
101
|
|
|
97
102
|
def path_captures(regexp, path)
|
|
98
|
-
path_match = path.match(regexp)
|
|
103
|
+
(path_match = path.match(regexp)) || (return nil)
|
|
99
104
|
params = if @wildcard_name
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
{@wildcard_name => path_match[1].to_s.split("/")}
|
|
106
|
+
else
|
|
107
|
+
path_match.names.map(&:to_sym).zip(path_match.captures).to_h
|
|
108
|
+
end
|
|
104
109
|
params.delete(:format) if params.key?(:format) && params[:format].nil?
|
|
105
110
|
params
|
|
106
111
|
end
|
data/lib/serviceworker/router.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module ServiceWorker
|
|
3
4
|
class Router
|
|
4
|
-
PATH_INFO = "PATH_INFO"
|
|
5
|
+
PATH_INFO = "PATH_INFO"
|
|
5
6
|
|
|
6
7
|
def self.default
|
|
7
8
|
new.draw_default
|
|
@@ -9,14 +10,15 @@ module ServiceWorker
|
|
|
9
10
|
|
|
10
11
|
attr_reader :routes
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
# standard:disable Style/ArgumentsForwarding
|
|
14
|
+
def initialize(&block)
|
|
13
15
|
@routes = []
|
|
14
16
|
|
|
15
|
-
draw(&
|
|
17
|
+
draw(&block)
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def draw(&block)
|
|
19
|
-
return self unless
|
|
21
|
+
return self unless block
|
|
20
22
|
|
|
21
23
|
if block.arity == 1
|
|
22
24
|
yield(self)
|
|
@@ -26,6 +28,7 @@ module ServiceWorker
|
|
|
26
28
|
|
|
27
29
|
self
|
|
28
30
|
end
|
|
31
|
+
# standard:enable Style/ArgumentsForwarding
|
|
29
32
|
|
|
30
33
|
def draw_default
|
|
31
34
|
draw { get "/serviceworker.js" }
|
|
@@ -42,7 +45,7 @@ module ServiceWorker
|
|
|
42
45
|
@routes << route
|
|
43
46
|
end
|
|
44
47
|
end
|
|
45
|
-
|
|
48
|
+
alias_method :get, :match
|
|
46
49
|
|
|
47
50
|
def any?
|
|
48
51
|
@routes.any?
|
|
@@ -50,10 +53,7 @@ module ServiceWorker
|
|
|
50
53
|
|
|
51
54
|
def match_route(env)
|
|
52
55
|
path = env[PATH_INFO]
|
|
53
|
-
@routes.
|
|
54
|
-
match = route.match(path) and return match
|
|
55
|
-
end
|
|
56
|
-
nil
|
|
56
|
+
@routes.lazy.map { |route| route.match(path) }.detect(&:itself)
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
end
|
data/lib/serviceworker-rails.rb
CHANGED
data/lib/serviceworker.rb
CHANGED
data/serviceworker-rails.gemspec
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
require "serviceworker/rails/version"
|
|
5
6
|
|
|
6
7
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name
|
|
8
|
-
spec.version
|
|
9
|
-
spec.authors
|
|
10
|
-
spec.email
|
|
8
|
+
spec.name = "serviceworker-rails"
|
|
9
|
+
spec.version = ServiceWorker::Rails::VERSION
|
|
10
|
+
spec.authors = ["Ross Kaffenberger"]
|
|
11
|
+
spec.email = ["rosskaff@gmail.com"]
|
|
11
12
|
|
|
12
|
-
spec.summary
|
|
13
|
-
spec.description
|
|
14
|
-
spec.homepage
|
|
15
|
-
spec.license
|
|
13
|
+
spec.summary = "ServiceWorker for Rails 7+"
|
|
14
|
+
spec.description = "Integrates ServiceWorker into the Rails asset pipeline."
|
|
15
|
+
spec.homepage = "https://github.com/rossta/serviceworker-rails"
|
|
16
|
+
spec.license = "MIT"
|
|
16
17
|
|
|
17
|
-
spec.files
|
|
18
|
-
spec.bindir
|
|
19
|
-
spec.executables
|
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
19
|
+
spec.bindir = "exe"
|
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
21
|
spec.require_paths = ["lib"]
|
|
21
22
|
|
|
22
|
-
spec.add_dependency "railties",
|
|
23
|
+
spec.add_dependency "railties", ">= 7.0"
|
|
24
|
+
spec.add_dependency "rack", [">= 2.1"]
|
|
25
|
+
spec.add_dependency "logger"
|
|
26
|
+
spec.add_dependency "benchmark"
|
|
27
|
+
spec.add_dependency "bigdecimal"
|
|
28
|
+
spec.add_dependency "ostruct"
|
|
29
|
+
spec.add_dependency "mutex_m"
|
|
30
|
+
spec.add_dependency "drb"
|
|
31
|
+
spec.add_dependency "cgi"
|
|
23
32
|
|
|
24
|
-
spec.add_development_dependency "sprockets-rails"
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 1.11"
|
|
26
|
-
spec.add_development_dependency "rake", "~> 11.0"
|
|
27
33
|
spec.add_development_dependency "minitest", "~> 5.0"
|
|
28
34
|
spec.add_development_dependency "rack-test"
|
|
29
|
-
spec.add_development_dependency "rubocop", "0.46.0"
|
|
30
35
|
spec.add_development_dependency "rails"
|
|
31
|
-
spec.add_development_dependency "
|
|
36
|
+
spec.add_development_dependency "rake"
|
|
37
|
+
spec.add_development_dependency "parallel", "~> 1.27"
|
|
32
38
|
spec.add_development_dependency "simplecov"
|
|
39
|
+
spec.add_development_dependency "sprockets", "~> 3.0"
|
|
40
|
+
spec.add_development_dependency "sprockets-rails"
|
|
41
|
+
spec.add_development_dependency "standard"
|
|
33
42
|
end
|