0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-17 23:45:29 -05:00

Merge pull request #65 from yannickcr/npm-search

Add search functionality
This commit is contained in:
Alex Kocharin 2014-06-24 06:25:28 +04:00
commit 9816059485
3 changed files with 123 additions and 0 deletions

View file

@ -170,6 +170,17 @@ module.exports = function(config_hash) {
stream.pipe(res)
})
// searching packages
app.get('/-/all/:package?', can('access'), function(req, res, next) {
var startkeyRegExp = /(.*)=([0-9]+)$/
var startkey = startkeyRegExp.test(req.url) ? new Date(+req.url.replace(startkeyRegExp, '$2')) : 0
storage.search(startkey, {req: req}, function(err, result) {
if (err) return next(err)
return res.send(result)
})
})
//app.get('/*', function(req, res) {
// proxy.request(req, res)
//})

View file

@ -429,6 +429,33 @@ Storage.prototype.get_package = function(name, options, callback) {
})
}
Storage.prototype.get_recent_packages = function(startkey, callback) {
var self = this
var i = 0
var list = []
fs.readdir(self.storage('').path, function(err, files) {
if (err) return callback(null, [])
var filesL = files.length
files.forEach(function(file) {
fs.stat(self.storage(file).path, function(err, stats) {
if (err) return callback(err)
if (stats.mtime > startkey) {
list.push({
time: stats.mtime,
name: file
})
}
if (++i !== filesL) {
return false
}
return callback(null, list)
})
})
})
}
//
// This function allows to update the package thread-safely
//

View file

@ -320,6 +320,91 @@ Storage.prototype.get_package = function(name, options, callback) {
})
}
//
// Retrieve remote and local packages more recent than {startkey}
//
// Function invokes uplink.request for npm and local.get_recent_packages for
// local ones then sum up the result in a json object
//
// Used storages: local && uplink (proxy_access)
//
Storage.prototype.search = function(startkey, options, callback) {
var self = this
var uplinks = []
var i = 0
var uplinks
for (var p in self.uplinks) {
uplinks.push(p)
}
function merge_with_local_packages(err, res, body) {
var j = 0
self.local.get_recent_packages(startkey, function(err, list) {
if (err) return callback(err)
var listL = list.length
if (!listL) return callback(null, body)
list.forEach(function(item) {
self.local.get_package(item.name, options, function(err, data) {
if (err) return callback(err)
var versions = utils.semver_sort(Object.keys(data.versions))
var latest = versions[versions.length - 1]
if (data.versions[latest]) {
body[item.name] = {
name : data.versions[latest].name,
description : data.versions[latest].description,
'dist-tags' : {
latest: latest
},
maintainers : data.versions[latest].maintainers || [data.versions[latest]._npmUser],
readmeFilename: data.versions[latest].readmeFilename || '',
time : {
modified: new Date(item.time).toISOString()
},
versions : {},
repository : data.versions[latest].repository,
keywords : data.versions[latest].keywords
}
body[item.name].versions[latest] = 'latest'
}
if (++j !== listL) {
return false
}
return callback(null, body)
})
})
})
}
function remote_search() {
var uplink = self.uplinks[uplinks[i]]
if (!uplink) {
return merge_with_local_packages(null, null, {})
}
self.uplinks[uplinks[i]].request({
uri: options.req.url,
timeout: self.uplinks[p].timeout,
json: true
}, function(err, res, body) {
if (err || Math.floor(res.statusCode / 100) > 3) {
i++
return remote_search()
}
return merge_with_local_packages(err, res, body)
})
}
remote_search()
}
// function fetches package information from uplinks and synchronizes it with local data
// if package is available locally, it MUST be provided in pkginfo
// returns callback(err, result, uplink_errors)