UNPKG

@o3r/eslint-plugin

Version:

The module provides in-house eslint plugins to use in your own eslint configuration.

128 lines (127 loc) 6.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("node:path"); const semver = require("semver"); const version_harmonize_1 = require("../../json/json-dependency-versions-harmonize/version-harmonize"); const utils_1 = require("../../utils"); const utils_2 = require("../utils"); const isYAMLScalar = (node) => node?.type === 'YAMLScalar'; const getStaticYAMLValue = (node) => { return isYAMLScalar(node) ? node.value?.toString() : undefined; }; const defaultOptions = [{ ignoredDependencies: [], excludePackages: [], yarnrcDependencyTypes: ['peerDependencies', 'dependencies'], dependencyTypesInPackages: ['optionalDependencies', 'dependencies', 'devDependencies', 'peerDependencies', 'generatorDependencies'] }]; exports.default = (0, utils_1.createRule)({ name: 'yarnrc-package-extensions-harmonize', meta: { hasSuggestions: true, type: 'problem', docs: { description: 'Ensure that the package extension versions are aligned with the range defined in the packages.' }, schema: [ { type: 'object', properties: { excludePackages: { type: 'array', description: 'List of package.json to ignore when determining the dependencies versions', items: { type: 'string' } }, yarnrcDependencyTypes: { type: 'array', description: 'List of dependency types to validate in .yarnrc.yml', default: defaultOptions[0].yarnrcDependencyTypes, items: { type: 'string' } }, dependencyTypesInPackages: { type: 'array', description: 'List of dependency types in package.json to parse', default: defaultOptions[0].dependencyTypesInPackages, items: { type: 'string' } }, ignoredDependencies: { type: 'array', description: 'List of dependencies to ignore', items: { type: 'string' } } }, additionalProperties: false } ], messages: { versionUpdate: 'Set version {{version}}', error: '{{depName}} should be updated to version {{version}} (from: {{packageJsonFile}})' }, fixable: 'code' }, defaultOptions, create: (context, [options]) => { const parserServices = (0, utils_2.getYamlParserServices)(context); const dirname = path.dirname(context.filename); const workspace = (0, version_harmonize_1.findWorkspacePackageJsons)(dirname); const bestRanges = workspace ? (0, version_harmonize_1.getBestRanges)(options.dependencyTypesInPackages, workspace.packages.filter(({ content }) => !content.name || !options.excludePackages.includes(content.name))) : {}; const ignoredDependencies = options.ignoredDependencies.map((dep) => new RegExp(dep.replace(/[$()+.?[\\\]^{|}]/g, '\\$&').replace(/\*/g, '.*'))); if (parserServices.isYAML) { return { // eslint-disable-next-line @typescript-eslint/naming-convention -- name required by Yaml Eslint parser YAMLPair: (node) => { if (node.value) { const range = getStaticYAMLValue(node.value)?.toString(); const parent = node.parent.parent && node.parent.parent.type === 'YAMLPair' && getStaticYAMLValue(node.parent.parent.key)?.toString(); const baseNode = node.parent.parent.parent.parent?.parent?.parent; const isCorrectNode = baseNode && baseNode.type === 'YAMLPair' && getStaticYAMLValue(baseNode.key)?.toString() === 'packageExtensions'; if (isCorrectNode && semver.validRange(range) && parent && options.yarnrcDependencyTypes.includes(parent)) { const depName = node.key && getStaticYAMLValue(node.key)?.toString(); if (!depName || !bestRanges[depName] || ignoredDependencies.some((ignore) => ignore.test(depName))) { return; } const minYarnrcVersion = semver.minVersion(range); const minBestRangeVersion = semver.minVersion(bestRanges[depName].range); if (minYarnrcVersion && minBestRangeVersion && semver.lt(minYarnrcVersion, minBestRangeVersion)) { const version = bestRanges[depName].range; const packageJsonFile = bestRanges[depName].path; context.report({ loc: node.value.loc, messageId: 'error', data: { depName, version, packageJsonFile }, fix: (fixer) => fixer.replaceTextRange(node.value.range, `${version}`), suggest: [ { messageId: 'versionUpdate', data: { version }, fix: (fixer) => fixer.replaceTextRange(node.value.range, `${version}`) } ] }); } } } } }; } return {}; } });