@nx/devkit 22.6.0-beta.2 → 22.6.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/devkit",
3
- "version": "22.6.0-beta.2",
3
+ "version": "22.6.0-beta.3",
4
4
  "private": false,
5
5
  "description": "The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by leveraging the Nx Devkit](https://nx.dev/extending-nx/intro/getting-started) on our docs.",
6
6
  "repository": {
@@ -33,12 +33,12 @@
33
33
  "tslib": "^2.3.0",
34
34
  "semver": "^7.6.3",
35
35
  "yargs-parser": "21.1.1",
36
- "minimatch": "10.1.1",
36
+ "minimatch": "10.2.1",
37
37
  "enquirer": "~2.3.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "jest": "^30.0.2",
41
- "nx": "22.6.0-beta.2"
41
+ "nx": "22.6.0-beta.3"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "nx": ">= 21 <= 23 || ^22.0.0-0"
@@ -1 +1 @@
1
- {"version":3,"file":"manager-factory.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/manager-factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,GACpB,cAAc,GAAG,IAAI,CASvB"}
1
+ {"version":3,"file":"manager-factory.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/manager-factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIhD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,GACpB,cAAc,GAAG,IAAI,CAWvB"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCatalogManager = getCatalogManager;
4
4
  const devkit_exports_1 = require("nx/src/devkit-exports");
5
5
  const pnpm_manager_1 = require("./pnpm-manager");
6
+ const yarn_manager_1 = require("./yarn-manager");
6
7
  /**
7
8
  * Factory function to get the appropriate catalog manager based on the package manager
8
9
  */
@@ -11,6 +12,8 @@ function getCatalogManager(workspaceRoot) {
11
12
  switch (packageManager) {
12
13
  case 'pnpm':
13
14
  return new pnpm_manager_1.PnpmCatalogManager();
15
+ case 'yarn':
16
+ return new yarn_manager_1.YarnCatalogManager();
14
17
  default:
15
18
  return null;
16
19
  }
@@ -1,6 +1,6 @@
1
1
  import type { Tree } from 'nx/src/devkit-exports';
2
- import type { PnpmWorkspaceYaml } from 'nx/src/utils/pnpm-workspace';
3
- import type { CatalogReference } from './types';
2
+ import type { CatalogDefinitions, CatalogReference } from './types';
3
+ export declare function formatCatalogError(error: string, suggestions: string[]): string;
4
4
  /**
5
5
  * Interface for catalog managers that handle package manager-specific catalog implementations.
6
6
  */
@@ -8,11 +8,12 @@ export interface CatalogManager {
8
8
  readonly name: string;
9
9
  isCatalogReference(version: string): boolean;
10
10
  parseCatalogReference(version: string): CatalogReference | null;
11
+ getCatalogDefinitionFilePaths(): string[];
11
12
  /**
12
13
  * Get catalog definitions from the workspace.
13
14
  */
14
- getCatalogDefinitions(workspaceRoot: string): PnpmWorkspaceYaml | null;
15
- getCatalogDefinitions(tree: Tree): PnpmWorkspaceYaml | null;
15
+ getCatalogDefinitions(workspaceRoot: string): CatalogDefinitions | null;
16
+ getCatalogDefinitions(tree: Tree): CatalogDefinitions | null;
16
17
  /**
17
18
  * Resolve a catalog reference to an actual version.
18
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAE7C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAEhE;;OAEG;IACH,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAAC;IACvE,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAAC;IAE5D;;OAEG;IACH,uBAAuB,CACrB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAAC;IACjB,uBAAuB,CACrB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAAC;IAEjB;;OAEG;IACH,wBAAwB,CACtB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI,CAAC;IACR,wBAAwB,CACtB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI,CAAC;IAER;;OAEG;IACH,qBAAqB,CACnB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI,CAAC;IACR,qBAAqB,CACnB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI,CAAC;CACT"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEpE,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAWR;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAE7C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAEhE,6BAA6B,IAAI,MAAM,EAAE,CAAC;IAE1C;;OAEG;IACH,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAAC;IACxE,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAE7D;;OAEG;IACH,uBAAuB,CACrB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAAC;IACjB,uBAAuB,CACrB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI,CAAC;IAEjB;;OAEG;IACH,wBAAwB,CACtB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI,CAAC;IACR,wBAAwB,CACtB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI,CAAC;IAER;;OAEG;IACH,qBAAqB,CACnB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI,CAAC;IACR,qBAAqB,CACnB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI,CAAC;CACT"}
@@ -1,2 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatCatalogError = formatCatalogError;
4
+ function formatCatalogError(error, suggestions) {
5
+ let message = error;
6
+ if (suggestions.length > 0) {
7
+ message += '\n\nSuggestions:';
8
+ suggestions.forEach((suggestion) => {
9
+ message += `\n • ${suggestion}`;
10
+ });
11
+ }
12
+ return message;
13
+ }
@@ -1,7 +1,6 @@
1
1
  import { type Tree } from 'nx/src/devkit-exports';
2
- import type { PnpmWorkspaceYaml } from 'nx/src/utils/pnpm-workspace';
3
- import type { CatalogManager } from './manager';
4
- import { type CatalogReference } from './types';
2
+ import { type CatalogManager } from './manager';
3
+ import type { CatalogDefinitions, CatalogReference } from './types';
5
4
  /**
6
5
  * PNPM-specific catalog manager implementation
7
6
  */
@@ -10,7 +9,8 @@ export declare class PnpmCatalogManager implements CatalogManager {
10
9
  readonly catalogProtocol = "catalog:";
11
10
  isCatalogReference(version: string): boolean;
12
11
  parseCatalogReference(version: string): CatalogReference | null;
13
- getCatalogDefinitions(treeOrRoot: Tree | string): PnpmWorkspaceYaml | null;
12
+ getCatalogDefinitionFilePaths(): string[];
13
+ getCatalogDefinitions(treeOrRoot: Tree | string): CatalogDefinitions | null;
14
14
  resolveCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): string | null;
15
15
  validateCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): void;
16
16
  updateCatalogVersions(treeOrRoot: Tree | string, updates: Array<{
@@ -1 +1 @@
1
- {"version":3,"file":"pnpm-manager.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/pnpm-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD;;GAEG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,eAAe,cAAc;IAEtC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI5C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAe/D,qBAAqB,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAe1E,uBAAuB,CACrB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI;IAuBhB,wBAAwB,CACtB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI;IA0HP,qBAAqB,CACnB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI;CAgFR"}
1
+ {"version":3,"file":"pnpm-manager.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/pnpm-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,KAAK,EACV,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAIjB;;GAEG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,eAAe,cAAc;IAEtC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI5C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAe/D,6BAA6B,IAAI,MAAM,EAAE;IAIzC,qBAAqB,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAe3E,uBAAuB,CACrB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI;IAsBhB,wBAAwB,CACtB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI;IAyHP,qBAAqB,CACnB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI;CAgFR"}
@@ -6,6 +6,8 @@ const node_fs_1 = require("node:fs");
6
6
  const node_path_1 = require("node:path");
7
7
  const devkit_exports_1 = require("nx/src/devkit-exports");
8
8
  const devkit_internals_1 = require("nx/src/devkit-internals");
9
+ const manager_1 = require("./manager");
10
+ const PNPM_WORKSPACE_FILENAME = 'pnpm-workspace.yaml';
9
11
  /**
10
12
  * PNPM-specific catalog manager implementation
11
13
  */
@@ -29,19 +31,22 @@ class PnpmCatalogManager {
29
31
  isDefaultCatalog: isDefault,
30
32
  };
31
33
  }
34
+ getCatalogDefinitionFilePaths() {
35
+ return [PNPM_WORKSPACE_FILENAME];
36
+ }
32
37
  getCatalogDefinitions(treeOrRoot) {
33
38
  if (typeof treeOrRoot === 'string') {
34
- const pnpmWorkspacePath = (0, node_path_1.join)(treeOrRoot, 'pnpm-workspace.yaml');
35
- if (!(0, node_fs_1.existsSync)(pnpmWorkspacePath)) {
39
+ const configPath = (0, node_path_1.join)(treeOrRoot, PNPM_WORKSPACE_FILENAME);
40
+ if (!(0, node_fs_1.existsSync)(configPath)) {
36
41
  return null;
37
42
  }
38
- return readYamlFileFromFs(pnpmWorkspacePath);
43
+ return readConfigFromFs(configPath);
39
44
  }
40
45
  else {
41
- if (!treeOrRoot.exists('pnpm-workspace.yaml')) {
46
+ if (!treeOrRoot.exists(PNPM_WORKSPACE_FILENAME)) {
42
47
  return null;
43
48
  }
44
- return readYamlFileFromTree(treeOrRoot, 'pnpm-workspace.yaml');
49
+ return readConfigFromTree(treeOrRoot, PNPM_WORKSPACE_FILENAME);
45
50
  }
46
51
  }
47
52
  resolveCatalogReference(treeOrRoot, packageName, version) {
@@ -49,18 +54,17 @@ class PnpmCatalogManager {
49
54
  if (!catalogRef) {
50
55
  return null;
51
56
  }
52
- const workspaceConfig = this.getCatalogDefinitions(treeOrRoot);
53
- if (!workspaceConfig) {
57
+ const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
58
+ if (!catalogDefs) {
54
59
  return null;
55
60
  }
56
61
  let catalogToUse;
57
62
  if (catalogRef.isDefaultCatalog) {
58
63
  // Check both locations for default catalog
59
- catalogToUse =
60
- workspaceConfig.catalog ?? workspaceConfig.catalogs?.default;
64
+ catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
61
65
  }
62
66
  else if (catalogRef.catalogName) {
63
- catalogToUse = workspaceConfig.catalogs?.[catalogRef.catalogName];
67
+ catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
64
68
  }
65
69
  return catalogToUse?.[packageName] || null;
66
70
  }
@@ -69,44 +73,43 @@ class PnpmCatalogManager {
69
73
  if (!catalogRef) {
70
74
  throw new Error(`Invalid catalog reference syntax: "${version}". Expected format: "catalog:" or "catalog:name"`);
71
75
  }
72
- const workspaceConfig = this.getCatalogDefinitions(treeOrRoot);
73
- if (!workspaceConfig) {
74
- throw new Error(formatCatalogError('Cannot get Pnpm Catalog definitions. No pnpm-workspace.yaml found in workspace root.', ['Create a pnpm-workspace.yaml file in your workspace root']));
76
+ const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
77
+ if (!catalogDefs) {
78
+ throw new Error((0, manager_1.formatCatalogError)(`Cannot get Pnpm catalog definitions. No ${PNPM_WORKSPACE_FILENAME} found in workspace root.`, [`Create a ${PNPM_WORKSPACE_FILENAME} file in your workspace root`]));
75
79
  }
76
80
  let catalogToUse;
77
81
  if (catalogRef.isDefaultCatalog) {
78
- const hasCatalog = !!workspaceConfig.catalog;
79
- const hasCatalogsDefault = !!workspaceConfig.catalogs?.default;
82
+ const hasCatalog = !!catalogDefs.catalog;
83
+ const hasCatalogsDefault = !!catalogDefs.catalogs?.default;
80
84
  // Error if both defined (matches pnpm behavior)
81
85
  if (hasCatalog && hasCatalogsDefault) {
82
86
  throw new Error("The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.");
83
87
  }
84
- catalogToUse =
85
- workspaceConfig.catalog ?? workspaceConfig.catalogs?.default;
88
+ catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
86
89
  if (!catalogToUse) {
87
- const availableCatalogs = Object.keys(workspaceConfig.catalogs || {});
90
+ const availableCatalogs = Object.keys(catalogDefs.catalogs || {});
88
91
  const suggestions = [
89
- 'Define a default catalog in pnpm-workspace.yaml under the "catalog" key',
92
+ `Define a default catalog in ${PNPM_WORKSPACE_FILENAME} under the "catalog" key`,
90
93
  ];
91
94
  if (availableCatalogs.length > 0) {
92
95
  suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
93
96
  .map((c) => `"catalog:${c}"`)
94
97
  .join(', ')}`);
95
98
  }
96
- throw new Error(formatCatalogError('No default catalog defined in pnpm-workspace.yaml', suggestions));
99
+ throw new Error((0, manager_1.formatCatalogError)(`No default catalog defined in ${PNPM_WORKSPACE_FILENAME}`, suggestions));
97
100
  }
98
101
  }
99
102
  else if (catalogRef.catalogName) {
100
- catalogToUse = workspaceConfig.catalogs?.[catalogRef.catalogName];
103
+ catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
101
104
  if (!catalogToUse) {
102
- const availableCatalogs = Object.keys(workspaceConfig.catalogs || {}).filter((c) => c !== 'default');
103
- const defaultCatalog = !!workspaceConfig.catalog
105
+ const availableCatalogs = Object.keys(catalogDefs.catalogs || {}).filter((c) => c !== 'default');
106
+ const defaultCatalog = !!catalogDefs.catalog
104
107
  ? 'catalog'
105
- : !workspaceConfig.catalogs?.default
108
+ : !catalogDefs.catalogs?.default
106
109
  ? 'catalogs.default'
107
110
  : null;
108
111
  const suggestions = [
109
- 'Define the catalog in pnpm-workspace.yaml under the "catalogs" key',
112
+ `Define the catalog in ${PNPM_WORKSPACE_FILENAME} under the "catalogs" key`,
110
113
  ];
111
114
  if (availableCatalogs.length > 0) {
112
115
  suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
@@ -116,14 +119,14 @@ class PnpmCatalogManager {
116
119
  if (defaultCatalog) {
117
120
  suggestions.push(`Or use the default catalog ("${defaultCatalog}")`);
118
121
  }
119
- throw new Error(formatCatalogError(`Catalog "${catalogRef.catalogName}" not found in pnpm-workspace.yaml`, suggestions));
122
+ throw new Error((0, manager_1.formatCatalogError)(`Catalog "${catalogRef.catalogName}" not found in ${PNPM_WORKSPACE_FILENAME}`, suggestions));
120
123
  }
121
124
  }
122
125
  if (!catalogToUse[packageName]) {
123
126
  let catalogName;
124
127
  if (catalogRef.isDefaultCatalog) {
125
128
  // Context-aware messaging based on which location exists
126
- const hasCatalog = !!workspaceConfig.catalog;
129
+ const hasCatalog = !!catalogDefs.catalog;
127
130
  catalogName = hasCatalog
128
131
  ? 'default catalog ("catalog")'
129
132
  : 'default catalog ("catalogs.default")';
@@ -133,14 +136,14 @@ class PnpmCatalogManager {
133
136
  }
134
137
  const availablePackages = Object.keys(catalogToUse);
135
138
  const suggestions = [
136
- `Add "${packageName}" to ${catalogName} in pnpm-workspace.yaml`,
139
+ `Add "${packageName}" to ${catalogName} in ${PNPM_WORKSPACE_FILENAME}`,
137
140
  ];
138
141
  if (availablePackages.length > 0) {
139
142
  suggestions.push(`Or select from the available packages in ${catalogName}: ${availablePackages
140
143
  .map((p) => `"${p}"`)
141
144
  .join(', ')}`);
142
145
  }
143
- throw new Error(formatCatalogError(`Package "${packageName}" not found in ${catalogName}`, suggestions));
146
+ throw new Error((0, manager_1.formatCatalogError)(`Package "${packageName}" not found in ${catalogName}`, suggestions));
144
147
  }
145
148
  }
146
149
  updateCatalogVersions(treeOrRoot, updates) {
@@ -148,29 +151,29 @@ class PnpmCatalogManager {
148
151
  let readYaml;
149
152
  let writeYaml;
150
153
  if (typeof treeOrRoot === 'string') {
151
- const workspaceYamlPath = (0, node_path_1.join)(treeOrRoot, 'pnpm-workspace.yaml');
152
- checkExists = () => (0, node_fs_1.existsSync)(workspaceYamlPath);
153
- readYaml = () => (0, node_fs_1.readFileSync)(workspaceYamlPath, 'utf-8');
154
- writeYaml = (content) => (0, node_fs_1.writeFileSync)(workspaceYamlPath, content, 'utf-8');
154
+ const configPath = (0, node_path_1.join)(treeOrRoot, PNPM_WORKSPACE_FILENAME);
155
+ checkExists = () => (0, node_fs_1.existsSync)(configPath);
156
+ readYaml = () => (0, node_fs_1.readFileSync)(configPath, 'utf-8');
157
+ writeYaml = (content) => (0, node_fs_1.writeFileSync)(configPath, content, 'utf-8');
155
158
  }
156
159
  else {
157
- checkExists = () => treeOrRoot.exists('pnpm-workspace.yaml');
158
- readYaml = () => treeOrRoot.read('pnpm-workspace.yaml', 'utf-8');
159
- writeYaml = (content) => treeOrRoot.write('pnpm-workspace.yaml', content);
160
+ checkExists = () => treeOrRoot.exists(PNPM_WORKSPACE_FILENAME);
161
+ readYaml = () => treeOrRoot.read(PNPM_WORKSPACE_FILENAME, 'utf-8');
162
+ writeYaml = (content) => treeOrRoot.write(PNPM_WORKSPACE_FILENAME, content);
160
163
  }
161
164
  if (!checkExists()) {
162
165
  devkit_exports_1.output.warn({
163
- title: 'No pnpm-workspace.yaml found',
166
+ title: `No ${PNPM_WORKSPACE_FILENAME} found`,
164
167
  bodyLines: [
165
- 'Cannot update catalog versions without a pnpm-workspace.yaml file.',
166
- 'Create a pnpm-workspace.yaml file to use catalogs.',
168
+ `Cannot update catalog versions without a ${PNPM_WORKSPACE_FILENAME} file.`,
169
+ `Create a ${PNPM_WORKSPACE_FILENAME} file to use catalogs.`,
167
170
  ],
168
171
  });
169
172
  return;
170
173
  }
171
174
  try {
172
- const workspaceContent = readYaml();
173
- const workspaceData = (0, js_yaml_1.load)(workspaceContent) || {};
175
+ const configContent = readYaml();
176
+ const configData = (0, js_yaml_1.load)(configContent) || {};
174
177
  let hasChanges = false;
175
178
  for (const update of updates) {
176
179
  const { packageName, version, catalogName } = update;
@@ -178,23 +181,23 @@ class PnpmCatalogManager {
178
181
  let targetCatalog;
179
182
  if (!normalizedCatalogName) {
180
183
  // Default catalog - update whichever exists, prefer catalog over catalogs.default
181
- if (workspaceData.catalog) {
182
- targetCatalog = workspaceData.catalog;
184
+ if (configData.catalog) {
185
+ targetCatalog = configData.catalog;
183
186
  }
184
- else if (workspaceData.catalogs?.default) {
185
- targetCatalog = workspaceData.catalogs.default;
187
+ else if (configData.catalogs?.default) {
188
+ targetCatalog = configData.catalogs.default;
186
189
  }
187
190
  else {
188
191
  // Neither exists, create catalog (shorthand syntax)
189
- workspaceData.catalog ??= {};
190
- targetCatalog = workspaceData.catalog;
192
+ configData.catalog ??= {};
193
+ targetCatalog = configData.catalog;
191
194
  }
192
195
  }
193
196
  else {
194
197
  // Named catalog
195
- workspaceData.catalogs ??= {};
196
- workspaceData.catalogs[normalizedCatalogName] ??= {};
197
- targetCatalog = workspaceData.catalogs[normalizedCatalogName];
198
+ configData.catalogs ??= {};
199
+ configData.catalogs[normalizedCatalogName] ??= {};
200
+ targetCatalog = configData.catalogs[normalizedCatalogName];
198
201
  }
199
202
  if (targetCatalog[packageName] !== version) {
200
203
  targetCatalog[packageName] = version;
@@ -202,7 +205,7 @@ class PnpmCatalogManager {
202
205
  }
203
206
  }
204
207
  if (hasChanges) {
205
- writeYaml((0, js_yaml_1.dump)(workspaceData, {
208
+ writeYaml((0, js_yaml_1.dump)(configData, {
206
209
  indent: 2,
207
210
  quotingType: '"',
208
211
  forceQuotes: true,
@@ -219,39 +222,28 @@ class PnpmCatalogManager {
219
222
  }
220
223
  }
221
224
  exports.PnpmCatalogManager = PnpmCatalogManager;
222
- function readYamlFileFromFs(path) {
225
+ function readConfigFromFs(path) {
223
226
  try {
224
227
  return (0, devkit_internals_1.readYamlFile)(path);
225
228
  }
226
229
  catch (error) {
227
230
  devkit_exports_1.output.warn({
228
- title: 'Unable to parse pnpm-workspace.yaml',
231
+ title: `Unable to parse ${PNPM_WORKSPACE_FILENAME}`,
229
232
  bodyLines: [error.toString()],
230
233
  });
231
234
  return null;
232
235
  }
233
236
  }
234
- function readYamlFileFromTree(tree, path) {
237
+ function readConfigFromTree(tree, path) {
235
238
  const content = tree.read(path, 'utf-8');
236
- const { load } = require('@zkochan/js-yaml');
237
239
  try {
238
- return load(content, { filename: path });
240
+ return (0, js_yaml_1.load)(content, { filename: path });
239
241
  }
240
242
  catch (error) {
241
243
  devkit_exports_1.output.warn({
242
- title: 'Unable to parse pnpm-workspace.yaml',
244
+ title: `Unable to parse ${PNPM_WORKSPACE_FILENAME}`,
243
245
  bodyLines: [error.toString()],
244
246
  });
245
247
  return null;
246
248
  }
247
249
  }
248
- function formatCatalogError(error, suggestions) {
249
- let message = error;
250
- if (suggestions && suggestions.length > 0) {
251
- message += '\n\nSuggestions:';
252
- suggestions.forEach((suggestion) => {
253
- message += `\n • ${suggestion}`;
254
- });
255
- }
256
- return message;
257
- }
@@ -2,4 +2,11 @@ export interface CatalogReference {
2
2
  catalogName?: string;
3
3
  isDefaultCatalog: boolean;
4
4
  }
5
+ export interface CatalogEntry {
6
+ [packageName: string]: string;
7
+ }
8
+ export interface CatalogDefinitions {
9
+ catalog?: CatalogEntry;
10
+ catalogs?: Record<string, CatalogEntry>;
11
+ }
5
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC3B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC"}
@@ -0,0 +1,22 @@
1
+ import { type Tree } from 'nx/src/devkit-exports';
2
+ import { type CatalogManager } from './manager';
3
+ import type { CatalogDefinitions, CatalogReference } from './types';
4
+ /**
5
+ * Yarn Berry (v4+) catalog manager implementation
6
+ */
7
+ export declare class YarnCatalogManager implements CatalogManager {
8
+ readonly name = "yarn";
9
+ readonly catalogProtocol = "catalog:";
10
+ isCatalogReference(version: string): boolean;
11
+ parseCatalogReference(version: string): CatalogReference | null;
12
+ getCatalogDefinitionFilePaths(): string[];
13
+ getCatalogDefinitions(treeOrRoot: Tree | string): CatalogDefinitions | null;
14
+ resolveCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): string | null;
15
+ validateCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): void;
16
+ updateCatalogVersions(treeOrRoot: Tree | string, updates: Array<{
17
+ packageName: string;
18
+ version: string;
19
+ catalogName?: string;
20
+ }>): void;
21
+ }
22
+ //# sourceMappingURL=yarn-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yarn-manager.d.ts","sourceRoot":"","sources":["../../../../../../packages/devkit/src/utils/catalog/yarn-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,KAAK,EACV,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAIjB;;GAEG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,eAAe,cAAc;IAEtC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI5C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAe/D,6BAA6B,IAAI,MAAM,EAAE;IAIzC,qBAAqB,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAe3E,uBAAuB,CACrB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,IAAI;IAsBhB,wBAAwB,CACtB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,IAAI;IAyHP,qBAAqB,CACnB,UAAU,EAAE,IAAI,GAAG,MAAM,EACzB,OAAO,EAAE,KAAK,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,GACD,IAAI;CA+ER"}
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.YarnCatalogManager = void 0;
4
+ const js_yaml_1 = require("@zkochan/js-yaml");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const devkit_exports_1 = require("nx/src/devkit-exports");
8
+ const devkit_internals_1 = require("nx/src/devkit-internals");
9
+ const manager_1 = require("./manager");
10
+ const YARNRC_FILENAME = '.yarnrc.yml';
11
+ /**
12
+ * Yarn Berry (v4+) catalog manager implementation
13
+ */
14
+ class YarnCatalogManager {
15
+ constructor() {
16
+ this.name = 'yarn';
17
+ this.catalogProtocol = 'catalog:';
18
+ }
19
+ isCatalogReference(version) {
20
+ return version.startsWith(this.catalogProtocol);
21
+ }
22
+ parseCatalogReference(version) {
23
+ if (!this.isCatalogReference(version)) {
24
+ return null;
25
+ }
26
+ const catalogName = version.substring(this.catalogProtocol.length);
27
+ // Normalize both "catalog:" and "catalog:default" to the same representation
28
+ const isDefault = !catalogName || catalogName === 'default';
29
+ return {
30
+ catalogName: isDefault ? undefined : catalogName,
31
+ isDefaultCatalog: isDefault,
32
+ };
33
+ }
34
+ getCatalogDefinitionFilePaths() {
35
+ return [YARNRC_FILENAME];
36
+ }
37
+ getCatalogDefinitions(treeOrRoot) {
38
+ if (typeof treeOrRoot === 'string') {
39
+ const configPath = (0, node_path_1.join)(treeOrRoot, YARNRC_FILENAME);
40
+ if (!(0, node_fs_1.existsSync)(configPath)) {
41
+ return null;
42
+ }
43
+ return readConfigFromFs(configPath);
44
+ }
45
+ else {
46
+ if (!treeOrRoot.exists(YARNRC_FILENAME)) {
47
+ return null;
48
+ }
49
+ return readConfigFromTree(treeOrRoot, YARNRC_FILENAME);
50
+ }
51
+ }
52
+ resolveCatalogReference(treeOrRoot, packageName, version) {
53
+ const catalogRef = this.parseCatalogReference(version);
54
+ if (!catalogRef) {
55
+ return null;
56
+ }
57
+ const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
58
+ if (!catalogDefs) {
59
+ return null;
60
+ }
61
+ let catalogToUse;
62
+ if (catalogRef.isDefaultCatalog) {
63
+ // Check both locations for default catalog
64
+ catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
65
+ }
66
+ else if (catalogRef.catalogName) {
67
+ catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
68
+ }
69
+ return catalogToUse?.[packageName] || null;
70
+ }
71
+ validateCatalogReference(treeOrRoot, packageName, version) {
72
+ const catalogRef = this.parseCatalogReference(version);
73
+ if (!catalogRef) {
74
+ throw new Error(`Invalid catalog reference syntax: "${version}". Expected format: "catalog:" or "catalog:name"`);
75
+ }
76
+ const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
77
+ if (!catalogDefs) {
78
+ throw new Error((0, manager_1.formatCatalogError)(`Cannot get Yarn catalog definitions. No ${YARNRC_FILENAME} found in workspace root.`, [`Create a ${YARNRC_FILENAME} file in your workspace root`]));
79
+ }
80
+ let catalogToUse;
81
+ if (catalogRef.isDefaultCatalog) {
82
+ const hasCatalog = !!catalogDefs.catalog;
83
+ const hasCatalogsDefault = !!catalogDefs.catalogs?.default;
84
+ // Error if both defined
85
+ if (hasCatalog && hasCatalogsDefault) {
86
+ throw new Error("The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.");
87
+ }
88
+ catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
89
+ if (!catalogToUse) {
90
+ const availableCatalogs = Object.keys(catalogDefs.catalogs || {});
91
+ const suggestions = [
92
+ `Define a default catalog in ${YARNRC_FILENAME} under the "catalog" key`,
93
+ ];
94
+ if (availableCatalogs.length > 0) {
95
+ suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
96
+ .map((c) => `"catalog:${c}"`)
97
+ .join(', ')}`);
98
+ }
99
+ throw new Error((0, manager_1.formatCatalogError)(`No default catalog defined in ${YARNRC_FILENAME}`, suggestions));
100
+ }
101
+ }
102
+ else if (catalogRef.catalogName) {
103
+ catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
104
+ if (!catalogToUse) {
105
+ const availableCatalogs = Object.keys(catalogDefs.catalogs || {}).filter((c) => c !== 'default');
106
+ const defaultCatalog = !!catalogDefs.catalog
107
+ ? 'catalog'
108
+ : !catalogDefs.catalogs?.default
109
+ ? 'catalogs.default'
110
+ : null;
111
+ const suggestions = [
112
+ `Define the catalog in ${YARNRC_FILENAME} under the "catalogs" key`,
113
+ ];
114
+ if (availableCatalogs.length > 0) {
115
+ suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
116
+ .map((c) => `"catalog:${c}"`)
117
+ .join(', ')}`);
118
+ }
119
+ if (defaultCatalog) {
120
+ suggestions.push(`Or use the default catalog ("${defaultCatalog}")`);
121
+ }
122
+ throw new Error((0, manager_1.formatCatalogError)(`Catalog "${catalogRef.catalogName}" not found in ${YARNRC_FILENAME}`, suggestions));
123
+ }
124
+ }
125
+ if (!catalogToUse[packageName]) {
126
+ let catalogName;
127
+ if (catalogRef.isDefaultCatalog) {
128
+ // Context-aware messaging based on which location exists
129
+ const hasCatalog = !!catalogDefs.catalog;
130
+ catalogName = hasCatalog
131
+ ? 'default catalog ("catalog")'
132
+ : 'default catalog ("catalogs.default")';
133
+ }
134
+ else {
135
+ catalogName = `catalog '${catalogRef.catalogName}'`;
136
+ }
137
+ const availablePackages = Object.keys(catalogToUse);
138
+ const suggestions = [
139
+ `Add "${packageName}" to ${catalogName} in ${YARNRC_FILENAME}`,
140
+ ];
141
+ if (availablePackages.length > 0) {
142
+ suggestions.push(`Or select from the available packages in ${catalogName}: ${availablePackages
143
+ .map((p) => `"${p}"`)
144
+ .join(', ')}`);
145
+ }
146
+ throw new Error((0, manager_1.formatCatalogError)(`Package "${packageName}" not found in ${catalogName}`, suggestions));
147
+ }
148
+ }
149
+ updateCatalogVersions(treeOrRoot, updates) {
150
+ let checkExists;
151
+ let readYaml;
152
+ let writeYaml;
153
+ if (typeof treeOrRoot === 'string') {
154
+ const configPath = (0, node_path_1.join)(treeOrRoot, YARNRC_FILENAME);
155
+ checkExists = () => (0, node_fs_1.existsSync)(configPath);
156
+ readYaml = () => (0, node_fs_1.readFileSync)(configPath, 'utf-8');
157
+ writeYaml = (content) => (0, node_fs_1.writeFileSync)(configPath, content, 'utf-8');
158
+ }
159
+ else {
160
+ checkExists = () => treeOrRoot.exists(YARNRC_FILENAME);
161
+ readYaml = () => treeOrRoot.read(YARNRC_FILENAME, 'utf-8');
162
+ writeYaml = (content) => treeOrRoot.write(YARNRC_FILENAME, content);
163
+ }
164
+ if (!checkExists()) {
165
+ devkit_exports_1.output.warn({
166
+ title: `No ${YARNRC_FILENAME} found`,
167
+ bodyLines: [
168
+ `Cannot update catalog versions without a ${YARNRC_FILENAME} file.`,
169
+ `Create a ${YARNRC_FILENAME} file to use catalogs.`,
170
+ ],
171
+ });
172
+ return;
173
+ }
174
+ try {
175
+ const configContent = readYaml();
176
+ const configData = (0, js_yaml_1.load)(configContent) || {};
177
+ let hasChanges = false;
178
+ for (const update of updates) {
179
+ const { packageName, version, catalogName } = update;
180
+ const normalizedCatalogName = catalogName === 'default' ? undefined : catalogName;
181
+ let targetCatalog;
182
+ if (!normalizedCatalogName) {
183
+ // Default catalog - update whichever exists, prefer catalog over catalogs.default
184
+ if (configData.catalog) {
185
+ targetCatalog = configData.catalog;
186
+ }
187
+ else if (configData.catalogs?.default) {
188
+ targetCatalog = configData.catalogs.default;
189
+ }
190
+ else {
191
+ // Neither exists, create catalog (shorthand syntax)
192
+ configData.catalog ??= {};
193
+ targetCatalog = configData.catalog;
194
+ }
195
+ }
196
+ else {
197
+ // Named catalog
198
+ configData.catalogs ??= {};
199
+ configData.catalogs[normalizedCatalogName] ??= {};
200
+ targetCatalog = configData.catalogs[normalizedCatalogName];
201
+ }
202
+ if (targetCatalog[packageName] !== version) {
203
+ targetCatalog[packageName] = version;
204
+ hasChanges = true;
205
+ }
206
+ }
207
+ if (hasChanges) {
208
+ writeYaml((0, js_yaml_1.dump)(configData, {
209
+ indent: 2,
210
+ quotingType: '"',
211
+ forceQuotes: true,
212
+ }));
213
+ }
214
+ }
215
+ catch (error) {
216
+ devkit_exports_1.output.error({
217
+ title: 'Failed to update catalog versions',
218
+ bodyLines: [error instanceof Error ? error.message : String(error)],
219
+ });
220
+ throw error;
221
+ }
222
+ }
223
+ }
224
+ exports.YarnCatalogManager = YarnCatalogManager;
225
+ function readConfigFromFs(path) {
226
+ try {
227
+ return (0, devkit_internals_1.readYamlFile)(path);
228
+ }
229
+ catch (error) {
230
+ devkit_exports_1.output.warn({
231
+ title: `Unable to parse ${YARNRC_FILENAME}`,
232
+ bodyLines: [error.toString()],
233
+ });
234
+ return null;
235
+ }
236
+ }
237
+ function readConfigFromTree(tree, path) {
238
+ const content = tree.read(path, 'utf-8');
239
+ try {
240
+ return (0, js_yaml_1.load)(content, { filename: path });
241
+ }
242
+ catch (error) {
243
+ devkit_exports_1.output.warn({
244
+ title: `Unable to parse ${YARNRC_FILENAME}`,
245
+ bodyLines: [error.toString()],
246
+ });
247
+ return null;
248
+ }
249
+ }