or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdconfiguration.mdenvironment-cli.mdindex.mdpackage-management.mdpresets.mdstory-processing.mdtext-processing.md

package-management.mddocs/

0

# Package Management

1

2

JavaScript package manager abstraction layer supporting npm, yarn, and pnpm. Provides unified interface for dependency management operations across different package managers.

3

4

## Capabilities

5

6

### JsPackageManager Abstract Class

7

8

Base class providing common interface for all JavaScript package managers.

9

10

```typescript { .api }

11

/**

12

* Abstract base class for JavaScript package managers

13

*/

14

abstract class JsPackageManager {

15

/** Package manager type identifier */

16

abstract type: 'npm' | 'yarn1' | 'yarn2' | 'pnpm';

17

18

/**

19

* Get command-line arguments for package installation

20

* @returns Array of install command arguments

21

*/

22

abstract getInstallArgs(): string[];

23

24

/**

25

* Get the run command for executing package scripts

26

* @returns Run command string (e.g., 'npm run', 'yarn')

27

*/

28

abstract getRunCommand(): string;

29

30

/**

31

* Get command-line arguments for running scripts

32

* @returns Array of run command arguments

33

*/

34

abstract getRunArgs(): string[];

35

36

/**

37

* Get command-line arguments for adding packages

38

* @param installAsDevDependencies - Whether to install as dev dependencies

39

* @returns Array of add command arguments

40

*/

41

abstract getAddArgs(installAsDevDependencies: boolean): string[];

42

43

/**

44

* Add packages to project dependencies

45

* @param packages - Array of package names/versions to add

46

* @param installAsDevDependencies - Whether to install as dev dependencies

47

* @returns Promise resolving when packages are added

48

*/

49

abstract addDependencies(

50

packages: string[],

51

installAsDevDependencies?: boolean

52

): Promise<void>;

53

54

/**

55

* Remove packages from project dependencies

56

* @param packages - Array of package names to remove

57

* @returns Promise resolving when packages are removed

58

*/

59

abstract removeDependencies(packages: string[]): Promise<void>;

60

61

/**

62

* Install all project dependencies

63

* @returns Promise resolving when installation is complete

64

*/

65

abstract installDependencies(): Promise<void>;

66

67

/**

68

* Run package script

69

* @param script - Script name to run

70

* @param args - Additional arguments for the script

71

* @returns Promise resolving when script completes

72

*/

73

abstract runScript(script: string, args?: string[]): Promise<void>;

74

75

/**

76

* Get package information

77

* @param packageName - Name of package to get info for

78

* @returns Promise resolving to package information

79

*/

80

abstract getPackageInfo(packageName: string): Promise<any>;

81

82

/**

83

* Check if package is installed

84

* @param packageName - Name of package to check

85

* @returns Promise resolving to true if package is installed

86

*/

87

abstract isPackageInstalled(packageName: string): Promise<boolean>;

88

89

/**

90

* Get installed package version

91

* @param packageName - Name of package

92

* @returns Promise resolving to version string or undefined

93

*/

94

abstract getInstalledVersion(packageName: string): Promise<string | undefined>;

95

}

96

```

97

98

### JsPackageManagerFactory

99

100

Factory class for creating appropriate package manager instances based on project configuration.

101

102

```typescript { .api }

103

/**

104

* Factory for creating JavaScript package manager instances

105

*/

106

class JsPackageManagerFactory {

107

/**

108

* Create package manager instance based on project configuration

109

* @param options - Factory options

110

* @returns Appropriate package manager instance

111

*/

112

static getPackageManager(options?: {

113

/** Force specific package manager type */

114

force?: 'npm' | 'yarn1' | 'yarn2' | 'pnpm';

115

/** Working directory for package manager detection */

116

cwd?: string;

117

}): JsPackageManager;

118

119

/**

120

* Detect package manager type from project files

121

* @param cwd - Working directory to check

122

* @returns Detected package manager type

123

*/

124

static detectPackageManager(cwd?: string): 'npm' | 'yarn1' | 'yarn2' | 'pnpm';

125

}

126

```

127

128

**Usage Examples:**

129

130

```typescript

131

import { JsPackageManagerFactory } from "@storybook/core-common";

132

133

// Auto-detect package manager

134

const packageManager = JsPackageManagerFactory.getPackageManager();

135

console.log(`Using ${packageManager.type} package manager`);

136

137

// Force specific package manager

138

const yarnManager = JsPackageManagerFactory.getPackageManager({

139

force: 'yarn1'

140

});

141

142

// Install dependencies

143

await packageManager.installDependencies();

144

145

// Add Storybook addons

146

await packageManager.addDependencies([

147

'@storybook/addon-docs',

148

'@storybook/addon-controls'

149

], true); // Install as dev dependencies

150

151

// Run Storybook

152

await packageManager.runScript('storybook', ['--port', '6006']);

153

```

154

155

### Package Information Utilities

156

157

Parse and extract package information from strings and configurations.

158

159

```typescript { .api }

160

/**

161

* Parse package name and version from package string

162

* @param pkg - Package string (e.g., 'react@18.2.0', '@storybook/react')

163

* @returns Object with parsed package details

164

*/

165

function getPackageDetails(pkg: string): {

166

name: string;

167

version?: string;

168

scope?: string;

169

};

170

```

171

172

**Usage Example:**

173

174

```typescript

175

import { getPackageDetails } from "@storybook/core-common";

176

177

// Parse scoped package with version

178

const details1 = getPackageDetails('@storybook/react@8.6.14');

179

console.log(details1);

180

// {

181

// name: '@storybook/react',

182

// version: '8.6.14',

183

// scope: '@storybook'

184

// }

185

186

// Parse simple package name

187

const details2 = getPackageDetails('lodash');

188

console.log(details2);

189

// {

190

// name: 'lodash',

191

// scope: undefined

192

// }

193

```

194

195

### PackageJson Types and Utilities

196

197

TypeScript types and utilities for working with package.json files.

198

199

```typescript { .api }

200

/**

201

* Extended package.json interface with common properties

202

*/

203

interface PackageJson {

204

name?: string;

205

version?: string;

206

description?: string;

207

main?: string;

208

module?: string;

209

types?: string;

210

dependencies?: Record<string, string>;

211

devDependencies?: Record<string, string>;

212

peerDependencies?: Record<string, string>;

213

scripts?: Record<string, string>;

214

[key: string]: any;

215

}

216

```

217

218

## Advanced Usage Patterns

219

220

### Multi-Package Manager Support

221

222

```typescript

223

import { JsPackageManagerFactory } from "@storybook/core-common";

224

225

async function setupStorybookWithPackageManager() {

226

// Detect package manager

227

const packageManager = JsPackageManagerFactory.getPackageManager();

228

229

console.log(`Detected ${packageManager.type} package manager`);

230

231

// Install Storybook dependencies based on package manager

232

const storybookPackages = [

233

'storybook',

234

'@storybook/react',

235

'@storybook/addon-essentials'

236

];

237

238

try {

239

await packageManager.addDependencies(storybookPackages, true);

240

console.log('Storybook packages installed successfully');

241

242

// Run initial Storybook setup

243

await packageManager.runScript('storybook', ['init']);

244

245

} catch (error) {

246

console.error(`Failed to install with ${packageManager.type}:`, error);

247

248

// Fallback to npm if other package manager fails

249

if (packageManager.type !== 'npm') {

250

const npmManager = JsPackageManagerFactory.getPackageManager({

251

force: 'npm'

252

});

253

await npmManager.addDependencies(storybookPackages, true);

254

}

255

}

256

}

257

```

258

259

### Dependency Validation

260

261

```typescript

262

import { JsPackageManagerFactory, getPackageDetails } from "@storybook/core-common";

263

264

async function validateStorybookDependencies(requiredPackages: string[]) {

265

const packageManager = JsPackageManagerFactory.getPackageManager();

266

const results = [];

267

268

for (const pkg of requiredPackages) {

269

const details = getPackageDetails(pkg);

270

const isInstalled = await packageManager.isPackageInstalled(details.name);

271

272

if (isInstalled) {

273

const installedVersion = await packageManager.getInstalledVersion(details.name);

274

results.push({

275

name: details.name,

276

required: details.version,

277

installed: installedVersion,

278

valid: !details.version || installedVersion === details.version

279

});

280

} else {

281

results.push({

282

name: details.name,

283

required: details.version,

284

installed: null,

285

valid: false

286

});

287

}

288

}

289

290

return results;

291

}

292

293

// Usage

294

const validation = await validateStorybookDependencies([

295

'@storybook/react@8.6.14',

296

'@storybook/addon-essentials',

297

'react@^18.0.0'

298

]);

299

300

console.log(validation);

301

```

302

303

### Custom Package Manager Operations

304

305

```typescript

306

import { JsPackageManagerFactory } from "@storybook/core-common";

307

308

class StorybookPackageManager {

309

private packageManager: any;

310

311

constructor(force?: 'npm' | 'yarn1' | 'yarn2' | 'pnpm') {

312

this.packageManager = JsPackageManagerFactory.getPackageManager({ force });

313

}

314

315

async installStorybookAddons(addons: string[]) {

316

// Validate addon names

317

const validAddons = addons.filter(addon =>

318

addon.startsWith('@storybook/') || addon.includes('storybook')

319

);

320

321

if (validAddons.length !== addons.length) {

322

console.warn('Some addons may not be Storybook-compatible');

323

}

324

325

// Install as dev dependencies

326

await this.packageManager.addDependencies(validAddons, true);

327

328

// Update package.json scripts if needed

329

await this.updateStorybookScripts();

330

}

331

332

async removeStorybookAddons(addons: string[]) {

333

// Remove from dependencies

334

await this.packageManager.removeDependencies(addons);

335

336

// Clean up any related configuration

337

await this.cleanupAddonConfig(addons);

338

}

339

340

async updateStorybookVersion(version: string) {

341

// Get all Storybook packages

342

const packageInfo = await this.packageManager.getPackageInfo('storybook');

343

const storybookPackages = Object.keys(packageInfo.dependencies || {})

344

.filter(pkg => pkg.startsWith('@storybook/'));

345

346

// Add version to all packages

347

const packagesWithVersion = storybookPackages.map(pkg => `${pkg}@${version}`);

348

349

// Update all Storybook packages

350

await this.packageManager.addDependencies(packagesWithVersion, true);

351

}

352

353

private async updateStorybookScripts() {

354

// Implementation for updating package.json scripts

355

}

356

357

private async cleanupAddonConfig(addons: string[]) {

358

// Implementation for cleaning up addon configuration

359

}

360

}

361

362

// Usage

363

const sbPackageManager = new StorybookPackageManager();

364

await sbPackageManager.installStorybookAddons([

365

'@storybook/addon-docs',

366

'@storybook/addon-controls',

367

'@storybook/addon-actions'

368

]);

369

```

370

371

## Package Manager Specific Behavior

372

373

### NPM Specific

374

375

```typescript

376

// npm-specific commands generated:

377

// Install: ['install']

378

// Add: ['install', '--save-dev'] or ['install', '--save']

379

// Remove: ['uninstall']

380

// Run: 'npm run'

381

```

382

383

### Yarn 1 Specific

384

385

```typescript

386

// yarn1-specific commands generated:

387

// Install: ['install']

388

// Add: ['add', '--dev'] or ['add']

389

// Remove: ['remove']

390

// Run: 'yarn'

391

```

392

393

### Yarn 2+ Specific

394

395

```typescript

396

// yarn2-specific commands generated:

397

// Install: ['install']

398

// Add: ['add', '--dev'] or ['add']

399

// Remove: ['remove']

400

// Run: 'yarn'

401

```

402

403

### PNPM Specific

404

405

```typescript

406

// pnpm-specific commands generated:

407

// Install: ['install']

408

// Add: ['add', '--save-dev'] or ['add', '--save']

409

// Remove: ['remove']

410

// Run: 'pnpm'

411

```