Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorForrest L Norvell <ogd@aoaioxxysz.net>2015-01-22 02:52:59 +0300
committerForrest L Norvell <forrest@npmjs.com>2015-01-23 15:51:38 +0300
commitc963eb295cf766921b1680f4a71fd0ed3e1bcad8 (patch)
tree341c79824ab1a44505231e74efbf73bde20b1230
parente9f8ab3cd6324fbf2678132324d4cd8579209442 (diff)
add `npm access` command, with 1/3 of its features
-rw-r--r--lib/access.js123
-rw-r--r--lib/config/defaults.js10
-rw-r--r--lib/npm.js1
-rw-r--r--test/tap/access.js91
4 files changed, 221 insertions, 4 deletions
diff --git a/lib/access.js b/lib/access.js
new file mode 100644
index 000000000..a479a971c
--- /dev/null
+++ b/lib/access.js
@@ -0,0 +1,123 @@
+var assert = require("assert")
+var resolve = require("path").resolve
+var url = require("url")
+
+var log = require("npmlog")
+var readPackageJson = require("read-package-json")
+
+var mapToRegistry = require("./utils/map-to-registry.js")
+var npa = require("npm-package-arg")
+var npm = require("./npm.js")
+
+module.exports = access
+
+access.usage = "npm access public [<package>]"
+ + "\nnpm access restricted [<package>]"
+ + "\nnpm access add <read-only|read-write> <entity> [<package>]"
+ + "\nnpm access rm <entity> [<package>]"
+ + "\nnpm access ls [<package>]"
+ + "\nnpm access edit [<package>]"
+
+access.completion = function (opts, cb) {
+ var argv = opts.conf.argv.remain
+ if (argv.length === 2) {
+ return cb(null, ["public", "restricted", "add", "rm", "ls", "edit"])
+ }
+
+ switch (argv[2]) {
+ case "public":
+ case "restricted":
+ case "ls":
+ case "edit":
+ return cb(new Error("unimplemented: packages you can change"))
+ case "add":
+ if (argv.length === 3) return cb(null, ["read-only", "read-write"])
+
+ return cb(new Error("unimplemented: entities and packages"))
+ case "rm":
+ return cb(new Error("unimplemented: entities and packages"))
+ default:
+ return cb(new Error(argv[2]+" not recognized"))
+ }
+}
+
+function access (args, cb) {
+ var cmd = args.shift()
+ switch (cmd) {
+ case "public": case "restricted": return changeAccess(args, cmd, cb)
+ case "add": case "set": return add(args, cb)
+ case "rm": case "del": case "clear": return rm(args, cb)
+ case "list": case "sl": case "ls": return ls(args, cb)
+ case "edit": case "ed": return edit(args, cb)
+ default: return cb("Usage:\n"+access.usage)
+ }
+}
+
+function changeAccess (args, level, cb) {
+ assert(Array.isArray(args), "changeAccess requires args be an array")
+ assert(
+ ["public", "restricted"].indexOf(level) !== -1,
+ "access level must be either 'public' or 'restricted'"
+ )
+ assert(typeof cb === "function", "changeAccess requires a callback")
+
+ var p = (args.shift() || "").trim()
+ if (!p) return getCurrentPackage(level, cb)
+ changeAccess_(p, level, cb)
+}
+
+function getCurrentPackage (level, cb) {
+ var here = resolve(npm.prefix, "package.json")
+ log.verbose("setPackageLevel", "here", here)
+
+ readPackageJson(here, function (er, data) {
+ if (er) return cb(er)
+
+ if (!data.name) {
+ return cb(new Error("Package must be named"))
+ }
+
+ changeAccess_(data.name, level, cb)
+ })
+}
+
+function changeAccess_ (name, level, cb) {
+ log.verbose("changeAccess", "name", name, "level", level)
+ mapToRegistry(name, npm.config, function (er, uri, auth, base) {
+ if (er) return cb(er)
+
+ var data = npa(name)
+ if (!data.scope) {
+ var msg = "Sorry, you can't change the access level of unscoped packages."
+ log.error("access", msg)
+ return cb(new Error(msg))
+ }
+
+ // name must be scoped, so escape separator
+ name = name.replace("/", "%2f")
+ // FIXME: mapToRegistry still isn't generic enough SIGH
+ uri = url.resolve(base, "-/package/"+name+"/access")
+ var params = {
+ level : level,
+ auth : auth
+ }
+
+ npm.registry.access(uri, params, cb)
+ })
+}
+
+function add (args, cb) {
+ return cb(new Error("npm access add isn't implemented yet!"))
+}
+
+function rm (args, cb) {
+ return cb(new Error("npm access rm isn't implemented yet!"))
+}
+
+function ls (args, cb) {
+ return cb(new Error("npm access ls isn't implemented yet!"))
+}
+
+function edit (args, cb) {
+ return cb(new Error("npm edit ls isn't implemented yet!"))
+}
diff --git a/lib/config/defaults.js b/lib/config/defaults.js
index 3d99ab86f..0f9c62c69 100644
--- a/lib/config/defaults.js
+++ b/lib/config/defaults.js
@@ -24,7 +24,7 @@ try {
exports.Umask = Umask
function Umask () {}
function validateUmask (data, k, val) {
- return umask.validate (data, k, val)
+ return umask.validate(data, k, val)
}
function validateSemver (data, k, val) {
@@ -119,7 +119,8 @@ Object.defineProperty(exports, "defaults", {get: function () {
}
defaults = {
- "always-auth" : false
+ access : "restricted"
+ , "always-auth" : false
, "bin-links" : true
, browser : null
@@ -228,7 +229,8 @@ Object.defineProperty(exports, "defaults", {get: function () {
}})
exports.types =
- { "always-auth" : Boolean
+ { access : ["restricted", "public"]
+ , "always-auth" : Boolean
, "bin-links": Boolean
, browser : [null, String]
, ca: [null, String, Array]
@@ -272,7 +274,7 @@ exports.types =
// local-address must be listed as an IP for a local network interface
// must be IPv4 due to node bug
, "local-address" : getLocalAddresses()
- , loglevel : ["silent","error","warn","http","info","verbose","silly"]
+ , loglevel : ["silent", "error", "warn", "http", "info", "verbose", "silly"]
, logstream : Stream
, long : Boolean
, message: String
diff --git a/lib/npm.js b/lib/npm.js
index d03ec47b6..28c57712c 100644
--- a/lib/npm.js
+++ b/lib/npm.js
@@ -111,6 +111,7 @@ var commandCache = {}
, "adduser"
, "unpublish"
, "owner"
+ , "access"
, "deprecate"
, "shrinkwrap"
diff --git a/test/tap/access.js b/test/tap/access.js
new file mode 100644
index 000000000..909fdf01a
--- /dev/null
+++ b/test/tap/access.js
@@ -0,0 +1,91 @@
+var fs = require("fs")
+var path = require("path")
+var mkdirp = require("mkdirp")
+var rimraf = require("rimraf")
+var mr = require("npm-registry-mock")
+
+var test = require("tap").test
+var common = require("../common-tap.js")
+
+var pkg = path.resolve(__dirname, "access")
+var server
+
+var scoped = {
+ name : "@scoped/pkg",
+ version : "1.1.1"
+}
+
+var body = {
+ access : "public"
+}
+
+function mocks (server) {
+ server.post("/-/package/@scoped%2fpkg/access", JSON.stringify(body))
+ .reply(200, { "access" : "public" })
+ server.post("/-/package/@scoped%2fanother/access", JSON.stringify(body))
+ .reply(200, { "access" : "public" })
+}
+
+test("setup", function (t) {
+ mkdirp(pkg, function (er) {
+ t.ifError(er, pkg + " made successfully")
+
+ mr({port : common.port, mocks : mocks}, function (s) {
+ server = s
+
+ fs.writeFile(
+ path.join(pkg, "package.json"),
+ JSON.stringify(scoped),
+ function (er) {
+ t.ifError(er, "wrote package.json")
+ t.end()
+ }
+ )
+ })
+ })
+})
+
+test("npm access on current package", function (t) {
+ common.npm(
+ [
+ "access",
+ "public",
+ "--registry", common.registry,
+ "--loglevel", "silent"
+ ],
+ { cwd : pkg },
+ function (er, code, stdout, stderr) {
+ t.ifError(er, "npm access")
+ t.notOk(code, "exited OK")
+ t.notOk(stderr, "no error output")
+
+ t.end()
+ }
+ )
+})
+
+test("npm access on named package", function (t) {
+ common.npm(
+ [
+ "access",
+ "public", "@scoped/another",
+ "--registry", common.registry,
+ "--loglevel", "silent"
+ ],
+ { cwd : pkg },
+ function (er, code, stdout, stderr) {
+ t.ifError(er, "npm access")
+ t.notOk(code, "exited OK")
+ t.notOk(stderr, "no error output")
+
+ t.end()
+ }
+ )
+})
+
+test("cleanup", function (t) {
+ t.pass("cleaned up")
+ rimraf.sync(pkg)
+ server.close()
+ t.end()
+})