UNPKG

danger-plugin-npm-check-updates

Version:
182 lines (181 loc) 9.36 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); const objectFilter = require("@arnaudnyc/object-filter"); const fs = require("fs"); const ncu = require("npm-check-updates"); const path = require("path"); const utils_1 = require("./utils"); const npmCheckUpdates = (options = {}, reporter = warn) => __awaiter(void 0, void 0, void 0, function* () { var _a; const { modified_files, created_files, deleted_files } = danger.git; const changedFiles = [...modified_files, ...created_files, ...deleted_files]; const { monorepo = false, monorepoPrefix = 'packages', onlyChangedPackages = false, excludePackages, ignoreLockVersion = true } = options, // tslint:disable-next-line: trailing-comma runOptions = __rest(options, ["monorepo", "monorepoPrefix", "onlyChangedPackages", "excludePackages", "ignoreLockVersion"]); const defaultBasePath = ((_a = runOptions.packageFile) === null || _a === void 0 ? void 0 : _a.replace('package.json', '')) || '.'; const defaultPackageJson = utils_1.readPackageJson(defaultBasePath); const defaultPackageLock = !ignoreLockVersion ? utils_1.readPackageLock(defaultBasePath) : null; let packages = defaultPackageJson ? [ { packageJson: defaultPackageJson, packageLock: defaultPackageLock, }, ] : []; if (monorepo) { const monorepoPackagesPattern = new RegExp(`${monorepoPrefix}\/(.+)\/`); const monorepoPackagesChangedDir = changedFiles .filter((file) => monorepoPackagesPattern.test(file)) .map((file) => { const match = file.match(monorepoPackagesPattern); if (Array.isArray(match)) { return match[0].split('/')[1]; } return []; }) .filter((file, i, arr) => arr.indexOf(file) === i && !Array.isArray(file)); try { const monorepoBasePath = path.join(defaultBasePath, monorepoPrefix); const monorepoPackagesDir = onlyChangedPackages ? monorepoPackagesChangedDir : fs.readdirSync(monorepoBasePath); const monorepoPackages = monorepoPackagesDir .filter((pkg) => { try { const basePath = path.join(monorepoBasePath, pkg.toString(), '/'); const packageJson = utils_1.readPackageJson(basePath); return Boolean(packageJson); } catch (e) { console.error(e.message); return false; } }) .map((pkg) => { const basePath = path.join(monorepoBasePath, pkg.toString(), '/'); return { packageJson: utils_1.readPackageJson(basePath), packageLock: !ignoreLockVersion ? utils_1.readPackageLock(basePath) : null, }; }); packages = packages.concat(monorepoPackages); // tslint:disable-next-line: no-empty } catch (e) { console.error(e.message); } } if (excludePackages) { if (typeof excludePackages === 'string') { packages = packages.filter((pkg) => { var _a; return excludePackages !== ((_a = pkg === null || pkg === void 0 ? void 0 : pkg.packageJson) === null || _a === void 0 ? void 0 : _a.name); }); } else if (Array.isArray(excludePackages)) { packages = packages.filter((pkg) => { var _a; return !excludePackages.includes((_a = pkg === null || pkg === void 0 ? void 0 : pkg.packageJson) === null || _a === void 0 ? void 0 : _a.name); }); } else if (excludePackages instanceof RegExp) { packages = packages.filter((pkg) => { var _a; return !excludePackages.test((_a = pkg === null || pkg === void 0 ? void 0 : pkg.packageJson) === null || _a === void 0 ? void 0 : _a.name); }); } } for (const { packageJson, packageLock } of packages) { try { const _options = Object.assign(Object.assign({}, runOptions), { packageData: JSON.stringify(packageJson) }); const getPackageLockVersion = (dep) => { var _a, _b; let result = '-'; if (packageLock) { switch (packageLock.type) { case 'npm': result = (_a = packageLock.dependencies[dep]) === null || _a === void 0 ? void 0 : _a.version; break; case 'yarn': const depNames = Object.keys(packageLock.object); const depName = depNames.find((name) => new RegExp(`^${dep}@`).test(name)); if (depName) { result = (_b = packageLock.object[depName]) === null || _b === void 0 ? void 0 : _b.version; } break; } } return result; }; const getPackageType = (dep) => { let result = '-'; if (packageJson) { const dependencyTypes = [ 'dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies', ]; for (const type of dependencyTypes) { const found = packageJson[type] && packageJson[type].constructor.name === 'Object' ? Object.keys(packageJson[type]).find((key) => key === dep) : null; if (found) { result = type; return result; } } } return result; }; let ncuResult = yield ncu.run(_options); if (!ignoreLockVersion) { const filteredNcuResult = objectFilter(ncuResult, (key, value) => { return !value.includes(getPackageLockVersion(key)); }); ncuResult = filteredNcuResult; } const outdatedDependenciesNames = Object.keys(ncuResult); const currentDependencies = ncu.getCurrentDependencies(packageJson); const outdatedDependencies = {}; for (const dep of outdatedDependenciesNames) { outdatedDependencies[dep] = { from: currentDependencies[dep] || '-', to: ncuResult[dep] || '-', lock: !ignoreLockVersion ? getPackageLockVersion(dep) : null, packageType: getPackageType(dep), url: `https://www.npmjs.com/package/${dep}`, }; } if (outdatedDependenciesNames.length) { const table = outdatedDependenciesNames .map((dependencyName) => { const { from, to, lock, packageType, url } = outdatedDependencies[dependencyName]; return `<tr><td><a href="${url}" target="_blank">${dependencyName}</a></td>${!ignoreLockVersion ? `<td>${lock}</td>` : ''}<td>${from}</td><td>${to}</td><td>${packageType}</td></tr>`; }) .join(' '); reporter(`You have ${outdatedDependenciesNames.length} outdated dependencies in ${packageJson === null || packageJson === void 0 ? void 0 : packageJson.name}.\n <details><summary>Show Lists</summary><table><thead><tr><th width="100%">Package</th>${!ignoreLockVersion ? `<th>Package Lock</th>` : ''}<th>From</th><th>To</th><th>Package Type</th></tr></thead>${table}</table></details>`); } } catch (err) { fail(`npm check updates error in ${packageJson === null || packageJson === void 0 ? void 0 : packageJson.name}: ` + err.message); } } }); exports.default = npmCheckUpdates;