Programmatic API for managing npm organization memberships and roles
npx @tessl/cli install tessl/npm-libnpmorg@8.0.0libnpmorg is a Node.js library for programmatically managing npm organization memberships and roles. It provides a clean API to add, remove, and list organization members with their roles through the npm registry API, supporting all standard npm authentication methods including tokens and OTP for two-factor authentication.
npm install libnpmorgconst org = require("libnpmorg");For individual functions:
const { set, rm, ls } = require("libnpmorg");const org = require("libnpmorg");
// List organization members
const roster = await org.ls("myorg", { token: "your-npm-token" });
console.log(roster);
// Roster { alice: 'developer', bob: 'admin', charlie: 'owner' }
// Add or update a member with specific role
const memberDetails = await org.set("myorg", "newuser", "developer", {
token: "your-npm-token"
});
console.log(memberDetails);
// MembershipDetail { org: { name: 'myorg', size: 4 }, user: 'newuser', role: 'developer' }
// Add member with default 'developer' role (role parameter omitted)
const memberDetails2 = await org.set("myorg", "anothernewuser", {
token: "your-npm-token"
});
console.log(memberDetails2);
// MembershipDetail { org: { name: 'myorg', size: 5 }, user: 'anothernewuser', role: 'developer' }
// Remove a member
await org.rm("myorg", "olduser", { token: "your-npm-token" });All functions accept an options object that supports npm-registry-fetch authentication:
Common authentication patterns:
// Using npm token
const options = { token: "npm_1234567890abcdef" };
// With two-factor authentication
const options = { token: "npm_1234567890abcdef", otp: "123456" };
// Custom registry
const options = {
token: "your-token",
registry: "https://custom-registry.com/"
};Adds a new member to an organization or updates an existing member's role.
/**
* Set or update a user's role in an organization
* @param org - Organization name (with or without @ prefix)
* @param user - Username (with or without @ prefix)
* @param role - Role ('admin', 'owner', or 'developer'). Optional, defaults to 'developer'
* @param opts - npm-registry-fetch options for authentication and configuration
* @returns Promise resolving to MembershipDetail object
*/
function set(org, user, role, opts);
/**
* Set or update a user's role in an organization (role omitted, defaults to 'developer')
* @param org - Organization name (with or without @ prefix)
* @param user - Username (with or without @ prefix)
* @param opts - npm-registry-fetch options for authentication and configuration
* @returns Promise resolving to MembershipDetail object
*/
function set(org, user, opts);Usage Examples:
// Add user with default 'developer' role
await org.set("myorg", "alice", { token: "your-token" });
// Add user with specific role
await org.set("@myorg", "@bob", "admin", { token: "your-token" });
// Update existing user's role
await org.set("myorg", "charlie", "owner", {
token: "your-token",
otp: "123456"
});Removes a user from an organization.
/**
* Remove a user from an organization
* @param org - Organization name (with or without @ prefix)
* @param user - Username (with or without @ prefix)
* @param opts - npm-registry-fetch options for authentication and configuration
* @returns Promise resolving to null on success
*/
function rm(org, user, opts);Usage Examples:
// Remove user from organization
await org.rm("myorg", "alice", { token: "your-token" });
// Remove user with @ prefixes
await org.rm("@myorg", "@bob", { token: "your-token" });Lists all members of an organization with their roles.
/**
* List all members of an organization
* @param org - Organization name (with or without @ prefix)
* @param opts - npm-registry-fetch options for authentication and configuration
* @returns Promise resolving to Roster object (username: role mappings)
*/
function ls(org, opts);Usage Examples:
// List all organization members
const roster = await org.ls("myorg", { token: "your-token" });
console.log(roster);
// Roster { alice: 'developer', bob: 'admin', charlie: 'owner' }
// Iterate over members
for (const [username, role] of Object.entries(roster)) {
console.log(`${username}: ${role}`);
}Returns a stream of organization members as [username, role] pairs.
/**
* Stream organization members as [key, value] pairs
* @param org - Organization name (with or without @ prefix)
* @param opts - npm-registry-fetch options for authentication and configuration
* @returns Stream emitting [username, role] pairs, compatible with Symbol.asyncIterator
*/
function ls.stream(org, opts);Usage Examples:
// Stream members using async iteration
for await (const [username, role] of org.ls.stream("myorg", { token: "your-token" })) {
console.log(`${username}: ${role}`);
}
// Collect stream results manually
const stream = org.ls.stream("myorg", { token: "your-token" });
const results = await stream.collect();
console.log(results); // [['alice', 'developer'], ['bob', 'admin'], ['charlie', 'owner']]/**
* Result object returned by set() operations
*/
class MembershipDetail {
org: {
name: string; // Organization name
size: number; // Total number of members
};
user: string; // Username
role: string; // User's role in organization
}
/**
* Result object returned by ls() operations
* Keys are usernames, values are roles
*/
class Roster {
[username: string]: 'admin' | 'owner' | 'developer';
}
/**
* Options object accepted by all functions
* Extends npm-registry-fetch options
*/
interface Options {
token?: string; // npm authentication token
otp?: string; // One-time password for 2FA
registry?: string; // Registry URL (defaults to npm)
[key: string]: any; // Other npm-registry-fetch options
}npm organizations support three role types:
All functions perform parameter validation using the aproba library:
Functions may throw errors from npm-registry-fetch and parameter validation:
err.code === 'EOTP')try {
await org.set("myorg", "alice", "admin", { token: "invalid-token" });
} catch (error) {
if (error.code === 'EOTP') {
// Retry with OTP
await org.set("myorg", "alice", "admin", {
token: "valid-token",
otp: "123456"
});
} else {
console.error("Operation failed:", error.message);
}
}