| var lists = module.exports = {} |
| |
| lists.first = function (head, req) { |
| var row = getRow() |
| send(toJSON([row, row.id, row.doc])) |
| } |
| |
| lists.short = function (head, req) { |
| require("monkeypatch").patch(Object, Date, Array, String) |
| |
| var out = {} |
| , row |
| , show = (req.query.show || "").split(",") |
| , v = show.indexOf("version") !== -1 |
| , t = show.indexOf("tag") !== -1 |
| while (row = getRow()) { |
| if (!row.id) continue |
| if (!t && !v) { |
| out[row.id] = true |
| continue |
| } |
| var val = row.value |
| if (t) Object.keys(val["dist-tags"] || {}).forEach(function (t) { |
| out[row.id + "@" + t] = true |
| }) |
| if (v) Object.keys(val.versions || {}).forEach(function (v) { |
| out[row.id + "@" + v] = true |
| }) |
| } |
| send(toJSON(Object.keys(out))) |
| } |
| |
| |
| lists.rss = function (head, req) { |
| var limit = +req.query.limit |
| , desc = req.query.descending |
| if (!desc || !limit || limit > 50 || limit < 0) { |
| start({ code: 403 |
| , headers: { 'Content-type': 'text/xml' }}) |
| send('<error><![CDATA[Please retry your request with ' |
| + '?descending=true&limit=50 query params]]></error>') |
| return |
| } |
| |
| start({ code: 200 |
| // application/rss+xml is correcter, but also annoyinger |
| , headers: { "Content-Type": "text/xml" } }) |
| send('<?xml version="1.0" encoding="UTF-8"?>' |
| +'\n<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" ' |
| +'"http://my.netscape.com/publish/formats/rss-0.91.dtd">' |
| +'\n<rss version="0.91">' |
| +'\n <channel>' |
| +'\n <title>npm recent updates</title>' |
| +'\n <link>http://search.npmjs.org/</link>' |
| +'\n <description>Updates to the npm package registry</description>' |
| +'\n <language>en</language>') |
| |
| var row |
| while (row = getRow()) { |
| if (!row.value || !row.value["dist-tags"]) continue |
| |
| var doc = row.value |
| var authors = doc.maintainers.map(function (m) { |
| return '<author>' + m.name + '</author>' |
| }).join('\n ') |
| |
| var latest = doc["dist-tags"].latest |
| var time = doc.time && doc.time[latest] |
| var date = new Date(time) |
| doc = doc.versions[latest] |
| if (!doc || !time || !date) continue |
| |
| var url = "https://npmjs.org/package/" + doc.name |
| |
| send('\n <item>' |
| +'\n <title>' + doc._id + '</title>' |
| +'\n <link>' + url + '</link>' |
| +'\n ' + authors |
| +'\n <description><![CDATA[' |
| + (doc.description || '').trim() + ']]></description>' |
| +'\n <pubDate>' + date.toISOString() + '</pubDate>' |
| +'\n </item>') |
| } |
| send('\n </channel>' |
| +'\n</rss>') |
| } |
| |
| |
| |
| lists.index = function (head, req) { |
| require("monkeypatch").patch(Object, Date, Array, String) |
| var basePath = req.requested_path |
| if (basePath.indexOf("_list") === -1) basePath = "" |
| else { |
| basePath = basePath.slice(0, basePath.indexOf("_list")) |
| .concat(["_rewrite", ""]).join("/") |
| } |
| |
| var row |
| , semver = require("semver") |
| , res = [] |
| |
| if (req.query.jsonp) send(req.query.jsonp + "(") |
| send('{"_updated":' + Date.now()) |
| while (row = getRow()) { |
| if (!row.id) continue |
| |
| var doc = row.value |
| if (!doc.name || !doc._id || |
| encodeURIComponent(doc._id) !== doc._id) continue |
| |
| var p = {} |
| |
| // legacy kludge |
| delete doc.mtime |
| delete doc.ctime |
| if (doc.versions) for (var v in doc.versions) { |
| var clean = semver.clean(v) |
| delete doc.versions[v].ctime |
| delete doc.versions[v].mtime |
| if (clean !== v) { |
| var x = doc.versions[v] |
| delete doc.versions[v] |
| x.version = v = clean |
| doc.versions[clean] = x |
| } |
| } |
| if (doc["dist-tags"]) for (var tag in doc["dist-tags"]) { |
| var clean = semver.clean(doc["dist-tags"][tag]) |
| if (!clean) delete doc["dist-tags"][tag] |
| else doc["dist-tags"][tag] = clean |
| } |
| // end kludge |
| |
| for (var i in doc) { |
| if (i === "versions" || i.charAt(0) === "_" || i === 'readme' || |
| i === 'time') continue |
| p[i] = doc[i] |
| } |
| if (doc.time) { |
| p.time = { modified: doc.time.modified } |
| } |
| if (p['dist-tags'] && typeof p['dist-tags'] === 'object') { |
| p.versions = Object.keys(p['dist-tags']).reduce(function (ac, v) { |
| ac[ p['dist-tags'][v] ] = v |
| return ac |
| }, {}) |
| } |
| if (doc.repositories && Array.isArray(doc.repositories)) { |
| doc.repository = doc.repositories[0] |
| delete doc.repositories |
| } |
| if (doc.repository) p.repository = doc.repository |
| if (doc.description) p.description = doc.description |
| for (var i in doc.versions) { |
| if (doc.versions[i].repository && !doc.repository) { |
| p.repository = doc.versions[i].repository |
| } |
| if (doc.versions[i].keywords) p.keywords = doc.versions[i].keywords |
| } |
| send(',' + JSON.stringify(doc._id) + ':' + JSON.stringify(p)) |
| } |
| send('}') |
| if (req.query.jsonp) send(')') |
| |
| } |
| |
| |
| lists.byField = function (head, req) { |
| require("monkeypatch").patch(Object, Date, Array, String) |
| |
| if (!req.query.field) { |
| start({"code":"400", "headers": {"Content-Type": "application/json"}}) |
| send('{"error":"Please specify a field parameter"}') |
| return |
| } |
| |
| start({"code": 200, "headers": {"Content-Type": "application/json"}}) |
| var row |
| , out = {} |
| , field = req.query.field |
| , not = field.charAt(0) === "!" |
| if (not) field = field.substr(1) |
| while (row = getRow()) { |
| if (!row.id) continue |
| var has = row.value.hasOwnProperty(field) |
| if (!not && !has || not && has) continue |
| out[row.key] = { "maintainers": row.value.maintainers.map(function (m) { |
| return m.name + " <" + m.email + ">" |
| }) } |
| if (has) out[row.key][field] = row.value[field] |
| } |
| send(JSON.stringify(out)) |
| } |
| |
| |
| |
| lists.preBuilt = function (head, req) { |
| start({"code": 200, "headers": {"Content-Type": "text/plain"}}); |
| var row |
| , out = [] |
| while (row = getRow()) { |
| if (!row.id) continue |
| if (!(req.query.bindist && row.value[req.query.bindist])) continue |
| out.push(row.key) |
| } |
| send(out.join("\n")) |
| } |
| |
| lists.needBuild = function (head, req) { |
| start({"code": 200, "headers": {"Content-Type": "text/plain"}}); |
| var row |
| , first = true |
| while (row = getRow()) { |
| if (!row.id) continue |
| if (req.query.bindist && row.value[req.query.bindist]) continue |
| // out.push(row.key) |
| send((first ? "{" : ",") |
| + JSON.stringify(row.key) |
| + ":" |
| + JSON.stringify(Object.keys(row.value)) |
| + "\n") |
| first = false |
| } |
| send("}\n") |
| } |
| |
| lists.scripts = function (head, req) { |
| var row |
| , out = {} |
| , scripts = req.query.scripts && req.query.scripts.split(",") |
| , match = req.query.match |
| |
| if (match) match = new RegExp(match) |
| |
| while (row = getRow()) { |
| inc = true |
| if (!row.id) continue |
| if (req.query.package && row.id !== req.query.package) continue |
| if (scripts && scripts.length) { |
| var inc = false |
| for (var s = 0, l = scripts.length; s < l && !inc; s ++) { |
| inc = row.value[scripts[s]] |
| if (match) inc = inc && row.value[scripts[s]].match(match) |
| } |
| if (!inc) continue |
| } |
| out[row.id] = row.value |
| } |
| send(toJSON(out)) |
| } |
| |
| |
| lists.rowdump = function (head, req) { |
| var rows = [] |
| while (row = getRow()) rows.push(row) |
| send(toJSON(rows)) |
| } |
| |
| lists.passthrough = function (head, req) { |
| var out = {} |
| , row |
| while (row = getRow()) { |
| if (!row.id) continue |
| out[row.id] = row.value |
| } |
| send(toJSON(out)) |
| } |
| |
| lists.byUser = function (head, req) { |
| var out = {} |
| , user = req.query.user && req.query.user !== "-" ? req.query.user : null |
| , users = user && user.split("|") |
| while (row = getRow()) { |
| if (!user || users.indexOf(row.key) !== -1) { |
| var l = out[row.key] = out[row.key] || [] |
| l.push(row.value) |
| } |
| } |
| send(toJSON(out)) |
| } |
| |
| lists.sortCount = function (head, req) { |
| var out = [] |
| while (row = getRow()) { |
| out.push([row.key, row.value]) |
| } |
| out = out.sort(function (a, b) { |
| return a[1] === b[1] ? 0 |
| : a[1] < b[1] ? 1 : -1 |
| }) |
| var outObj = {} |
| for (var i = 0, l = out.length; i < l; i ++) { |
| outObj[out[i][0]] = out[i][1] |
| } |
| send(toJSON(outObj)) |
| } |
| |
| lists.size = function (head, req) { |
| var row |
| , out = [] |
| , max = 0 |
| while (row = getRow()) { |
| if (!row.id) continue |
| out.push(row.value) |
| } |
| var list = [] |
| out = out.sort(function (a, b) { |
| max = Math.max(max, a.size, b.size) |
| return a.size > b.size ? -1 : 1 |
| }) |
| .reduce(function (l, r) { |
| var stars = new Array(Math.ceil(80 * (r.size/max)) + 1).join("\u25FE") |
| l[r._id] = { size: r.size |
| , count: r.count |
| , avg: r.avg |
| , rel: r.size / max |
| , s: stars |
| } |
| return l |
| }, {}) |
| send(JSON.stringify(out)) |
| } |
| |
| lists.histogram = function (head, req) { |
| require("monkeypatch").patch(Object, Date, Array, String) |
| start({"code": 200, "headers": {"Content-Type": "text/plain"}}); |
| var row |
| , out = [] |
| , max = {} |
| , field = req.query.field |
| , sort = req.query.sort |
| , doAll = !field |
| |
| while (row = getRow()) { |
| if (!row.id) continue |
| out.push(row.value) |
| } |
| |
| if (!doAll) out.sort(function (a, b) { |
| max[field] = Math.max(max[field] || -Infinity, a[field], b[field]) |
| return a[field] > b[field] ? -1 : 1 |
| }) |
| else out.sort(function (a, b) { |
| for (var field in a) if (field.charAt(0) !== "_" && !isNaN(a[field])) { |
| max[field] = Math.max(max[field] || -Infinity, a[field]) |
| } |
| for (var field in b) if (field.charAt(0) !== "_" && !isNaN(b[field])) { |
| max[field] = Math.max(max[field] || -Infinity, b[field]) |
| } |
| if (sort) { |
| return Number(a[sort]) > Number(b[sort]) ? -1 : 1 |
| } else { |
| return 0 |
| } |
| }) |
| if (doAll) { |
| // sort the fields by the max sizes. |
| var m = {} |
| Object.keys(max).sort(function (a, b) { |
| return max[a] > max[b] ? -1 : 1 |
| }).forEach(function (k) { m[k] = max[k] }) |
| max = m |
| } |
| out = out.map(function (a) { |
| var o = {} |
| for (var f in max) { |
| var blk = new Array(Math.ceil(80*(a[f] / max[f])+1)).join("#") |
| , spc = new Array(80 - blk.length + 1).join(" ") |
| o[f] = spc + blk + " " + a[f] |
| } |
| o._id = a._id |
| return o |
| }).reduce(function (l, r) { |
| l[r._id] = r |
| return l |
| }, {}) |
| |
| var spc = new Array(82).join(" ") |
| send(Object.keys(out).map(function (i) { |
| if (doAll) return [spc + i].concat(Object.keys(max).map(function (f) { |
| return out[i][f] + " " + f |
| })).join("\n") + "\n" |
| return out[i][field] + " " + i |
| }).join("\n")) |
| } |
| |