-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add
npm access
command, with 1/3 of its features
- Loading branch information
Showing
4 changed files
with
221 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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!")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,6 +111,7 @@ var commandCache = {} | |
, "adduser" | ||
, "unpublish" | ||
, "owner" | ||
, "access" | ||
, "deprecate" | ||
, "shrinkwrap" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
}) |