@nx/devkit
Advanced tools
@@ -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'; |
+5
-3
| "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; |
+3
-5
| { | ||
| "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; |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
7
-22.22%27
-10%298178
-9.26%114
-10.94%6767
-9.4%2
100%- Removed
- Removed