🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@nx/devkit

Package Overview
Dependencies
Maintainers
5
Versions
1866
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nx/devkit - npm Package Compare versions

Comparing version
23.1.0
to
23.2.0-beta.0
+2
-2
dist/internal.d.ts

@@ -1,2 +0,2 @@

export { signalToCode, createProjectRootMappingsFromProjectConfigurations, PluginCache, safeWriteFileCache, emitPluginWorkerLog, resolveImplementation, resolveSchema, ImplementationResolutionError, SchemaResolutionError, resolvePrompt, PromptResolutionError, } from 'nx/src/devkit-internals';
export { signalToCode, createProjectRootMappingsFromProjectConfigurations, PluginCache, safeWriteFileCache, emitPluginWorkerLog, resolveImplementation, resolveSchema, ImplementationResolutionError, SchemaResolutionError, resolvePrompt, PromptResolutionError, acknowledgeBuildScripts, } from 'nx/src/devkit-internals';
export { determineArtifactNameAndDirectoryOptions, getRelativeCwd, type FileExtensionType, } from './src/generators/artifact-name-and-directory-utils';

@@ -16,3 +16,3 @@ export { getE2EWebServerInfo, type E2EWebServerDetails, } from './src/generators/e2e-web-server-info-utils';

export { calculateHashForCreateNodes, calculateHashesForCreateNodes, } from './src/utils/calculate-hash-for-create-nodes';
export { getCatalogManager } from './src/utils/catalog';
export { getCatalogManager } from 'nx/src/utils/catalog';
export { loadConfigFile, clearRequireCache } from './src/utils/config-utils';

@@ -19,0 +19,0 @@ export { findPluginForConfigFile } from './src/utils/find-plugin-for-config-file';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkAndCleanWithSemver = exports.eachValueFrom = exports.logShowProjectCommand = exports.getNamedInputs = exports.findPluginForConfigFile = exports.clearRequireCache = exports.loadConfigFile = exports.getCatalogManager = exports.calculateHashesForCreateNodes = exports.calculateHashForCreateNodes = exports.mapAsyncIterable = exports.combineAsyncIterables = exports.createAsyncIterable = exports.assertSupportedPackageVersion = exports.assertSupportedInstalledPackageVersion = exports.getInstalledPackageVersion = exports.getDeclaredPackageVersion = exports.addPlugin = exports.upsertTargetDefault = exports.updateTargetDefault = exports.readTargetDefaultsForTarget = exports.findTargetDefault = exports.addE2eCiTargetDefaults = exports.addBuildTargetDefaults = exports.promptWhenInteractive = exports.resolveImportPath = exports.ensureRootProjectName = exports.determineProjectNameAndRootOptions = exports.toProjectRelativePath = exports.deleteMatchingProperties = exports.processTargetOutputs = exports.NoTargetsToMigrateError = exports.migrateProjectExecutorsToPluginV1 = exports.migrateProjectExecutorsToPlugin = exports.AggregatedLog = exports.forEachExecutorOptions = exports.getE2EWebServerInfo = exports.getRelativeCwd = exports.determineArtifactNameAndDirectoryOptions = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.createProjectRootMappingsFromProjectConfigurations = exports.signalToCode = void 0;
exports.dasherize = exports.classify = exports.capitalize = exports.camelize = void 0;
exports.eachValueFrom = exports.logShowProjectCommand = exports.getNamedInputs = exports.findPluginForConfigFile = exports.clearRequireCache = exports.loadConfigFile = exports.getCatalogManager = exports.calculateHashesForCreateNodes = exports.calculateHashForCreateNodes = exports.mapAsyncIterable = exports.combineAsyncIterables = exports.createAsyncIterable = exports.assertSupportedPackageVersion = exports.assertSupportedInstalledPackageVersion = exports.getInstalledPackageVersion = exports.getDeclaredPackageVersion = exports.addPlugin = exports.upsertTargetDefault = exports.updateTargetDefault = exports.readTargetDefaultsForTarget = exports.findTargetDefault = exports.addE2eCiTargetDefaults = exports.addBuildTargetDefaults = exports.promptWhenInteractive = exports.resolveImportPath = exports.ensureRootProjectName = exports.determineProjectNameAndRootOptions = exports.toProjectRelativePath = exports.deleteMatchingProperties = exports.processTargetOutputs = exports.NoTargetsToMigrateError = exports.migrateProjectExecutorsToPluginV1 = exports.migrateProjectExecutorsToPlugin = exports.AggregatedLog = exports.forEachExecutorOptions = exports.getE2EWebServerInfo = exports.getRelativeCwd = exports.determineArtifactNameAndDirectoryOptions = exports.acknowledgeBuildScripts = exports.PromptResolutionError = exports.resolvePrompt = exports.SchemaResolutionError = exports.ImplementationResolutionError = exports.resolveSchema = exports.resolveImplementation = exports.emitPluginWorkerLog = exports.safeWriteFileCache = exports.PluginCache = exports.createProjectRootMappingsFromProjectConfigurations = exports.signalToCode = void 0;
exports.dasherize = exports.classify = exports.capitalize = exports.camelize = exports.checkAndCleanWithSemver = void 0;
var devkit_internals_1 = require("nx/src/devkit-internals");

@@ -17,2 +17,3 @@ Object.defineProperty(exports, "signalToCode", { enumerable: true, get: function () { return devkit_internals_1.signalToCode; } });

Object.defineProperty(exports, "PromptResolutionError", { enumerable: true, get: function () { return devkit_internals_1.PromptResolutionError; } });
Object.defineProperty(exports, "acknowledgeBuildScripts", { enumerable: true, get: function () { return devkit_internals_1.acknowledgeBuildScripts; } });
// Generators

@@ -65,3 +66,4 @@ var artifact_name_and_directory_utils_1 = require("./src/generators/artifact-name-and-directory-utils");

Object.defineProperty(exports, "calculateHashesForCreateNodes", { enumerable: true, get: function () { return calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes; } });
var catalog_1 = require("./src/utils/catalog");
// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- nx/src/utils/catalog exists since nx 22.0.0, the whole supported range; swap to the nx/src/devkit-internals re-export in v25
var catalog_1 = require("nx/src/utils/catalog");
Object.defineProperty(exports, "getCatalogManager", { enumerable: true, get: function () { return catalog_1.getCatalogManager; } });

@@ -68,0 +70,0 @@ var config_utils_1 = require("./src/utils/config-utils");

@@ -15,3 +15,4 @@ "use strict";

const install_packages_task_1 = require("../tasks/install-packages-task");
const catalog_1 = require("./catalog");
// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- nx/src/utils/catalog exists since nx 22.0.0, the whole supported range; swap to the nx/src/devkit-internals re-export in v25
const catalog_1 = require("nx/src/utils/catalog");
const UNIDENTIFIED_VERSION = 'UNIDENTIFIED_VERSION';

@@ -18,0 +19,0 @@ const NON_SEMVER_TAGS = {

@@ -6,3 +6,4 @@ "use strict";

const semver_1 = require("semver");
const catalog_1 = require("./catalog");
// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- nx/src/utils/catalog exists since nx 22.0.0, the whole supported range; swap to the nx/src/devkit-internals re-export in v25
const catalog_1 = require("nx/src/utils/catalog");
function checkAndCleanWithSemver(treeOrPkgName, pkgNameOrVersion, version) {

@@ -9,0 +10,0 @@ const tree = typeof treeOrPkgName === 'string' ? undefined : treeOrPkgName;

{
"name": "@nx/devkit",
"version": "23.1.0",
"version": "23.2.0-beta.0",
"private": false,

@@ -53,3 +53,2 @@ "type": "commonjs",

"dependencies": {
"@zkochan/js-yaml": "0.0.7",
"ejs": "5.0.1",

@@ -60,8 +59,7 @@ "tslib": "^2.3.0",

"minimatch": "10.2.5",
"enquirer": "~2.3.6",
"yaml": "^2.8.3"
"enquirer": "~2.3.6"
},
"devDependencies": {
"jest": "30.3.0",
"nx": "23.1.0"
"nx": "23.2.0-beta.0"
},

@@ -68,0 +66,0 @@ "peerDependencies": {

import { type Tree } from 'nx/src/devkit-exports';
import { getCatalogManager } from './manager-factory';
import type { CatalogManager } from './manager';
export { type CatalogManager, getCatalogManager };
/**
* Detects which packages in a package.json use catalog references
* Returns Map of package name -> catalog name (undefined for default catalog)
*/
export declare function getCatalogDependenciesFromPackageJson(tree: Tree, packageJsonPath: string, manager: CatalogManager): Map<string, string | undefined>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCatalogManager = void 0;
exports.getCatalogDependenciesFromPackageJson = getCatalogDependenciesFromPackageJson;
const devkit_exports_1 = require("nx/src/devkit-exports");
const manager_factory_1 = require("./manager-factory");
Object.defineProperty(exports, "getCatalogManager", { enumerable: true, get: function () { return manager_factory_1.getCatalogManager; } });
/**
* Detects which packages in a package.json use catalog references
* Returns Map of package name -> catalog name (undefined for default catalog)
*/
function getCatalogDependenciesFromPackageJson(tree, packageJsonPath, manager) {
const catalogDeps = new Map();
if (!tree.exists(packageJsonPath)) {
return catalogDeps;
}
try {
const packageJson = (0, devkit_exports_1.readJson)(tree, packageJsonPath);
const allDependencies = {
...packageJson.dependencies,
...packageJson.devDependencies,
...packageJson.peerDependencies,
...packageJson.optionalDependencies,
};
for (const [packageName, version] of Object.entries(allDependencies || {})) {
if (manager.isCatalogReference(version)) {
const catalogRef = manager.parseCatalogReference(version);
if (catalogRef) {
catalogDeps.set(packageName, catalogRef.catalogName);
}
}
}
}
catch (error) {
// If we can't read the package.json, return empty map
}
return catalogDeps;
}
import type { CatalogManager } from './manager';
/**
* Factory function to get the appropriate catalog manager based on the package manager
*/
export declare function getCatalogManager(workspaceRoot: string): CatalogManager | null;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCatalogManager = getCatalogManager;
const devkit_exports_1 = require("nx/src/devkit-exports");
const pnpm_manager_1 = require("./pnpm-manager");
const yarn_manager_1 = require("./yarn-manager");
/**
* Factory function to get the appropriate catalog manager based on the package manager
*/
function getCatalogManager(workspaceRoot) {
const packageManager = (0, devkit_exports_1.detectPackageManager)(workspaceRoot);
switch (packageManager) {
case 'pnpm':
return new pnpm_manager_1.PnpmCatalogManager();
case 'yarn':
return new yarn_manager_1.YarnCatalogManager();
default:
return null;
}
}
import { type Tree } from 'nx/src/devkit-exports';
import type { CatalogDefinitions } from './types';
export declare function readCatalogConfigFromFs(filename: string, fullPath: string): CatalogDefinitions | null;
export declare function readCatalogConfigFromTree(filename: string, tree: Tree): CatalogDefinitions | null;
export declare function updateCatalogVersionsInFile(filename: string, treeOrRoot: Tree | string, updates: Array<{
packageName: string;
version: string;
catalogName?: string;
}>): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readCatalogConfigFromFs = readCatalogConfigFromFs;
exports.readCatalogConfigFromTree = readCatalogConfigFromTree;
exports.updateCatalogVersionsInFile = updateCatalogVersionsInFile;
// Keep in sync with packages/nx/src/utils/catalog/manager-utils.ts; the body below
// the imports is duplicated because @nx/devkit supports a range of nx majors and
// this logic isn't part of the nx surface it can import across that range.
const js_yaml_1 = require("@zkochan/js-yaml");
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const devkit_exports_1 = require("nx/src/devkit-exports");
const devkit_internals_1 = require("nx/src/devkit-internals");
const yaml_1 = require("yaml");
// Walks `path` resolving aliases at every step so structural checks can
// see through `key: *anchor` references. Neither `doc.getIn` nor
// `doc.hasIn` traverse aliases on their own. Returns the resolved node, or
// `undefined` if any ancestor isn't a map.
function resolveAt(doc, path) {
let node = doc.contents;
for (let i = 0; i < path.length; i++) {
if ((0, yaml_1.isAlias)(node))
node = node.resolve(doc);
if (!(0, yaml_1.isMap)(node))
return undefined;
node = node.get(path[i], true);
}
if ((0, yaml_1.isAlias)(node))
node = node.resolve(doc);
return node;
}
function isMapAt(doc, path) {
return (0, yaml_1.isMap)(resolveAt(doc, path));
}
function existsAt(doc, path) {
return resolveAt(doc, path) !== undefined;
}
// `doc.getIn` does not traverse aliases. For aliased paths it returns
// undefined even when the resolved node has a value. Use the alias-aware
// walk and unwrap scalar nodes to their JS value.
function getValueAt(doc, path) {
const node = resolveAt(doc, path);
return (0, yaml_1.isScalar)(node) ? node.value : node;
}
// Walks `targetPath` resolving aliases at every step and mutates the
// resolved map directly so anchors are preserved. When a step is missing
// or holds a null placeholder (`key:` with no value), creates a fresh map
// inside the current parent and carries over the placeholder's comments
// and anchor so they aren't dropped. A dropped anchor would leave any
// alias referencing it unresolved and make `String(doc)` throw. Falls back
// to `doc.setIn` when the current parent isn't a map: an empty-document
// root gets bootstrapped, while a non-map value where a catalog map was
// expected makes `setIn` throw, surfacing the malformed config.
function setThroughAliases(doc, targetPath, value) {
let parent = doc.contents;
if ((0, yaml_1.isAlias)(parent))
parent = parent.resolve(doc);
for (let i = 0; i < targetPath.length - 1; i++) {
if (!(0, yaml_1.isMap)(parent)) {
doc.setIn(targetPath, value);
return;
}
let next = parent.get(targetPath[i], true);
const nextWasAlias = (0, yaml_1.isAlias)(next);
if ((0, yaml_1.isAlias)(next))
next = next.resolve(doc);
const placeholder = (0, yaml_1.isScalar)(next) && next.value === null ? next : undefined;
if (next === undefined || placeholder) {
let cur = parent;
for (let j = i; j < targetPath.length - 1; j++) {
const fresh = new yaml_1.YAMLMap();
if (j === i && placeholder) {
if (placeholder.comment)
fresh.comment = placeholder.comment;
if (placeholder.commentBefore)
fresh.commentBefore = placeholder.commentBefore;
// Copy the anchor only for a directly-held placeholder. When it
// was reached through an alias, the anchor still lives on the
// definition node, so re-emitting it here would duplicate it.
if (!nextWasAlias && placeholder.anchor)
fresh.anchor = placeholder.anchor;
}
cur.set(targetPath[j], fresh);
cur = fresh;
}
cur.set(targetPath[targetPath.length - 1], value);
return;
}
parent = next;
}
if (!(0, yaml_1.isMap)(parent)) {
doc.setIn(targetPath, value);
return;
}
parent.set(targetPath[targetPath.length - 1], value);
}
function readCatalogConfigFromFs(filename, fullPath) {
try {
return (0, devkit_internals_1.readYamlFile)(fullPath);
}
catch (error) {
devkit_exports_1.output.warn({
title: `Unable to parse ${filename}`,
bodyLines: [error.toString()],
});
return null;
}
}
function readCatalogConfigFromTree(filename, tree) {
const content = tree.read(filename, 'utf-8');
try {
return (0, js_yaml_1.load)(content, { filename });
}
catch (error) {
devkit_exports_1.output.warn({
title: `Unable to parse ${filename}`,
bodyLines: [error.toString()],
});
return null;
}
}
function updateCatalogVersionsInFile(filename, treeOrRoot, updates) {
let checkExists;
let readYaml;
let writeYaml;
if (typeof treeOrRoot === 'string') {
const configPath = (0, node_path_1.join)(treeOrRoot, filename);
checkExists = () => (0, node_fs_1.existsSync)(configPath);
readYaml = () => (0, node_fs_1.readFileSync)(configPath, 'utf-8');
writeYaml = (content) => (0, node_fs_1.writeFileSync)(configPath, content, 'utf-8');
}
else {
checkExists = () => treeOrRoot.exists(filename);
readYaml = () => treeOrRoot.read(filename, 'utf-8');
writeYaml = (content) => treeOrRoot.write(filename, content);
}
if (!checkExists()) {
devkit_exports_1.output.warn({
title: `No ${filename} found`,
bodyLines: [
`Cannot update catalog versions without a ${filename} file.`,
`Create a ${filename} file to use catalogs.`,
],
});
return;
}
try {
// parseDocument keeps comments and anchors so a catalog bump doesn't
// rewrite the user's config file.
const lineCounter = new yaml_1.LineCounter();
const doc = (0, yaml_1.parseDocument)(readYaml(), { lineCounter });
// parseDocument collects syntax errors instead of throwing; surface them
// now, with their line/column detail, rather than failing later in
// `String(doc)` with a generic message or skipping a no-op write on a
// malformed file (the previous js-yaml `load()` threw here).
if (doc.errors.length > 0) {
throw new Error(doc.errors.map((e) => e.message).join('\n'));
}
// A dangling alias (`*ref` with no matching `&ref`) is not a syntax error,
// so parseDocument leaves it out of doc.errors. Surface it here with the
// same line/column detail the old js-yaml `load()` reported; otherwise a
// broken reference is silently overwritten or written back untouched.
const unresolvedAliases = [];
(0, yaml_1.visit)(doc, {
Alias(_key, node) {
if (node.resolve(doc) !== undefined)
return;
const pos = node.range ? lineCounter.linePos(node.range[0]) : undefined;
unresolvedAliases.push(pos
? `Unresolved alias "${node.source}" at line ${pos.line}, column ${pos.col}`
: `Unresolved alias "${node.source}"`);
},
});
if (unresolvedAliases.length > 0) {
throw new Error(unresolvedAliases.join('\n'));
}
let hasChanges = false;
for (const update of updates) {
const { packageName, version, catalogName } = update;
const normalizedCatalogName = catalogName === 'default' ? undefined : catalogName;
let targetPath;
if (!normalizedCatalogName) {
// An empty `catalog:` placeholder must not claim the default route
// when `catalogs.default` is populated; that would create a
// duplicate-default config rejected by pnpm.
if (isMapAt(doc, ['catalog'])) {
targetPath = ['catalog', packageName];
}
else if (existsAt(doc, ['catalogs', 'default'])) {
targetPath = ['catalogs', 'default', packageName];
}
else {
targetPath = ['catalog', packageName];
}
}
else {
targetPath = ['catalogs', normalizedCatalogName, packageName];
}
if (getValueAt(doc, targetPath) !== version) {
setThroughAliases(doc, targetPath, version);
hasChanges = true;
}
}
if (hasChanges) {
writeYaml(String(doc));
}
}
catch (error) {
devkit_exports_1.output.error({
title: 'Failed to update catalog versions',
bodyLines: [error instanceof Error ? error.message : String(error)],
});
throw error;
}
}
import type { Tree } from 'nx/src/devkit-exports';
import type { CatalogDefinitions, CatalogReference } from './types';
export declare function formatCatalogError(error: string, suggestions: string[]): string;
/**
* Interface for catalog managers that handle package manager-specific catalog implementations.
*/
export interface CatalogManager {
readonly name: string;
isCatalogReference(version: string): boolean;
parseCatalogReference(version: string): CatalogReference | null;
getCatalogDefinitionFilePaths(): string[];
/**
* Get catalog definitions from the workspace.
*/
getCatalogDefinitions(workspaceRoot: string): CatalogDefinitions | null;
getCatalogDefinitions(tree: Tree): CatalogDefinitions | null;
/**
* Resolve a catalog reference to an actual version.
*/
resolveCatalogReference(workspaceRoot: string, packageName: string, version: string): string | null;
resolveCatalogReference(tree: Tree, packageName: string, version: string): string | null;
/**
* Check that a catalog reference is valid.
*/
validateCatalogReference(workspaceRoot: string, packageName: string, version: string): void;
validateCatalogReference(tree: Tree, packageName: string, version: string): void;
/**
* Updates catalog definitions for specified packages in their respective catalogs.
*/
updateCatalogVersions(tree: Tree, updates: Array<{
packageName: string;
version: string;
catalogName?: string;
}>): void;
updateCatalogVersions(workspaceRoot: string, updates: Array<{
packageName: string;
version: string;
catalogName?: string;
}>): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatCatalogError = formatCatalogError;
function formatCatalogError(error, suggestions) {
let message = error;
if (suggestions.length > 0) {
message += '\n\nSuggestions:';
suggestions.forEach((suggestion) => {
message += `\n • ${suggestion}`;
});
}
return message;
}
import { type Tree } from 'nx/src/devkit-exports';
import { type CatalogManager } from './manager';
import type { CatalogDefinitions, CatalogReference } from './types';
/**
* PNPM-specific catalog manager implementation
*/
export declare class PnpmCatalogManager implements CatalogManager {
readonly name = "pnpm";
readonly catalogProtocol = "catalog:";
isCatalogReference(version: string): boolean;
parseCatalogReference(version: string): CatalogReference | null;
getCatalogDefinitionFilePaths(): string[];
getCatalogDefinitions(treeOrRoot: Tree | string): CatalogDefinitions | null;
resolveCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): string | null;
validateCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): void;
updateCatalogVersions(treeOrRoot: Tree | string, updates: Array<{
packageName: string;
version: string;
catalogName?: string;
}>): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PnpmCatalogManager = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const manager_1 = require("./manager");
const manager_utils_1 = require("./manager-utils");
const PNPM_WORKSPACE_FILENAME = 'pnpm-workspace.yaml';
/**
* PNPM-specific catalog manager implementation
*/
class PnpmCatalogManager {
constructor() {
this.name = 'pnpm';
this.catalogProtocol = 'catalog:';
}
isCatalogReference(version) {
return version.startsWith(this.catalogProtocol);
}
parseCatalogReference(version) {
if (!this.isCatalogReference(version)) {
return null;
}
const catalogName = version.substring(this.catalogProtocol.length);
// Normalize both "catalog:" and "catalog:default" to the same representation
const isDefault = !catalogName || catalogName === 'default';
return {
catalogName: isDefault ? undefined : catalogName,
isDefaultCatalog: isDefault,
};
}
getCatalogDefinitionFilePaths() {
return [PNPM_WORKSPACE_FILENAME];
}
getCatalogDefinitions(treeOrRoot) {
if (typeof treeOrRoot === 'string') {
const configPath = (0, node_path_1.join)(treeOrRoot, PNPM_WORKSPACE_FILENAME);
if (!(0, node_fs_1.existsSync)(configPath)) {
return null;
}
return (0, manager_utils_1.readCatalogConfigFromFs)(PNPM_WORKSPACE_FILENAME, configPath);
}
else {
if (!treeOrRoot.exists(PNPM_WORKSPACE_FILENAME)) {
return null;
}
return (0, manager_utils_1.readCatalogConfigFromTree)(PNPM_WORKSPACE_FILENAME, treeOrRoot);
}
}
resolveCatalogReference(treeOrRoot, packageName, version) {
const catalogRef = this.parseCatalogReference(version);
if (!catalogRef) {
return null;
}
const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
if (!catalogDefs) {
return null;
}
let catalogToUse;
if (catalogRef.isDefaultCatalog) {
// Check both locations for default catalog
catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
}
else if (catalogRef.catalogName) {
catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
}
return catalogToUse?.[packageName] || null;
}
validateCatalogReference(treeOrRoot, packageName, version) {
const catalogRef = this.parseCatalogReference(version);
if (!catalogRef) {
throw new Error(`Invalid catalog reference syntax: "${version}". Expected format: "catalog:" or "catalog:name"`);
}
const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
if (!catalogDefs) {
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`]));
}
let catalogToUse;
if (catalogRef.isDefaultCatalog) {
const hasCatalog = !!catalogDefs.catalog;
const hasCatalogsDefault = !!catalogDefs.catalogs?.default;
// Error if both defined (matches pnpm behavior)
if (hasCatalog && hasCatalogsDefault) {
throw new Error("The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.");
}
catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
if (!catalogToUse) {
const availableCatalogs = Object.keys(catalogDefs.catalogs || {});
const suggestions = [
`Define a default catalog in ${PNPM_WORKSPACE_FILENAME} under the "catalog" key`,
];
if (availableCatalogs.length > 0) {
suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
.map((c) => `"catalog:${c}"`)
.join(', ')}`);
}
throw new Error((0, manager_1.formatCatalogError)(`No default catalog defined in ${PNPM_WORKSPACE_FILENAME}`, suggestions));
}
}
else if (catalogRef.catalogName) {
catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
if (!catalogToUse) {
const availableCatalogs = Object.keys(catalogDefs.catalogs || {}).filter((c) => c !== 'default');
const defaultCatalog = !!catalogDefs.catalog
? 'catalog'
: !catalogDefs.catalogs?.default
? 'catalogs.default'
: null;
const suggestions = [
`Define the catalog in ${PNPM_WORKSPACE_FILENAME} under the "catalogs" key`,
];
if (availableCatalogs.length > 0) {
suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
.map((c) => `"catalog:${c}"`)
.join(', ')}`);
}
if (defaultCatalog) {
suggestions.push(`Or use the default catalog ("${defaultCatalog}")`);
}
throw new Error((0, manager_1.formatCatalogError)(`Catalog "${catalogRef.catalogName}" not found in ${PNPM_WORKSPACE_FILENAME}`, suggestions));
}
}
if (!catalogToUse[packageName]) {
let catalogName;
if (catalogRef.isDefaultCatalog) {
// Context-aware messaging based on which location exists
const hasCatalog = !!catalogDefs.catalog;
catalogName = hasCatalog
? 'default catalog ("catalog")'
: 'default catalog ("catalogs.default")';
}
else {
catalogName = `catalog '${catalogRef.catalogName}'`;
}
const availablePackages = Object.keys(catalogToUse);
const suggestions = [
`Add "${packageName}" to ${catalogName} in ${PNPM_WORKSPACE_FILENAME}`,
];
if (availablePackages.length > 0) {
suggestions.push(`Or select from the available packages in ${catalogName}: ${availablePackages
.map((p) => `"${p}"`)
.join(', ')}`);
}
throw new Error((0, manager_1.formatCatalogError)(`Package "${packageName}" not found in ${catalogName}`, suggestions));
}
}
updateCatalogVersions(treeOrRoot, updates) {
(0, manager_utils_1.updateCatalogVersionsInFile)(PNPM_WORKSPACE_FILENAME, treeOrRoot, updates);
}
}
exports.PnpmCatalogManager = PnpmCatalogManager;
export interface CatalogReference {
catalogName?: string;
isDefaultCatalog: boolean;
}
export interface CatalogEntry {
[packageName: string]: string;
}
export interface CatalogDefinitions {
catalog?: CatalogEntry;
catalogs?: Record<string, CatalogEntry>;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
import { type Tree } from 'nx/src/devkit-exports';
import { type CatalogManager } from './manager';
import type { CatalogDefinitions, CatalogReference } from './types';
/**
* Yarn Berry (v4+) catalog manager implementation
*/
export declare class YarnCatalogManager implements CatalogManager {
readonly name = "yarn";
readonly catalogProtocol = "catalog:";
isCatalogReference(version: string): boolean;
parseCatalogReference(version: string): CatalogReference | null;
getCatalogDefinitionFilePaths(): string[];
getCatalogDefinitions(treeOrRoot: Tree | string): CatalogDefinitions | null;
resolveCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): string | null;
validateCatalogReference(treeOrRoot: Tree | string, packageName: string, version: string): void;
updateCatalogVersions(treeOrRoot: Tree | string, updates: Array<{
packageName: string;
version: string;
catalogName?: string;
}>): void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.YarnCatalogManager = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const manager_1 = require("./manager");
const manager_utils_1 = require("./manager-utils");
const YARNRC_FILENAME = '.yarnrc.yml';
/**
* Yarn Berry (v4+) catalog manager implementation
*/
class YarnCatalogManager {
constructor() {
this.name = 'yarn';
this.catalogProtocol = 'catalog:';
}
isCatalogReference(version) {
return version.startsWith(this.catalogProtocol);
}
parseCatalogReference(version) {
if (!this.isCatalogReference(version)) {
return null;
}
const catalogName = version.substring(this.catalogProtocol.length);
// Normalize both "catalog:" and "catalog:default" to the same representation
const isDefault = !catalogName || catalogName === 'default';
return {
catalogName: isDefault ? undefined : catalogName,
isDefaultCatalog: isDefault,
};
}
getCatalogDefinitionFilePaths() {
return [YARNRC_FILENAME];
}
getCatalogDefinitions(treeOrRoot) {
if (typeof treeOrRoot === 'string') {
const configPath = (0, node_path_1.join)(treeOrRoot, YARNRC_FILENAME);
if (!(0, node_fs_1.existsSync)(configPath)) {
return null;
}
return (0, manager_utils_1.readCatalogConfigFromFs)(YARNRC_FILENAME, configPath);
}
else {
if (!treeOrRoot.exists(YARNRC_FILENAME)) {
return null;
}
return (0, manager_utils_1.readCatalogConfigFromTree)(YARNRC_FILENAME, treeOrRoot);
}
}
resolveCatalogReference(treeOrRoot, packageName, version) {
const catalogRef = this.parseCatalogReference(version);
if (!catalogRef) {
return null;
}
const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
if (!catalogDefs) {
return null;
}
let catalogToUse;
if (catalogRef.isDefaultCatalog) {
// Check both locations for default catalog
catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
}
else if (catalogRef.catalogName) {
catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
}
return catalogToUse?.[packageName] || null;
}
validateCatalogReference(treeOrRoot, packageName, version) {
const catalogRef = this.parseCatalogReference(version);
if (!catalogRef) {
throw new Error(`Invalid catalog reference syntax: "${version}". Expected format: "catalog:" or "catalog:name"`);
}
const catalogDefs = this.getCatalogDefinitions(treeOrRoot);
if (!catalogDefs) {
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`]));
}
let catalogToUse;
if (catalogRef.isDefaultCatalog) {
const hasCatalog = !!catalogDefs.catalog;
const hasCatalogsDefault = !!catalogDefs.catalogs?.default;
// Error if both defined
if (hasCatalog && hasCatalogsDefault) {
throw new Error("The 'default' catalog was defined multiple times. Use the 'catalog' field or 'catalogs.default', but not both.");
}
catalogToUse = catalogDefs.catalog ?? catalogDefs.catalogs?.default;
if (!catalogToUse) {
const availableCatalogs = Object.keys(catalogDefs.catalogs || {});
const suggestions = [
`Define a default catalog in ${YARNRC_FILENAME} under the "catalog" key`,
];
if (availableCatalogs.length > 0) {
suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
.map((c) => `"catalog:${c}"`)
.join(', ')}`);
}
throw new Error((0, manager_1.formatCatalogError)(`No default catalog defined in ${YARNRC_FILENAME}`, suggestions));
}
}
else if (catalogRef.catalogName) {
catalogToUse = catalogDefs.catalogs?.[catalogRef.catalogName];
if (!catalogToUse) {
const availableCatalogs = Object.keys(catalogDefs.catalogs || {}).filter((c) => c !== 'default');
const defaultCatalog = !!catalogDefs.catalog
? 'catalog'
: !catalogDefs.catalogs?.default
? 'catalogs.default'
: null;
const suggestions = [
`Define the catalog in ${YARNRC_FILENAME} under the "catalogs" key`,
];
if (availableCatalogs.length > 0) {
suggestions.push(`Or select from the available named catalogs: ${availableCatalogs
.map((c) => `"catalog:${c}"`)
.join(', ')}`);
}
if (defaultCatalog) {
suggestions.push(`Or use the default catalog ("${defaultCatalog}")`);
}
throw new Error((0, manager_1.formatCatalogError)(`Catalog "${catalogRef.catalogName}" not found in ${YARNRC_FILENAME}`, suggestions));
}
}
if (!catalogToUse[packageName]) {
let catalogName;
if (catalogRef.isDefaultCatalog) {
// Context-aware messaging based on which location exists
const hasCatalog = !!catalogDefs.catalog;
catalogName = hasCatalog
? 'default catalog ("catalog")'
: 'default catalog ("catalogs.default")';
}
else {
catalogName = `catalog '${catalogRef.catalogName}'`;
}
const availablePackages = Object.keys(catalogToUse);
const suggestions = [
`Add "${packageName}" to ${catalogName} in ${YARNRC_FILENAME}`,
];
if (availablePackages.length > 0) {
suggestions.push(`Or select from the available packages in ${catalogName}: ${availablePackages
.map((p) => `"${p}"`)
.join(', ')}`);
}
throw new Error((0, manager_1.formatCatalogError)(`Package "${packageName}" not found in ${catalogName}`, suggestions));
}
}
updateCatalogVersions(treeOrRoot, updates) {
(0, manager_utils_1.updateCatalogVersionsInFile)(YARNRC_FILENAME, treeOrRoot, updates);
}
}
exports.YarnCatalogManager = YarnCatalogManager;