paquette 0.1.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 (38) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +10 -0
  3. data/README.md +90 -0
  4. data/lib/paquette/gem_server/directory_gem_repository.rb +154 -0
  5. data/lib/paquette/gem_server/gem_repacker.rb +170 -0
  6. data/lib/paquette/gem_server/gem_repository.rb +53 -0
  7. data/lib/paquette/gem_server/personalizer.rb +66 -0
  8. data/lib/paquette/gem_server/read_gated_repository.rb +74 -0
  9. data/lib/paquette/gem_server.rb +393 -0
  10. data/lib/paquette/npm_repacker.rb +153 -0
  11. data/lib/paquette/npm_server/directory_npm_repository.rb +127 -0
  12. data/lib/paquette/npm_server/gated_npm_repository.rb +66 -0
  13. data/lib/paquette/npm_server/npm_repository.rb +53 -0
  14. data/lib/paquette/npm_server.rb +98 -0
  15. data/lib/paquette/routes.rb +78 -0
  16. data/lib/paquette/subdomain_router.rb +59 -0
  17. data/lib/paquette/version.rb +3 -0
  18. data/lib/paquette.rb +12 -0
  19. data/test/fixtures/gems/minuscule_test/minuscule_test-0.1.0.gem +0 -0
  20. data/test/fixtures/gems/zip_kit/zip_kit-6.2.0.gem +0 -0
  21. data/test/fixtures/gems/zip_kit/zip_kit-6.2.1.gem +0 -0
  22. data/test/fixtures/npm/react-dropzone/react-dropzone-14.3.8.tgz +0 -0
  23. data/test/gem_server/bundler_install_test.rb +86 -0
  24. data/test/gem_server/directory_gem_repository_test.rb +208 -0
  25. data/test/gem_server/gem_repacker_test.rb +289 -0
  26. data/test/gem_server/personalizer_metadata_test.rb +49 -0
  27. data/test/gem_server/personalizer_test.rb +66 -0
  28. data/test/gem_server/read_gated_repository_test.rb +254 -0
  29. data/test/gem_server/repository_stack_test.rb +71 -0
  30. data/test/gem_server_test.rb +339 -0
  31. data/test/npm_repacker_sourcemap_test.rb +108 -0
  32. data/test/npm_repacker_test.rb +117 -0
  33. data/test/npm_server_test.rb +140 -0
  34. data/test/routes_test.rb +142 -0
  35. data/test/subdomain_router_integration_test.rb +126 -0
  36. data/test/subdomain_router_test.rb +125 -0
  37. data/test/test_helper.rb +12 -0
  38. metadata +117 -0
@@ -0,0 +1,140 @@
1
+ require_relative "test_helper"
2
+
3
+ class NpmServerTest < Minitest::Test
4
+ include Rack::Test::Methods
5
+
6
+ def setup
7
+ # Create a temporary directory for test packages
8
+ @test_packages_dir = Dir.mktmpdir("paquette_npm_test")
9
+ @app = Paquette::NpmServer.new(@test_packages_dir)
10
+
11
+ # Create some test packages
12
+ create_test_packages
13
+ end
14
+
15
+ def teardown
16
+ FileUtils.rm_rf(@test_packages_dir) if @test_packages_dir
17
+ end
18
+
19
+ attr_reader :app
20
+
21
+ def test_root_endpoint
22
+ get "/"
23
+ assert_equal 200, last_response.status
24
+ assert_equal "Paquette NPM Repository", last_response.body
25
+ end
26
+
27
+ def test_ping_endpoint
28
+ get "/-/ping"
29
+ assert_equal 200, last_response.status
30
+ assert_equal "application/json", last_response.content_type
31
+
32
+ response = JSON.parse(last_response.body)
33
+ assert_equal({}, response)
34
+ end
35
+
36
+ def test_whoami_endpoint
37
+ get "/-/whoami"
38
+ assert_equal 200, last_response.status
39
+ assert_equal "application/json", last_response.content_type
40
+
41
+ response = JSON.parse(last_response.body)
42
+ assert_equal "paquette", response["username"]
43
+ end
44
+
45
+ def test_package_metadata
46
+ get "/test-package"
47
+ assert_equal 200, last_response.status
48
+ assert_equal "application/json", last_response.content_type
49
+
50
+ metadata = JSON.parse(last_response.body)
51
+ assert_equal "test-package", metadata["name"]
52
+ assert metadata["versions"].is_a?(Hash)
53
+ assert metadata["versions"].key?("1.0.0")
54
+ assert metadata["versions"].key?("1.1.0")
55
+ assert_equal "1.1.0", metadata["dist-tags"]["latest"]
56
+ assert metadata["time"].is_a?(Hash)
57
+ assert metadata["time"].key?("1.0.0")
58
+ assert metadata["time"].key?("1.1.0")
59
+ end
60
+
61
+ def test_package_metadata_nonexistent
62
+ get "/nonexistent-package"
63
+ assert_equal 404, last_response.status
64
+ end
65
+
66
+ def test_dist_tags
67
+ get "/-/package/test-package/dist-tags"
68
+ assert_equal 200, last_response.status
69
+ assert_equal "application/json", last_response.content_type
70
+
71
+ dist_tags = JSON.parse(last_response.body)
72
+ assert_equal "1.1.0", dist_tags["latest"]
73
+ end
74
+
75
+ def test_dist_tags_nonexistent
76
+ get "/-/package/nonexistent-package/dist-tags"
77
+ assert_equal 404, last_response.status
78
+ end
79
+
80
+ def test_package_download
81
+ get "/test-package/test-package-1.0.0.tgz"
82
+ assert_equal 200, last_response.status
83
+ assert_equal "application/octet-stream", last_response.content_type
84
+ assert last_response.body.length > 0
85
+ end
86
+
87
+ def test_package_download_nonexistent
88
+ get "/test-package/test-package-999.0.0.tgz"
89
+ assert_equal 404, last_response.status
90
+ end
91
+
92
+ def test_package_download_invalid_filename
93
+ get "/test-package/invalid-filename.tgz"
94
+ assert_equal 404, last_response.status
95
+ end
96
+
97
+ def test_multiple_packages
98
+ get "/another-package"
99
+ assert_equal 200, last_response.status
100
+
101
+ metadata = JSON.parse(last_response.body)
102
+ assert_equal "another-package", metadata["name"]
103
+ assert metadata["versions"].key?("2.0.0")
104
+ assert_equal "2.0.0", metadata["dist-tags"]["latest"]
105
+ end
106
+
107
+ def test_package_versions_structure
108
+ get "/test-package"
109
+ metadata = JSON.parse(last_response.body)
110
+
111
+ # Check version structure
112
+ version_1_0_0 = metadata["versions"]["1.0.0"]
113
+ assert_equal "test-package", version_1_0_0["name"]
114
+ assert_equal "1.0.0", version_1_0_0["version"]
115
+ assert version_1_0_0["dist"].is_a?(Hash)
116
+ assert_equal "test-package/test-package-1.0.0.tgz", version_1_0_0["dist"]["tarball"]
117
+
118
+ version_1_1_0 = metadata["versions"]["1.1.0"]
119
+ assert_equal "test-package", version_1_1_0["name"]
120
+ assert_equal "1.1.0", version_1_1_0["version"]
121
+ assert_equal "test-package/test-package-1.1.0.tgz", version_1_1_0["dist"]["tarball"]
122
+ end
123
+
124
+ private
125
+
126
+ def create_test_packages
127
+ # Create test-package with versions 1.0.0 and 1.1.0
128
+ package_dir = File.join(@test_packages_dir, "test-package")
129
+ FileUtils.mkdir_p(package_dir)
130
+
131
+ # Create dummy .tgz files
132
+ File.write(File.join(package_dir, "test-package-1.0.0.tgz"), "dummy tarball content 1.0.0")
133
+ File.write(File.join(package_dir, "test-package-1.1.0.tgz"), "dummy tarball content 1.1.0")
134
+
135
+ # Create another-package with version 2.0.0
136
+ another_package_dir = File.join(@test_packages_dir, "another-package")
137
+ FileUtils.mkdir_p(another_package_dir)
138
+ File.write(File.join(another_package_dir, "another-package-2.0.0.tgz"), "dummy tarball content 2.0.0")
139
+ end
140
+ end
@@ -0,0 +1,142 @@
1
+ require_relative "test_helper"
2
+
3
+ class RoutesTest < Minitest::Test
4
+ include Rack::Test::Methods
5
+
6
+ class TestApp
7
+ attr_reader :last_params, :last_action
8
+
9
+ def initialize
10
+ @last_params = nil
11
+ @last_action = nil
12
+ end
13
+
14
+ def call(env)
15
+ request = Rack::Request.new(env)
16
+
17
+ if (route = @routes.match(request))
18
+ @last_params = route.params(request)
19
+ @last_action = @routes.perform_action(route, self, request)
20
+ else
21
+ [404, {}, ["Not Found"]]
22
+ end
23
+ end
24
+
25
+ def setup_routes
26
+ @routes = Paquette::Routes.draw do |r|
27
+ r.get "/" do
28
+ [200, {}, ["Root"]]
29
+ end
30
+
31
+ r.get "/hello/:name" do |name:|
32
+ [200, {}, ["Hello #{name}"]]
33
+ end
34
+
35
+ r.get "/gem/stuff/:some_param.gz" do |some_param:|
36
+ [200, {}, ["Gem stuff with param: #{some_param}"]]
37
+ end
38
+
39
+ r.post "/api/data" do
40
+ [201, {}, ["Data created"]]
41
+ end
42
+
43
+ r.get "/api/version/:version" do |version:|
44
+ [200, {}, ["Version: #{version}"]]
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def setup
51
+ @app = TestApp.new
52
+ @app.setup_routes
53
+ end
54
+
55
+ attr_reader :app
56
+
57
+ def test_root_route
58
+ get "/"
59
+ assert_equal 200, last_response.status
60
+ assert_equal "Root", last_response.body
61
+ end
62
+
63
+ def test_hello_route_with_params
64
+ get "/hello/world"
65
+ assert_equal 200, last_response.status
66
+ assert_equal "Hello world", last_response.body
67
+ assert_equal "world", app.last_params["name"]
68
+ end
69
+
70
+ def test_gem_stuff_route_with_params
71
+ get "/gem/stuff/test-param.gz"
72
+ assert_equal 200, last_response.status
73
+ assert_equal "Gem stuff with param: test-param", last_response.body
74
+ assert_equal "test-param", app.last_params["some_param"]
75
+ end
76
+
77
+ def test_post_route
78
+ post "/api/data"
79
+ assert_equal 201, last_response.status
80
+ assert_equal "Data created", last_response.body
81
+ end
82
+
83
+ def test_version_route_with_params
84
+ get "/api/version/1.2.3"
85
+ assert_equal 200, last_response.status
86
+ assert_equal "Version: 1.2.3", last_response.body
87
+ assert_equal "1.2.3", app.last_params["version"]
88
+ end
89
+
90
+ def test_nonexistent_route
91
+ get "/nonexistent"
92
+ assert_equal 404, last_response.status
93
+ assert_equal "Not Found", last_response.body
94
+ end
95
+
96
+ def test_wrong_method
97
+ post "/hello/world"
98
+ assert_equal 404, last_response.status
99
+ assert_equal "Not Found", last_response.body
100
+ end
101
+
102
+ def test_routes_class_draw_method
103
+ routes = Paquette::Routes.draw do |r|
104
+ r.get "/test" do
105
+ [200, {}, ["Test"]]
106
+ end
107
+ end
108
+
109
+ assert_instance_of Paquette::Routes, routes
110
+ assert_equal 1, routes.instance_variable_get(:@routes).length
111
+ end
112
+
113
+ def test_route_builder_methods
114
+ routes = Paquette::Routes.draw do |r|
115
+ r.get("/get") { [200, {}, ["GET"]] }
116
+ r.post("/post") { [200, {}, ["POST"]] }
117
+ r.put("/put") { [200, {}, ["PUT"]] }
118
+ r.delete("/delete") { [200, {}, ["DELETE"]] }
119
+ r.patch("/patch") { [200, {}, ["PATCH"]] }
120
+ end
121
+
122
+ assert_equal 5, routes.instance_variable_get(:@routes).length
123
+ end
124
+
125
+ def test_instance_exec_in_route_blocks
126
+ test_instance = self
127
+
128
+ routes = Paquette::Routes.draw do |r|
129
+ r.get "/self-test" do
130
+ [200, {}, ["Instance: #{self.class}"]]
131
+ end
132
+ end
133
+
134
+ # Create a mock request
135
+ request = Rack::Request.new(Rack::MockRequest.env_for("/self-test"))
136
+ route = routes.match(request)
137
+
138
+ assert route
139
+ result = routes.perform_action(route, test_instance, request)
140
+ assert_equal [200, {}, ["Instance: RoutesTest"]], result
141
+ end
142
+ end
@@ -0,0 +1,126 @@
1
+ require_relative "test_helper"
2
+
3
+ class SubdomainRouterIntegrationTest < Minitest::Test
4
+ include Rack::Test::Methods
5
+
6
+ def setup
7
+ # No need to set environment variables since we use the packages directory structure
8
+ end
9
+
10
+ def app
11
+ # Load config.ru with the test fixtures dir so we don't depend on
12
+ # whatever a dev push may have left in packages/.
13
+ ENV["PAQUETTE_PACKAGES_DIR"] = File.expand_path("fixtures", __dir__)
14
+ Rack::Builder.parse_file(File.expand_path("../config.ru", __dir__))
15
+ end
16
+
17
+ def test_gem_subdomain_routing
18
+ get "/", {}, {"HTTP_HOST" => "gem.example.com"}
19
+ assert_equal 200, last_response.status
20
+ assert_equal "Paquette RubyGems Repository", last_response.body
21
+ end
22
+
23
+ def test_gem_subdomain_api_endpoints
24
+ get "/api/v1/names", {}, {"HTTP_HOST" => "gem.example.com"}
25
+ assert_equal 200, last_response.status
26
+ assert_equal "application/json", last_response.content_type
27
+
28
+ names = JSON.parse(last_response.body)
29
+ assert_equal ["minuscule_test", "zip_kit"], names.sort
30
+ end
31
+
32
+ def test_gem_subdomain_specs_endpoint
33
+ get "/specs.4.8", {}, {"HTTP_HOST" => "gem.example.com"}
34
+ assert_equal 200, last_response.status
35
+ assert_equal "application/octet-stream", last_response.content_type
36
+
37
+ specs = Marshal.load(last_response.body)
38
+ assert specs.is_a?(Array)
39
+ assert_equal 3, specs.length
40
+
41
+ gem_names = specs.map { |spec| spec[0] }.sort.uniq
42
+ assert_equal ["minuscule_test", "zip_kit"], gem_names
43
+ end
44
+
45
+ def test_npm_subdomain_routing
46
+ # Test that requests to npm.example.com are routed to NpmServer
47
+ get "/", {}, {"HTTP_HOST" => "npm.example.com"}
48
+ assert_equal 200, last_response.status
49
+ assert_equal "Paquette NPM Repository", last_response.body
50
+ end
51
+
52
+ def test_npm_subdomain_ping_endpoint
53
+ # Test that npm ping endpoint works with npm subdomain
54
+ get "/-/ping", {}, {"HTTP_HOST" => "npm.example.com"}
55
+ assert_equal 200, last_response.status
56
+ assert_equal "application/json", last_response.content_type
57
+
58
+ response = JSON.parse(last_response.body)
59
+ assert_equal({}, response)
60
+ end
61
+
62
+ def test_npm_subdomain_package_metadata
63
+ # Test that package metadata works with npm subdomain
64
+ get "/react-dropzone", {}, {"HTTP_HOST" => "npm.example.com"}
65
+ assert_equal 200, last_response.status
66
+ assert_equal "application/json", last_response.content_type
67
+
68
+ metadata = JSON.parse(last_response.body)
69
+ assert_equal "react-dropzone", metadata["name"]
70
+ assert metadata["versions"].is_a?(Hash)
71
+ assert metadata["versions"].key?("14.3.8")
72
+ end
73
+
74
+ def test_npm_subdomain_package_download
75
+ # Test that package download works with npm subdomain
76
+ get "/react-dropzone/react-dropzone-14.3.8.tgz", {}, {"HTTP_HOST" => "npm.example.com"}
77
+ assert_equal 200, last_response.status
78
+ assert_equal "application/octet-stream", last_response.content_type
79
+ assert last_response.body.length > 0
80
+ end
81
+
82
+ def test_unknown_subdomain_fallback
83
+ # Test that unknown subdomains get the fallback response
84
+ get "/", {}, {"HTTP_HOST" => "api.example.com"}
85
+ assert_equal 404, last_response.status
86
+ assert_equal "Need subdomain gem/npm", last_response.body
87
+ end
88
+
89
+ def test_no_subdomain_fallback
90
+ # Test that requests without subdomain get the fallback response
91
+ get "/", {}, {"HTTP_HOST" => "example.com"}
92
+ assert_equal 404, last_response.status
93
+ assert_equal "Need subdomain gem/npm", last_response.body
94
+ end
95
+
96
+ def test_localhost_with_port_gem_subdomain
97
+ # Test that localhost with port works for gem subdomain
98
+ get "/", {}, {"HTTP_HOST" => "gem.localhost:9292"}
99
+ assert_equal 200, last_response.status
100
+ assert_equal "Paquette RubyGems Repository", last_response.body
101
+ end
102
+
103
+ def test_localhost_with_port_npm_subdomain
104
+ # Test that localhost with port works for npm subdomain
105
+ get "/", {}, {"HTTP_HOST" => "npm.localhost:9292"}
106
+ assert_equal 200, last_response.status
107
+ assert_equal "Paquette NPM Repository", last_response.body
108
+ end
109
+
110
+ def test_gem_subdomain_gem_download
111
+ get "/gems/zip_kit-6.2.0.gem", {}, {"HTTP_HOST" => "gem.example.com"}
112
+ assert_equal 200, last_response.status
113
+ assert_equal "application/octet-stream", last_response.content_type
114
+ assert last_response.body.length > 0
115
+ end
116
+
117
+ def test_cross_subdomain_isolation
118
+ # Test that npm endpoints don't work on gem subdomain
119
+ get "/-/ping", {}, {"HTTP_HOST" => "gem.example.com"}
120
+ assert_equal 404, last_response.status
121
+
122
+ # Test that gem endpoints don't work on npm subdomain
123
+ get "/api/v1/names", {}, {"HTTP_HOST" => "npm.example.com"}
124
+ assert_equal 404, last_response.status
125
+ end
126
+ end
@@ -0,0 +1,125 @@
1
+ require_relative "test_helper"
2
+
3
+ class SubdomainRouterTest < Minitest::Test
4
+ def setup
5
+ @mock_app = MockApp.new
6
+ @gem_server = Paquette::GemServer.new(Paquette::GemServer::DirectoryGemRepository.new(FIXTURE_GEMS_DIR))
7
+ @npm_server = Paquette::NpmServer.new(FIXTURE_NPM_DIR)
8
+ @router = Paquette::SubdomainRouter.new do |router|
9
+ router.map "gems", to: @gem_server
10
+ router.map "npm", to: @npm_server
11
+ router.fallback to: @mock_app
12
+ end
13
+ end
14
+
15
+ def test_extract_subdomain_with_gems_subdomain
16
+ test_cases = [
17
+ ["gems.example.com", "gems"],
18
+ ["gems.localhost", "gems"],
19
+ ["gems.localhost:9292", "gems"]
20
+ ]
21
+
22
+ test_cases.each do |host, expected|
23
+ result = @router.send(:extract_subdomain, host)
24
+ assert_equal expected, result, "Expected '#{expected}' for host '#{host}', got '#{result}'"
25
+ end
26
+ end
27
+
28
+ def test_extract_subdomain_with_npm_subdomain
29
+ test_cases = [
30
+ ["npm.example.com", "npm"],
31
+ ["npm.localhost", "npm"],
32
+ ["npm.localhost:9292", "npm"]
33
+ ]
34
+
35
+ test_cases.each do |host, expected|
36
+ result = @router.send(:extract_subdomain, host)
37
+ assert_equal expected, result, "Expected '#{expected}' for host '#{host}', got '#{result}'"
38
+ end
39
+ end
40
+
41
+ def test_extract_subdomain_with_no_subdomain
42
+ test_cases = [
43
+ ["localhost", nil],
44
+ ["localhost:9292", nil],
45
+ ["example.com", nil],
46
+ ["api.example.com", nil] # unknown subdomain
47
+ ]
48
+
49
+ test_cases.each do |host, expected|
50
+ result = @router.send(:extract_subdomain, host)
51
+ if expected.nil?
52
+ assert_nil result, "Expected nil for host '#{host}', got '#{result}'"
53
+ else
54
+ assert_equal expected, result, "Expected '#{expected}' for host '#{host}', got '#{result}'"
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_routing_to_gems_server
60
+ env = create_env("gems.example.com", "/")
61
+
62
+ # Mock the GemServer instance to verify it's called
63
+ gem_server_mock = Minitest::Mock.new
64
+ gem_server_mock.expect :call, [200, {}, ["GemServer response"]], [env]
65
+
66
+ # Stub the instance method
67
+ @gem_server.stub :call, ->(env) { gem_server_mock.call(env) } do
68
+ response = @router.call(env)
69
+ assert_equal [200, {}, ["GemServer response"]], response
70
+ end
71
+
72
+ gem_server_mock.verify
73
+ end
74
+
75
+ def test_routing_to_npm_server
76
+ env = create_env("npm.example.com", "/")
77
+
78
+ # Mock the NpmServer instance to verify it's called
79
+ npm_server_mock = Minitest::Mock.new
80
+ npm_server_mock.expect :call, [200, {}, ["NpmServer response"]], [env]
81
+
82
+ # Stub the instance method
83
+ @npm_server.stub :call, ->(env) { npm_server_mock.call(env) } do
84
+ response = @router.call(env)
85
+ assert_equal [200, {}, ["NpmServer response"]], response
86
+ end
87
+
88
+ npm_server_mock.verify
89
+ end
90
+
91
+ def test_routing_to_default_app
92
+ env = create_env("example.com", "/")
93
+
94
+ # The router should call the default app
95
+ response = @router.call(env)
96
+ assert_equal [200, {}, ["Default app response"]], response
97
+ end
98
+
99
+ def test_fallback_behavior
100
+ env = create_env("unknown.example.com", "/")
101
+
102
+ # The router should call the fallback app
103
+ response = @router.call(env)
104
+ assert_equal [200, {}, ["Default app response"]], response
105
+ end
106
+
107
+ private
108
+
109
+ def create_env(host, path)
110
+ {
111
+ "HTTP_HOST" => host,
112
+ "REQUEST_METHOD" => "GET",
113
+ "PATH_INFO" => path,
114
+ "QUERY_STRING" => "",
115
+ "rack.input" => StringIO.new
116
+ }
117
+ end
118
+
119
+ # Mock app for testing
120
+ class MockApp
121
+ def call(env)
122
+ [200, {}, ["Default app response"]]
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,12 @@
1
+ require "minitest/autorun"
2
+ require "rack/test"
3
+ require "rack"
4
+ require "fileutils"
5
+ require "json"
6
+ require "stringio"
7
+ require "net/http"
8
+ require "tempfile"
9
+ require_relative "../lib/paquette"
10
+
11
+ FIXTURE_GEMS_DIR = File.expand_path("fixtures/gems", __dir__)
12
+ FIXTURE_NPM_DIR = File.expand_path("fixtures/npm", __dir__)
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paquette
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Julik Tarkhanov
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2026-04-26 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rack
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '3.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '3.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: mustermann
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: sourcemap
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.1'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.1'
54
+ executables: []
55
+ extensions: []
56
+ extra_rdoc_files: []
57
+ files:
58
+ - LICENSE.md
59
+ - README.md
60
+ - lib/paquette.rb
61
+ - lib/paquette/gem_server.rb
62
+ - lib/paquette/gem_server/directory_gem_repository.rb
63
+ - lib/paquette/gem_server/gem_repacker.rb
64
+ - lib/paquette/gem_server/gem_repository.rb
65
+ - lib/paquette/gem_server/personalizer.rb
66
+ - lib/paquette/gem_server/read_gated_repository.rb
67
+ - lib/paquette/npm_repacker.rb
68
+ - lib/paquette/npm_server.rb
69
+ - lib/paquette/npm_server/directory_npm_repository.rb
70
+ - lib/paquette/npm_server/gated_npm_repository.rb
71
+ - lib/paquette/npm_server/npm_repository.rb
72
+ - lib/paquette/routes.rb
73
+ - lib/paquette/subdomain_router.rb
74
+ - lib/paquette/version.rb
75
+ - test/fixtures/gems/minuscule_test/minuscule_test-0.1.0.gem
76
+ - test/fixtures/gems/zip_kit/zip_kit-6.2.0.gem
77
+ - test/fixtures/gems/zip_kit/zip_kit-6.2.1.gem
78
+ - test/fixtures/npm/react-dropzone/react-dropzone-14.3.8.tgz
79
+ - test/gem_server/bundler_install_test.rb
80
+ - test/gem_server/directory_gem_repository_test.rb
81
+ - test/gem_server/gem_repacker_test.rb
82
+ - test/gem_server/personalizer_metadata_test.rb
83
+ - test/gem_server/personalizer_test.rb
84
+ - test/gem_server/read_gated_repository_test.rb
85
+ - test/gem_server/repository_stack_test.rb
86
+ - test/gem_server_test.rb
87
+ - test/npm_repacker_sourcemap_test.rb
88
+ - test/npm_repacker_test.rb
89
+ - test/npm_server_test.rb
90
+ - test/routes_test.rb
91
+ - test/subdomain_router_integration_test.rb
92
+ - test/subdomain_router_test.rb
93
+ - test/test_helper.rb
94
+ homepage: https://github.com/julik/paquette
95
+ licenses:
96
+ - Osassy
97
+ metadata:
98
+ homepage_uri: https://github.com/julik/paquette
99
+ source_code_uri: https://github.com/julik/paquette
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '3.1'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.6.2
115
+ specification_version: 4
116
+ summary: Rack-based server for gated gem and NPM package repositories
117
+ test_files: []