-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathjspm_api.rb
91 lines (76 loc) · 2.48 KB
/
jspm_api.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Importmap::JspmApi
Error = Class.new(StandardError)
HTTPError = Class.new(Error)
ServiceError = Error.new(Error)
singleton_class.attr_accessor :generate_endpoint, :download_endpoint
self.generate_endpoint = "https://api.jspm.io/generate"
self.download_endpoint = "https://api.jspm.io/download"
def generate(install:, flatten_scope:, env:, provider:)
response = post_json(self.class.generate_endpoint, {
install:,
flattenScope: flatten_scope,
env:,
provider: normalize_provider(provider)
})
response_json(response)
end
def download(versioned_package_names:, provider:, exclude:)
response = post_json("#{self.class.download_endpoint}", {
packages: versioned_package_names,
provider: normalize_provider(provider),
exclude:
})
json = response_json(response)
return {} if json.blank?
json.transform_values do |package_download_details|
files = package_download_details["files"]
package_uri = URI(package_download_details["pkgUrl"])
Net::HTTP.start(package_uri.hostname, { use_ssl: true }) do |http|
files.map do |file|
[
file,
fetch_file(http, "#{package_uri.path}/#{file}")
]
end.to_h
end
end
end
private
def fetch_file(http, path)
response = http.get(path)
if response.code == "200"
response.body
else
handle_failure_response(response)
end
rescue => error
raise HTTPError, "Unexpected transport error (#{error.class}: #{error.message})"
end
def response_json(response)
case response.code
when "200" then JSON.parse(response.body)
when "404", "401" then {}
else handle_failure_response(response)
end
end
def normalize_provider(name)
name.to_s == "jspm" ? "jspm.io" : name.to_s
end
def post_json(endpoint, body)
Net::HTTP.post(URI(endpoint), body.to_json, "Content-Type" => "application/json")
rescue => error
raise HTTPError, "Unexpected transport error (#{error.class}: #{error.message})"
end
def handle_failure_response(response)
if error_message = parse_service_error(response)
raise ServiceError, error_message
else
raise HTTPError, "Unexpected response code (#{response.code})"
end
end
def parse_service_error(response)
JSON.parse(response.body.to_s)["error"]
rescue JSON::ParserError
nil
end
end