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:
commit
9816059485
3 changed files with 123 additions and 0 deletions
11
lib/index.js
11
lib/index.js
|
@ -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)
|
||||
//})
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue