forked from vercel/resolve-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
59 lines (49 loc) · 1.38 KB
/
index.js
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
const { run } = require('micro')
const { parse } = require('url')
const fetch = require('node-fetch')
const { maxSatisfying } = require('semver')
const INDEX = 'https://nodejs.org/dist/index.json'
async function resolveVersion(tag) {
const res = await fetch(INDEX)
if (!res.ok) {
// TODO: handle error response
}
let body = await res.json()
const ltsParts = tag.match(/^lts(?:\/([a-z]+))?$/)
const isLts = ltsParts !== null
if (isLts) {
const codename = ltsParts[1]
body = body.filter(b => b.lts && (codename ? b.lts.toLowerCase() === codename : true))
}
const data = new Map(body.map(b => [b.version, b]))
const versions = body.map(b => b.version)
const matchTag = isLts ? '*' : tag
const version = maxSatisfying(versions, matchTag)
if (!version) {
return null
}
return Object.assign({ tag }, data.get(version))
}
async function handler (req, res) {
const { pathname, query } = parse(req.url, true)
const tag = (
query.tag ||
decodeURIComponent(pathname.substr(1)) ||
'*'
).toLowerCase()
const match = await resolveVersion(tag)
if (!match) {
res.statusCode = 404
return {
tag,
error: 'No match found'
}
}
if (/json/.test(req.headers.accept)) {
return match
} else {
res.setHeader('Content-Type', 'text/plain')
return match.version
}
}
module.exports = (req, res) => run(req, res, handler)