or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# @pnpm/workspace.pkgs-graph

1

2

@pnpm/workspace.pkgs-graph creates dependency graphs from arrays of workspace packages in monorepo environments. It analyzes package manifests and their dependencies to build directed graph structures that represent relationships between packages, supporting various dependency types and workspace-specific dependency references.

3

4

## Package Information

5

6

- **Package Name**: @pnpm/workspace.pkgs-graph

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `pnpm add @pnpm/workspace.pkgs-graph`

10

11

## Core Imports

12

13

```typescript

14

import { createPkgGraph, type Package, type PackageNode } from "@pnpm/workspace.pkgs-graph";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { createPkgGraph } = require("@pnpm/workspace.pkgs-graph");

21

```

22

23

## Basic Usage

24

25

```typescript

26

import { createPkgGraph } from "@pnpm/workspace.pkgs-graph";

27

28

const packages = [

29

{

30

rootDir: "/workspace/foo",

31

manifest: {

32

name: "foo",

33

version: "1.0.0",

34

dependencies: {

35

bar: "^1.0.0",

36

},

37

},

38

},

39

{

40

rootDir: "/workspace/bar",

41

manifest: {

42

name: "bar",

43

version: "1.1.0",

44

},

45

}

46

];

47

48

const { graph, unmatched } = createPkgGraph(packages);

49

50

console.log(graph);

51

// {

52

// "/workspace/foo": {

53

// dependencies: ["/workspace/bar"],

54

// package: { rootDir: "/workspace/foo", manifest: { ... } }

55

// },

56

// "/workspace/bar": {

57

// dependencies: [],

58

// package: { rootDir: "/workspace/bar", manifest: { ... } }

59

// }

60

// }

61

62

console.log(unmatched);

63

// [] - empty array means all dependencies were matched

64

```

65

66

## Architecture

67

68

The package is built around several key concepts:

69

70

- **Dependency Graph Creation**: Analyzes package arrays to create directed dependency graphs

71

- **Workspace Protocol Support**: Handles `workspace:` protocol dependencies with version range resolution

72

- **Multiple Dependency Types**: Processes regular, dev, peer, and optional dependencies

73

- **Path Resolution**: Supports both relative path dependencies and file: protocol references

74

- **Version Matching**: Intelligent version range resolution within workspace environments

75

- **Unmatched Tracking**: Reports dependencies that couldn't be resolved to workspace packages

76

77

## Capabilities

78

79

### Graph Creation

80

81

Creates a dependency graph from an array of packages with configurable options for dependency processing.

82

83

```typescript { .api }

84

/**

85

* Creates a dependency graph from an array of packages

86

* @param pkgs - Array of packages to analyze

87

* @param opts - Optional configuration for graph creation

88

* @returns Object containing the dependency graph and unmatched dependencies

89

*/

90

function createPkgGraph<Pkg extends Package>(

91

pkgs: Pkg[],

92

opts?: {

93

ignoreDevDeps?: boolean;

94

linkWorkspacePackages?: boolean;

95

}

96

): {

97

graph: Record<ProjectRootDir, PackageNode<Pkg>>;

98

unmatched: Array<{ pkgName: string; range: string }>;

99

};

100

```

101

102

**Usage Examples:**

103

104

```typescript

105

// Basic graph creation

106

const result = createPkgGraph(packages);

107

108

// Ignore dev dependencies

109

const prodGraph = createPkgGraph(packages, {

110

ignoreDevDeps: true

111

});

112

113

// Disable workspace package linking

114

const strictGraph = createPkgGraph(packages, {

115

linkWorkspacePackages: false

116

});

117

```

118

119

### Workspace Protocol Support

120

121

The library fully supports pnpm's workspace protocol syntax for referencing workspace packages:

122

123

```typescript

124

// Supported workspace dependency formats

125

const packagesWithWorkspaceDeps = [

126

{

127

rootDir: "/workspace/app",

128

manifest: {

129

name: "app",

130

version: "1.0.0",

131

dependencies: {

132

"utils": "workspace:^1.0.0", // Version range

133

"config": "workspace:*", // Any version

134

"shared": "workspace:~", // Compatible version

135

"ui-alias": "workspace:ui@*", // Aliased package reference

136

},

137

},

138

}

139

];

140

```

141

142

### Directory Dependencies

143

144

Handles local directory dependencies using relative paths and file: protocol:

145

146

```typescript

147

const packagesWithLocalDeps = [

148

{

149

rootDir: "/workspace/app",

150

manifest: {

151

name: "app",

152

dependencies: {

153

"local-utils": "../utils", // Relative path

154

"shared-lib": "file:../shared", // File protocol

155

},

156

},

157

}

158

];

159

```

160

161

## Types

162

163

```typescript { .api }

164

/**

165

* Represents a package with manifest and root directory

166

*/

167

interface Package {

168

/** Package manifest containing metadata and dependencies */

169

manifest: BaseManifest;

170

/** Absolute path to the package root directory */

171

rootDir: ProjectRootDir;

172

}

173

174

/**

175

* Represents a node in the dependency graph

176

*/

177

interface PackageNode<Pkg extends Package> {

178

/** The package data */

179

package: Pkg;

180

/** Array of root directories of packages this package depends on */

181

dependencies: ProjectRootDir[];

182

}

183

184

/**

185

* Project root directory path (from @pnpm/types)

186

*/

187

type ProjectRootDir = string;

188

189

/**

190

* Base manifest interface (from @pnpm/types)

191

* Contains standard package.json fields including:

192

* - name: string

193

* - version: string

194

* - dependencies: Record<string, string>

195

* - devDependencies: Record<string, string>

196

* - peerDependencies: Record<string, string>

197

* - optionalDependencies: Record<string, string>

198

*/

199

interface BaseManifest {

200

name?: string;

201

version?: string;

202

dependencies?: Record<string, string>;

203

devDependencies?: Record<string, string>;

204

peerDependencies?: Record<string, string>;

205

optionalDependencies?: Record<string, string>;

206

}

207

```

208

209

## Configuration Options

210

211

### ignoreDevDeps

212

213

When set to `true`, development dependencies are excluded from the dependency graph:

214

215

```typescript

216

const result = createPkgGraph(packages, { ignoreDevDeps: true });

217

// Only includes dependencies, peerDependencies, and optionalDependencies

218

```

219

220

### linkWorkspacePackages

221

222

Controls whether non-workspace dependencies should be linked to workspace packages. When set to `false`, only explicit workspace: dependencies are linked:

223

224

```typescript

225

const result = createPkgGraph(packages, { linkWorkspacePackages: false });

226

// Regular version ranges won't match workspace packages

227

// Only workspace: prefixed dependencies will be linked

228

```

229

230

## Return Value Details

231

232

### Graph Structure

233

234

The `graph` object maps each package's root directory to its `PackageNode`:

235

236

```typescript

237

const { graph } = createPkgGraph(packages);

238

239

// Access specific package node

240

const fooNode = graph["/workspace/foo"];

241

console.log(fooNode.dependencies); // Array of dependency root dirs

242

console.log(fooNode.package); // Original package data

243

```

244

245

### Unmatched Dependencies

246

247

The `unmatched` array contains dependencies that couldn't be resolved to workspace packages:

248

249

```typescript

250

const { unmatched } = createPkgGraph(packages);

251

252

unmatched.forEach(({ pkgName, range }) => {

253

console.log(`Could not resolve ${pkgName}@${range} to workspace package`);

254

});

255

```

256

257

Common reasons for unmatched dependencies:

258

- External packages not present in workspace

259

- Version ranges that don't match any workspace package versions

260

- Malformed dependency specifications

261

262

## Edge Cases and Error Handling

263

264

### Missing Package Versions

265

266

The library gracefully handles packages without version fields:

267

268

```typescript

269

const packagesWithoutVersions = [

270

{

271

rootDir: "/workspace/utils",

272

manifest: {

273

name: "utils",

274

// No version field

275

},

276

}

277

];

278

279

// Still creates valid graph structure

280

const result = createPkgGraph(packagesWithoutVersions);

281

```

282

283

### Invalid Dependencies

284

285

Malformed or invalid dependency specifications are silently ignored:

286

287

```typescript

288

const packagesWithInvalidDeps = [

289

{

290

rootDir: "/workspace/app",

291

manifest: {

292

name: "app",

293

dependencies: {

294

"weird-dep": ":aaaaa", // Invalid spec - ignored

295

"valid-dep": "^1.0.0",

296

},

297

},

298

}

299

];

300

```

301

302

### Case Sensitivity

303

304

The library handles case mismatches on case-insensitive filesystems by using both fast and slow path resolution strategies.

305

306

### Prerelease Versions

307

308

Correctly matches prerelease versions when using wildcard ranges:

309

310

```typescript

311

const prereleasePackages = [

312

{

313

rootDir: "/workspace/beta",

314

manifest: {

315

name: "beta",

316

version: "1.0.0-beta.1", // Prerelease version

317

},

318

}

319

];

320

321

// "*" range will match prerelease versions

322

const result = createPkgGraph([

323

{

324

rootDir: "/workspace/app",

325

manifest: {

326

dependencies: { "beta": "*" }

327

}

328

},

329

...prereleasePackages

330

]);

331

```