CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-np

A better npm publish tool with automated workflows, version bumping, testing, and git integration

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

npm-operations.mddocs/

NPM Registry Operations

NPM registry interactions including package validation, publishing, 2FA management, and error handling for the publishing workflow.

Capabilities

NPM Information Functions

Functions for retrieving NPM registry and package information.

/**
 * Get the current npm version
 * @returns Promise resolving to npm version string
 */
function version(): Promise<string>;

/**
 * Check NPM registry connection
 * @returns Promise that resolves if connection is successful
 * @throws Error if unable to connect to registry
 */
function checkConnection(): Promise<void>;

/**
 * Get the current npm username
 * @param options - Configuration options
 * @param options.externalRegistry - True if using external registry
 * @returns Promise resolving to npm username
 */
function username(options: {externalRegistry?: boolean}): Promise<string>;

/**
 * Check if package name is available on npm registry
 * @param package_ - Package object with name property
 * @returns Promise resolving to availability information
 */
function isPackageNameAvailable(package_: {name: string}): Promise<{
  isAvailable: boolean;
  isUnknown: boolean;
}>;

/**
 * Get package collaborators/maintainers
 * @param package_ - Package object with name property
 * @returns Promise resolving to JSON string of collaborator information, or false if package doesn't exist
 */
function collaborators(package_: {name: string}): Promise<string | false>;

/**
 * Get prerelease distribution tags for a package
 * @param packageName - Name of the package
 * @returns Promise resolving to array of prerelease tags
 */
function prereleaseTags(packageName: string): Promise<string[]>;

Usage Examples:

import * as npm from "np/source/npm/util.js";

// Check npm environment
const npmVersion = await npm.version();
const currentUser = await npm.username({externalRegistry: false});

console.log(`NPM version: ${npmVersion}`);
console.log(`Logged in as: ${currentUser}`);

// Validate package name
const availability = await npm.isPackageNameAvailable({name: "my-package"});
if (availability.isAvailable) {
  console.log("Package name is available - first publish");
} else if (availability.isUnknown) {
  console.warn("Could not determine package availability");
} else {
  console.log("Package exists - updating existing package");
}

// Check collaborators
const collaboratorInfo = await npm.collaborators({name: "my-package"});
if (collaboratorInfo) {
  const maintainers = JSON.parse(collaboratorInfo);
  console.log(`Package maintainers: ${Object.keys(maintainers).length}`);
} else {
  console.log("Package does not exist");
}

NPM Validation Functions

Functions for validating NPM environment and package configuration.

/**
 * Verify npm version meets minimum requirements
 * @throws Error if npm version is too old
 */
function verifyRecentNpmVersion(): Promise<void>;

/**
 * Check if package uses external npm registry
 * @param package_ - Package object with publishConfig or registry info
 * @returns True if using external registry
 */
function isExternalRegistry(package_: object): boolean;

/**
 * Check ignore strategy for npm publishing
 * @param files - Package files configuration
 * @param rootDirectory - Project root directory
 * @returns Promise resolving to ignore strategy information
 */
function checkIgnoreStrategy(
  files: {files?: string[]}, 
  rootDirectory: string
): Promise<object>;

/**
 * Get list of files that will be packed by npm
 * @param rootDirectory - Project root directory
 * @returns Promise resolving to array of file paths
 */
function getFilesToBePacked(rootDirectory: string): Promise<string[]>;

Usage Examples:

import * as npm from "np/source/npm/util.js";

// Validate npm environment
await npm.verifyRecentNpmVersion(); // Throws if npm < 9

// Check registry configuration
const isExternal = npm.isExternalRegistry(packageJson);
if (isExternal) {
  console.log("Using external registry");
}

// Analyze package files
const filesToPack = await npm.getFilesToBePacked(process.cwd());
console.log(`${filesToPack.length} files will be published`);

// Check ignore configuration
const ignoreInfo = await npm.checkIgnoreStrategy(
  {files: packageJson.files}, 
  process.cwd()
);

NPM Publishing Functions

Functions for executing NPM publish operations.

/**
 * Generate npm publish command arguments
 * @param options - Publishing options
 * @returns Array of command line arguments for npm publish
 */
function getPackagePublishArguments(options: {
  tag?: string;
  contents?: string;
  otp?: string;
  [key: string]: any;
}): string[];

/**
 * Execute npm publish command
 * @param arguments_ - Command arguments from getPackagePublishArguments
 * @returns Child process (execa) that can be awaited or used with streams
 */
function runPublish(arguments_: string[]): ChildProcess;

Usage Examples:

import { getPackagePublishArguments, runPublish } from "np/source/npm/publish.js";

// Generate publish arguments
const publishArgs = getPackagePublishArguments({
  tag: "beta",
  contents: "dist",
  otp: "123456"
});
// Result: ["publish", "dist", "--tag", "beta", "--otp", "123456"]

// Execute publish
const publishProcess = runPublish(publishArgs);

// Stream output
publishProcess.stdout.on('data', (data) => {
  console.log(data.toString());
});

publishProcess.stderr.on('data', (data) => {
  console.error(data.toString());
});

// Promise-based usage
try {
  await publishProcess;
  console.log('Successfully published to npm');
} catch (error) {
  console.error('Publish failed:', error.message);
}

Two-Factor Authentication (2FA)

Functions for managing 2FA on npm packages.

/**
 * Generate arguments for enabling 2FA on a package
 * @param packageName - Name of the package
 * @param options - Configuration options
 * @param options.otp - One-time password for authentication
 * @returns Promise resolving to npm access command arguments
 */
function getEnable2faArguments(
  packageName: string, 
  options: {otp?: string}
): Promise<string[]>;

/**
 * Attempt to enable 2FA on a package with user interaction
 * @param task - Listr task instance for user interaction
 * @param packageName - Name of the package
 * @param options - Configuration options
 * @returns Promise that resolves when 2FA is enabled
 */
function tryEnable2fa(
  task: object, 
  packageName: string, 
  options: {otp?: string}
): Promise<void>;

Usage Examples:

import enable2fa, { getEnable2faArguments } from "np/source/npm/enable-2fa.js";

// Generate 2FA command
const args = await getEnable2faArguments("my-package", {otp: "123456"});
// Result: ["access", "2fa-required", "my-package", "--otp", "123456"]

// Enable 2FA in task context
await enable2fa(listrTask, "my-package", {otp: userOtp});

NPM Error Handling

Advanced error handling for npm publish operations.

/**
 * Handle npm publish errors with OTP retry logic
 * @param error - Error from npm publish command
 * @param task - Listr task for user interaction
 * @param retryFn - Function to retry publish with OTP
 * @returns Promise that handles error and retry logic
 */
function handleNpmError(
  error: Error,
  task: object,
  retryFn: (otp: string) => ChildProcess
): Promise<void>;

Usage Examples:

import handleNpmError from "np/source/npm/handle-npm-error.js";
import { runPublish, getPackagePublishArguments } from "np/source/npm/publish.js";

// Use error handling in publish workflow
const publishStream = from(runPublish(getPackagePublishArguments(options)))
  .pipe(
    catchError(error => handleNpmError(error, task, (otp) => {
      // Retry with OTP
      const argsWithOtp = getPackagePublishArguments({...options, otp});
      return runPublish(argsWithOtp);
    }))
  );

NPM Workflow Integration

Pre-publish Validation

NPM validation steps before publishing:

  1. NPM Version Check: Ensure npm version ≥ 9.0.0
  2. Registry Connection: Verify connection to npm registry
  3. Authentication: Confirm user is logged in
  4. Package Name: Check if package name is available/owned
  5. File Analysis: Analyze files that will be published
  6. External Registry: Handle external registry configuration

Publishing Process

NPM operations during publishing:

  1. Argument Generation: Create npm publish command arguments
  2. Execution: Run npm publish with proper error handling
  3. OTP Handling: Prompt for 2FA codes if required
  4. Error Recovery: Handle network failures and authentication issues
  5. Success Confirmation: Verify package was published successfully

Post-publish Operations

NPM operations after successful publishing:

  1. 2FA Setup: Enable 2FA on new packages if configured
  2. Tag Management: Verify correct dist-tag was applied
  3. Access Control: Configure package access if needed

Publishing Options

NPM publish supports various options:

const options = {
  tag: "beta",           // Publish under beta tag
  contents: "dist",      // Publish from dist directory
  otp: "123456",        // One-time password for 2FA
  access: "public",     // Package access level
  registry: "custom"    // Custom registry URL
};

Package Access Management

Access Levels

NPM packages can have different access levels:

/**
 * Get npm package access information
 * @param name - Package name
 * @returns Promise resolving to access information
 */
function getNpmPackageAccess(name: string): Promise<{
  access: 'public' | 'restricted';
  [key: string]: any;
}>;

Access Types:

  • public: Anyone can install (default for unscoped packages)
  • restricted: Only collaborators can install (default for scoped packages)

Scoped Packages

Handle scoped package publishing:

// Scoped package names
"@myorg/my-package"
"@username/project-name"

// Require explicit public access
const publishArgs = getPackagePublishArguments({
  access: "public"  // Required for public scoped packages
});

Registry Configuration

Default Registry

Standard npm registry configuration:

// Default npm registry
"https://registry.npmjs.org/"

// Package manager detection
const isNpm = packageManager.id === 'npm';
const registryUrl = isNpm ? undefined : packageManager.registry;

External Registries

Support for external npm registries:

// Custom registry in package.json
{
  "publishConfig": {
    "registry": "https://npm.example.com/"
  }
}

// Detection
const isExternal = npm.isExternalRegistry(packageJson);
if (isExternal) {
  // Disable 2FA setup
  // Adjust publish commands
  // Handle authentication differently
}

Enterprise Registries

Enterprise registry considerations:

  • Authentication: May use different auth mechanisms
  • 2FA: May not support 2FA enforcement
  • Tags: May have different tag restrictions
  • Scopes: May require specific scopes

Error Conditions

Common NPM Errors

Authentication Errors:

  • Not logged in to npm
  • Invalid credentials
  • 2FA token required
  • 2FA token expired

Publishing Errors:

  • Package name conflicts
  • Permission denied
  • Network timeouts
  • Registry unavailable

Validation Errors:

  • Invalid package.json
  • Missing required fields
  • Version conflicts
  • File access issues

Error Recovery

NPM error handling strategies:

// OTP retry for 2FA
if (error.code === 'EOTP') {
  const otp = await promptForOTP();
  return retryPublish({...options, otp});
}

// Network retry
if (error.code === 'ENOTFOUND') {
  await delay(1000);
  return retryPublish(options);
}

// Permission error guidance
if (error.code === 'E403') {
  throw new Error('Permission denied. Run "npm login" or check package ownership');
}

Debug Information

NPM operations provide detailed debug information:

  • Command executed: Full npm command with arguments
  • Registry URL: Target registry for publishing
  • User context: Current npm user and authentication state
  • Package analysis: Files included, size, and structure
  • Network details: Request/response information for troubleshooting

Install with Tessl CLI

npx tessl i tessl/npm-np

docs

configuration.md

core-publishing.md

git-operations.md

index.md

npm-operations.md

package-manager.md

utilities.md

version-management.md

tile.json