Deprecated compatibility shim for Storybook's framework-agnostic API utilities
—
JavaScript package manager abstraction layer supporting npm, yarn, and pnpm. Provides unified interface for dependency management operations across different package managers.
Base class providing common interface for all JavaScript package managers.
/**
* Abstract base class for JavaScript package managers
*/
abstract class JsPackageManager {
/** Package manager type identifier */
abstract type: 'npm' | 'yarn1' | 'yarn2' | 'pnpm';
/**
* Get command-line arguments for package installation
* @returns Array of install command arguments
*/
abstract getInstallArgs(): string[];
/**
* Get the run command for executing package scripts
* @returns Run command string (e.g., 'npm run', 'yarn')
*/
abstract getRunCommand(): string;
/**
* Get command-line arguments for running scripts
* @returns Array of run command arguments
*/
abstract getRunArgs(): string[];
/**
* Get command-line arguments for adding packages
* @param installAsDevDependencies - Whether to install as dev dependencies
* @returns Array of add command arguments
*/
abstract getAddArgs(installAsDevDependencies: boolean): string[];
/**
* Add packages to project dependencies
* @param packages - Array of package names/versions to add
* @param installAsDevDependencies - Whether to install as dev dependencies
* @returns Promise resolving when packages are added
*/
abstract addDependencies(
packages: string[],
installAsDevDependencies?: boolean
): Promise<void>;
/**
* Remove packages from project dependencies
* @param packages - Array of package names to remove
* @returns Promise resolving when packages are removed
*/
abstract removeDependencies(packages: string[]): Promise<void>;
/**
* Install all project dependencies
* @returns Promise resolving when installation is complete
*/
abstract installDependencies(): Promise<void>;
/**
* Run package script
* @param script - Script name to run
* @param args - Additional arguments for the script
* @returns Promise resolving when script completes
*/
abstract runScript(script: string, args?: string[]): Promise<void>;
/**
* Get package information
* @param packageName - Name of package to get info for
* @returns Promise resolving to package information
*/
abstract getPackageInfo(packageName: string): Promise<any>;
/**
* Check if package is installed
* @param packageName - Name of package to check
* @returns Promise resolving to true if package is installed
*/
abstract isPackageInstalled(packageName: string): Promise<boolean>;
/**
* Get installed package version
* @param packageName - Name of package
* @returns Promise resolving to version string or undefined
*/
abstract getInstalledVersion(packageName: string): Promise<string | undefined>;
}Factory class for creating appropriate package manager instances based on project configuration.
/**
* Factory for creating JavaScript package manager instances
*/
class JsPackageManagerFactory {
/**
* Create package manager instance based on project configuration
* @param options - Factory options
* @returns Appropriate package manager instance
*/
static getPackageManager(options?: {
/** Force specific package manager type */
force?: 'npm' | 'yarn1' | 'yarn2' | 'pnpm';
/** Working directory for package manager detection */
cwd?: string;
}): JsPackageManager;
/**
* Detect package manager type from project files
* @param cwd - Working directory to check
* @returns Detected package manager type
*/
static detectPackageManager(cwd?: string): 'npm' | 'yarn1' | 'yarn2' | 'pnpm';
}Usage Examples:
import { JsPackageManagerFactory } from "@storybook/core-common";
// Auto-detect package manager
const packageManager = JsPackageManagerFactory.getPackageManager();
console.log(`Using ${packageManager.type} package manager`);
// Force specific package manager
const yarnManager = JsPackageManagerFactory.getPackageManager({
force: 'yarn1'
});
// Install dependencies
await packageManager.installDependencies();
// Add Storybook addons
await packageManager.addDependencies([
'@storybook/addon-docs',
'@storybook/addon-controls'
], true); // Install as dev dependencies
// Run Storybook
await packageManager.runScript('storybook', ['--port', '6006']);Parse and extract package information from strings and configurations.
/**
* Parse package name and version from package string
* @param pkg - Package string (e.g., 'react@18.2.0', '@storybook/react')
* @returns Object with parsed package details
*/
function getPackageDetails(pkg: string): {
name: string;
version?: string;
scope?: string;
};Usage Example:
import { getPackageDetails } from "@storybook/core-common";
// Parse scoped package with version
const details1 = getPackageDetails('@storybook/react@8.6.14');
console.log(details1);
// {
// name: '@storybook/react',
// version: '8.6.14',
// scope: '@storybook'
// }
// Parse simple package name
const details2 = getPackageDetails('lodash');
console.log(details2);
// {
// name: 'lodash',
// scope: undefined
// }TypeScript types and utilities for working with package.json files.
/**
* Extended package.json interface with common properties
*/
interface PackageJson {
name?: string;
version?: string;
description?: string;
main?: string;
module?: string;
types?: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
scripts?: Record<string, string>;
[key: string]: any;
}import { JsPackageManagerFactory } from "@storybook/core-common";
async function setupStorybookWithPackageManager() {
// Detect package manager
const packageManager = JsPackageManagerFactory.getPackageManager();
console.log(`Detected ${packageManager.type} package manager`);
// Install Storybook dependencies based on package manager
const storybookPackages = [
'storybook',
'@storybook/react',
'@storybook/addon-essentials'
];
try {
await packageManager.addDependencies(storybookPackages, true);
console.log('Storybook packages installed successfully');
// Run initial Storybook setup
await packageManager.runScript('storybook', ['init']);
} catch (error) {
console.error(`Failed to install with ${packageManager.type}:`, error);
// Fallback to npm if other package manager fails
if (packageManager.type !== 'npm') {
const npmManager = JsPackageManagerFactory.getPackageManager({
force: 'npm'
});
await npmManager.addDependencies(storybookPackages, true);
}
}
}import { JsPackageManagerFactory, getPackageDetails } from "@storybook/core-common";
async function validateStorybookDependencies(requiredPackages: string[]) {
const packageManager = JsPackageManagerFactory.getPackageManager();
const results = [];
for (const pkg of requiredPackages) {
const details = getPackageDetails(pkg);
const isInstalled = await packageManager.isPackageInstalled(details.name);
if (isInstalled) {
const installedVersion = await packageManager.getInstalledVersion(details.name);
results.push({
name: details.name,
required: details.version,
installed: installedVersion,
valid: !details.version || installedVersion === details.version
});
} else {
results.push({
name: details.name,
required: details.version,
installed: null,
valid: false
});
}
}
return results;
}
// Usage
const validation = await validateStorybookDependencies([
'@storybook/react@8.6.14',
'@storybook/addon-essentials',
'react@^18.0.0'
]);
console.log(validation);import { JsPackageManagerFactory } from "@storybook/core-common";
class StorybookPackageManager {
private packageManager: any;
constructor(force?: 'npm' | 'yarn1' | 'yarn2' | 'pnpm') {
this.packageManager = JsPackageManagerFactory.getPackageManager({ force });
}
async installStorybookAddons(addons: string[]) {
// Validate addon names
const validAddons = addons.filter(addon =>
addon.startsWith('@storybook/') || addon.includes('storybook')
);
if (validAddons.length !== addons.length) {
console.warn('Some addons may not be Storybook-compatible');
}
// Install as dev dependencies
await this.packageManager.addDependencies(validAddons, true);
// Update package.json scripts if needed
await this.updateStorybookScripts();
}
async removeStorybookAddons(addons: string[]) {
// Remove from dependencies
await this.packageManager.removeDependencies(addons);
// Clean up any related configuration
await this.cleanupAddonConfig(addons);
}
async updateStorybookVersion(version: string) {
// Get all Storybook packages
const packageInfo = await this.packageManager.getPackageInfo('storybook');
const storybookPackages = Object.keys(packageInfo.dependencies || {})
.filter(pkg => pkg.startsWith('@storybook/'));
// Add version to all packages
const packagesWithVersion = storybookPackages.map(pkg => `${pkg}@${version}`);
// Update all Storybook packages
await this.packageManager.addDependencies(packagesWithVersion, true);
}
private async updateStorybookScripts() {
// Implementation for updating package.json scripts
}
private async cleanupAddonConfig(addons: string[]) {
// Implementation for cleaning up addon configuration
}
}
// Usage
const sbPackageManager = new StorybookPackageManager();
await sbPackageManager.installStorybookAddons([
'@storybook/addon-docs',
'@storybook/addon-controls',
'@storybook/addon-actions'
]);// npm-specific commands generated:
// Install: ['install']
// Add: ['install', '--save-dev'] or ['install', '--save']
// Remove: ['uninstall']
// Run: 'npm run'// yarn1-specific commands generated:
// Install: ['install']
// Add: ['add', '--dev'] or ['add']
// Remove: ['remove']
// Run: 'yarn'// yarn2-specific commands generated:
// Install: ['install']
// Add: ['add', '--dev'] or ['add']
// Remove: ['remove']
// Run: 'yarn'// pnpm-specific commands generated:
// Install: ['install']
// Add: ['add', '--save-dev'] or ['add', '--save']
// Remove: ['remove']
// Run: 'pnpm'Install with Tessl CLI
npx tessl i tessl/npm-storybook--core-common