@nx/devkit
Version:
152 lines (151 loc) • 6.86 kB
JavaScript
;
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;