or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-pnpm--read-projects-context

Reads the current state of projects from modules manifest for pnpm workspace management

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@pnpm/read-projects-context@1000.0.x

To install, run

npx @tessl/cli install tessl/npm-pnpm--read-projects-context@1000.0.0

index.mddocs/

@pnpm/read-projects-context

@pnpm/read-projects-context provides functionality to read and process the current state of projects from modules manifest files in pnpm workspaces. It analyzes project configurations, hoisting patterns, and module states to provide comprehensive context for pnpm operations.

Package Information

  • Package Name: @pnpm/read-projects-context
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @pnpm/read-projects-context

Core Imports

import { readProjectsContext, type ProjectOptions } from "@pnpm/read-projects-context";

For CommonJS:

const { readProjectsContext } = require("@pnpm/read-projects-context");

Basic Usage

import { readProjectsContext, type ProjectOptions } from "@pnpm/read-projects-context";

// Define projects to read context for
const projects: ProjectOptions[] = [
  {
    rootDir: "/path/to/project1",
    modulesDir: "node_modules", // optional
    binsDir: "node_modules/.bin" // optional
  },
  {
    rootDir: "/path/to/project2"
  }
];

// Read projects context
const context = await readProjectsContext(projects, {
  lockfileDir: "/path/to/workspace/root",
  modulesDir: "node_modules" // optional
});

// Access the results
console.log("Root modules directory:", context.rootModulesDir);
console.log("Hoisted dependencies:", context.hoistedDependencies);
console.log("Registry configurations:", context.registries);
console.log("Projects with resolved paths:", context.projects);

Capabilities

Project Context Reading

Reads and processes the current state of multiple projects from their modules manifest files, providing comprehensive workspace context.

/**
 * Reads project context including modules state, registries, and project configurations
 * @param projects - Array of project configurations with optional generic extensions
 * @param opts - Options containing lockfile directory and optional modules directory
 * @returns Promise resolving to comprehensive project context
 */
function readProjectsContext<T>(
  projects: Array<ProjectOptions & T>,
  opts: {
    lockfileDir: string;
    modulesDir?: string;
  }
): Promise<{
  currentHoistPattern?: string[];
  currentPublicHoistPattern?: string[];
  hoist?: boolean;
  hoistedDependencies: HoistedDependencies;
  projects: Array<{
    id: ProjectId;
  } & T & Required<ProjectOptions>>;
  include: IncludedDependencies;
  modules: Modules | null;
  pendingBuilds: string[];
  registries: Registries | null | undefined;
  rootModulesDir: string;
  skipped: Set<DepPath>;
  virtualStoreDirMaxLength?: number;
}>;

Project Configuration Interface

Defines the structure for individual project options that can be passed to readProjectsContext.

/**
 * Configuration options for a single project
 */
interface ProjectOptions {
  /** Optional binary directory path */
  binsDir?: string;
  /** Optional modules directory path */
  modulesDir?: string;
  /** Required project root directory */
  rootDir: ProjectRootDir;
  /** Optional real path to root directory */
  rootDirRealPath?: ProjectRootDirRealPath;
}

Types

// Core type definitions (from @pnpm/types)
// Note: These are branded string types for type safety but work as regular strings at runtime
type ProjectRootDir = string;
type ProjectRootDirRealPath = string;
type ProjectId = string;
type DepPath = string;
type DependenciesField = "dependencies" | "devDependencies" | "optionalDependencies";

// Return type interfaces
interface HoistedDependencies {
  [depPath: string]: {
    [alias: string]: "public" | "private";
  };
}

interface Registries {
  default: string;
  [scope: string]: string;
}

type IncludedDependencies = {
  [dependenciesField in DependenciesField]: boolean;
};

interface Modules {
  hoistedAliases?: { [depPath: string]: string[] }; // for backward compatibility
  hoistedDependencies: HoistedDependencies;
  hoistPattern?: string[];
  included: IncludedDependencies;
  layoutVersion: number;
  nodeLinker?: "hoisted" | "isolated" | "pnp";
  packageManager: string;
  pendingBuilds: string[];
  ignoredBuilds?: string[];
  prunedAt: string;
  registries?: Registries; // nullable for backward compatibility
  shamefullyHoist?: boolean; // for backward compatibility
  publicHoistPattern?: string[];
  skipped: string[];
  storeDir: string;
  virtualStoreDir: string;
  virtualStoreDirMaxLength: number;
  injectedDeps?: Record<string, string[]>;
  hoistedLocations?: Record<string, string[]>;
}

Usage Examples

Generic Project Extensions

interface CustomProjectData {
  customField: string;
  buildScript?: string;
}

const projectsWithCustomData: Array<ProjectOptions & CustomProjectData> = [
  {
    rootDir: "/path/to/project",
    customField: "custom value",
    buildScript: "npm run build"
  }
];

const context = await readProjectsContext(projectsWithCustomData, {
  lockfileDir: "/workspace/root"
});

// Projects will now include custom fields along with resolved paths
context.projects.forEach(project => {
  console.log(project.customField); // "custom value"
  console.log(project.id); // resolved project ID
  console.log(project.modulesDir); // resolved modules directory
});

Working with Hoisting Configuration

const context = await readProjectsContext(projects, {
  lockfileDir: "/workspace/root"
});

if (context.hoist) {
  console.log("Hoisting is enabled");
  console.log("Current hoist pattern:", context.currentHoistPattern);
  console.log("Public hoist pattern:", context.currentPublicHoistPattern);
  
  // Access hoisted dependencies
  Object.entries(context.hoistedDependencies).forEach(([depPath, aliases]) => {
    Object.entries(aliases).forEach(([alias, visibility]) => {
      console.log(`Dependency ${depPath} has alias ${alias} with visibility: ${visibility}`);
    });
  });
}

Registry Configuration

const context = await readProjectsContext(projects, {
  lockfileDir: "/workspace/root"
});

if (context.registries) {
  // Process normalized registry configurations
  console.log("Default registry:", context.registries.default);
  Object.entries(context.registries).forEach(([scope, registry]) => {
    if (scope !== "default") {
      console.log(`Scope ${scope} uses registry: ${registry}`);
    }
  });
}

// Access complete modules information if available
if (context.modules) {
  console.log("Package manager:", context.modules.packageManager);
  console.log("Layout version:", context.modules.layoutVersion);
  console.log("Store directory:", context.modules.storeDir);
  console.log("Virtual store directory:", context.modules.virtualStoreDir);
  console.log("Node linker:", context.modules.nodeLinker);
  console.log("Pruned at:", context.modules.prunedAt);
}