-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathNpmRegistry.res
More file actions
61 lines (50 loc) · 1.64 KB
/
NpmRegistry.res
File metadata and controls
61 lines (50 loc) · 1.64 KB
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
type response = {
ok: bool,
status: int,
json: unit => promise<Js.Json.t>,
}
@val external fetch: string => promise<response> = "fetch"
@scope(("process", "env"))
external npm_config_registry: option<string> = "NPM_CONFIG_REGISTRY"
@inline
let defaultRegistryUrl = "https://registry.npmjs.org"
let getNpmRegistry = () =>
npm_config_registry
->Option.flatMap(registry => registry->Node.Url.make)
->Option.mapOr(defaultRegistryUrl, url => url->Node.Url.href)
type fetchError =
| FetchError({message: string})
| HttpError({status: int})
| ParseError
let getFetchErrorMessage = fetchError => {
let message = switch fetchError {
| FetchError({message}) => `Fetch error. Message: ${message}`
| HttpError({status}) => `Http error. Status: ${status->Int.toString}`
| ParseError => "Parse error."
}
`Fetching versions from registry failed: ${message}`
}
let getPackageVersions = async (packageName, range) => {
let registryUrl = getNpmRegistry()
switch await fetch(`${registryUrl}/${packageName}`) {
| response if response.ok =>
switch await response.json() {
| Object(dict) =>
switch dict->Dict.get("versions") {
| Some(Object(dict)) =>
let versions =
dict
->Dict.keysToArray
->Array.filterMap(version =>
version->CompareVersions.satisfies(range) ? Some(version) : None
)
versions->Array.reverse
versions->Ok
| _ => Error(ParseError)
}
| _ => Error(ParseError)
}
| responseNotOk => Error(HttpError({status: responseNotOk.status}))
| exception JsExn(exn) => Error(FetchError({message: exn->ErrorUtils.getErrorMessage}))
}
}