or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdindex.mdpackage-management.mdpatch-application.mdpatch-creation.mdrebase-operations.mdutility-apis.md

package-management.mddocs/

0

# Package Management Integration

1

2

Package manager detection, version resolution, and lockfile integration for npm, yarn, and npm-shrinkwrap environments. This module provides comprehensive support for different package managers and their specific behaviors, lockfile formats, and resolution strategies.

3

4

## Capabilities

5

6

### Package Manager Detection

7

8

Automatic detection of package manager based on lockfiles and project configuration.

9

10

```typescript { .api }

11

/**

12

* Detect which package manager is being used

13

* @param appRootPath - Application root directory path

14

* @param overridePackageManager - Force specific package manager

15

* @returns Detected or overridden package manager

16

*/

17

function detectPackageManager(

18

appRootPath: string,

19

overridePackageManager: PackageManager | null

20

): PackageManager;

21

22

type PackageManager = "yarn" | "npm" | "npm-shrinkwrap";

23

```

24

25

The detection logic checks for:

26

- `yarn.lock` → yarn

27

- `package-lock.json` → npm

28

- `npm-shrinkwrap.json` → npm-shrinkwrap

29

- Falls back to npm if no lockfile is found

30

31

**Usage Examples:**

32

33

```typescript

34

import { detectPackageManager } from "patch-package/dist/detectPackageManager";

35

36

// Auto-detect package manager

37

const packageManager = detectPackageManager(process.cwd(), null);

38

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

39

40

// Force yarn usage

41

const forcedYarn = detectPackageManager(process.cwd(), "yarn");

42

43

// Use in patch creation

44

import { makePatch } from "patch-package/dist/makePatch";

45

makePatch({

46

packagePathSpecifier: "lodash",

47

appPath: process.cwd(),

48

packageManager: detectPackageManager(process.cwd(), null),

49

// ... other options

50

});

51

```

52

53

### Package Resolution

54

55

Resolution of package versions and locations from lockfiles.

56

57

```typescript { .api }

58

/**

59

* Get package resolution from lockfiles

60

* @param options - Package resolution options

61

* @returns Resolved package version string

62

*/

63

function getPackageResolution(options: PackageResolutionOptions): string;

64

65

interface PackageResolutionOptions {

66

/** Package details for resolution */

67

packageDetails: PackageDetails;

68

/** Package manager type */

69

packageManager: PackageManager;

70

/** Application path */

71

appPath: string;

72

}

73

```

74

75

Resolution behavior varies by package manager:

76

- **npm**: Reads `package-lock.json` for exact versions

77

- **yarn**: Parses `yarn.lock` for resolution info

78

- **npm-shrinkwrap**: Uses `npm-shrinkwrap.json` for locked versions

79

80

**Usage Examples:**

81

82

```typescript

83

import { getPackageResolution } from "patch-package/dist/getPackageResolution";

84

import { getPatchDetailsFromCliString } from "patch-package/dist/PackageDetails";

85

86

const packageDetails = getPatchDetailsFromCliString("lodash");

87

const resolution = getPackageResolution({

88

packageDetails,

89

packageManager: "yarn",

90

appPath: process.cwd()

91

});

92

93

console.log(`Resolved version: ${resolution}`);

94

```

95

96

### Version Utilities

97

98

Utilities for working with package versions and semver.

99

100

```typescript { .api }

101

/**

102

* Get package version from package.json

103

* @param packageJsonPath - Path to package.json file

104

* @returns Package version string

105

*/

106

function getPackageVersion(packageJsonPath: string): string;

107

108

/**

109

* Coerce version string to valid semver

110

* @param version - Version string to coerce

111

* @returns Valid semver string or null if invalid

112

*/

113

function coerceSemVer(version: string): string | null;

114

```

115

116

**Usage Examples:**

117

118

```typescript

119

import { getPackageVersion, coerceSemVer } from "patch-package/dist/getPackageVersion";

120

121

// Read version from package.json

122

const version = getPackageVersion("./node_modules/lodash/package.json");

123

124

// Coerce non-standard version to semver

125

const coercedVersion = coerceSemVer("1.0.0-beta.1+build.123");

126

// Returns: "1.0.0-beta.1"

127

128

const invalidVersion = coerceSemVer("not-a-version");

129

// Returns: null

130

```

131

132

## Dependency Analysis

133

134

### Development Dependency Detection

135

136

Determine if a package is a development dependency to optimize patch application.

137

138

```typescript { .api }

139

/**

140

* Check if package is development dependency

141

* @param options - Development dependency check options

142

* @returns True if package is dev dependency

143

*/

144

function packageIsDevDependency(options: DevDepOptions): boolean;

145

146

interface DevDepOptions {

147

/** Application path */

148

appPath: string;

149

/** Patch details for the package */

150

patchDetails: PatchedPackageDetails;

151

}

152

```

153

154

This function checks:

155

- `devDependencies` in package.json

156

- Nested dependency relationships

157

- Package installation context

158

159

**Usage Examples:**

160

161

```typescript

162

import { packageIsDevDependency } from "patch-package/dist/packageIsDevDependency";

163

164

const isDevDep = packageIsDevDependency({

165

appPath: process.cwd(),

166

patchDetails: {

167

name: "typescript",

168

version: "4.5.0",

169

// ... other patch details

170

}

171

});

172

173

if (isDevDep) {

174

console.log("This is a development dependency");

175

}

176

```

177

178

### File Dependency Resolution

179

180

Handle relative file dependencies in package resolutions.

181

182

```typescript { .api }

183

/**

184

* Resolve relative file dependencies in package resolutions

185

* @param appRootPath - Application root path

186

* @param resolutions - Package resolutions map

187

* @returns Updated resolutions with resolved file paths

188

*/

189

function resolveRelativeFileDependencies(

190

appRootPath: string,

191

resolutions: Record<string, string>

192

): Record<string, string>;

193

```

194

195

Handles cases like:

196

- `"my-package": "file:../local-package"`

197

- `"utils": "file:./packages/utils"`

198

- Relative path resolution across different project structures

199

200

**Usage Examples:**

201

202

```typescript

203

import { resolveRelativeFileDependencies } from "patch-package/dist/resolveRelativeFileDependencies";

204

205

const resolutions = {

206

"local-utils": "file:../utils",

207

"shared-lib": "file:./packages/shared",

208

"regular-dep": "^1.0.0"

209

};

210

211

const resolved = resolveRelativeFileDependencies(process.cwd(), resolutions);

212

// Converts relative file: paths to absolute paths

213

```

214

215

## Application Root Detection

216

217

### App Root Discovery

218

219

Find application root by locating package.json files in the directory hierarchy.

220

221

```typescript { .api }

222

/**

223

* Find application root by locating package.json

224

* @returns Application root path

225

* @throws Error if no package.json found

226

*/

227

function getAppRootPath(): string;

228

```

229

230

The function searches up the directory tree from the current working directory until it finds a `package.json` file, indicating the project root.

231

232

**Usage Examples:**

233

234

```typescript

235

import { getAppRootPath } from "patch-package/dist/getAppRootPath";

236

237

try {

238

const appRoot = getAppRootPath();

239

console.log(`Application root: ${appRoot}`);

240

} catch (error) {

241

console.error("Could not find application root");

242

}

243

```

244

245

## Package Manager-Specific Behaviors

246

247

### npm Integration

248

249

npm-specific handling including:

250

- `package-lock.json` parsing

251

- npm v5+ compatibility

252

- Shrinkwrap file support

253

- npm workspace detection

254

255

### yarn Integration

256

257

yarn v1-specific handling including:

258

- `yarn.lock` parsing

259

- Yarn workspace detection

260

- Resolution strategy differences

261

- Version constraint handling

262

263

### Workspace Support

264

265

Support for monorepo structures:

266

- npm workspaces

267

- yarn workspaces

268

- Lerna integration

269

- Relative dependency resolution

270

271

**Workspace Example:**

272

273

```typescript

274

import { detectPackageManager } from "patch-package/dist/detectPackageManager";

275

import { getAppRootPath } from "patch-package/dist/getAppRootPath";

276

277

// Works in monorepo workspaces

278

const appRoot = getAppRootPath(); // Finds workspace root

279

const packageManager = detectPackageManager(appRoot, null);

280

281

// Will correctly detect yarn workspaces or npm workspaces

282

console.log(`Workspace uses ${packageManager}`);

283

```

284

285

## Integration Examples

286

287

### Complete Package Manager Workflow

288

289

```typescript

290

import {

291

detectPackageManager,

292

getPackageResolution,

293

packageIsDevDependency,

294

getAppRootPath

295

} from "patch-package/dist";

296

297

// Full workflow example

298

async function analyzePackage(packageName: string) {

299

// Find application root

300

const appPath = getAppRootPath();

301

302

// Detect package manager

303

const packageManager = detectPackageManager(appPath, null);

304

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

305

306

// Get package details

307

const packageDetails = getPatchDetailsFromCliString(packageName);

308

if (!packageDetails) {

309

throw new Error(`Invalid package: ${packageName}`);

310

}

311

312

// Resolve package version

313

const resolution = getPackageResolution({

314

packageDetails,

315

packageManager,

316

appPath

317

});

318

console.log(`Resolved version: ${resolution}`);

319

320

// Check if development dependency

321

const isDevDep = packageIsDevDependency({

322

appPath,

323

patchDetails: {

324

...packageDetails,

325

version: resolution,

326

patchFilename: `${packageName}+${resolution}.patch`,

327

isDevOnly: false

328

}

329

});

330

331

console.log(`Development dependency: ${isDevDep}`);

332

333

return {

334

packageManager,

335

resolution,

336

isDevDep,

337

appPath

338

};

339

}

340

```

341

342

This integration layer ensures patch-package works seamlessly across different package manager environments while respecting each manager's specific behaviors and conventions.