UNPKG

flow-typed

Version:

A repository of high quality flow type definitions

265 lines (206 loc) 9.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.determineFlowVersion = determineFlowVersion; exports.findFlowSpecificVer = findFlowSpecificVer; exports.findPackageJsonDepVersionStr = findPackageJsonDepVersionStr; exports.findPackageJsonPath = findPackageJsonPath; exports.findWorkspacesPackages = findWorkspacesPackages; exports.getPackageJsonData = getPackageJsonData; exports.getPackageJsonDependencies = getPackageJsonDependencies; exports.loadPnpResolver = loadPnpResolver; exports.mergePackageJsonDependencies = mergePackageJsonDependencies; var _safe = _interopRequireDefault(require("colors/safe")); var _glob = _interopRequireDefault(require("glob")); var _semver = _interopRequireWildcard(require("semver")); var _jsYaml = require("js-yaml"); var _fileUtils = require("../fileUtils"); var _node = require("../node"); var _semver2 = require("../semver"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const PKG_JSON_DEP_FIELDS = ['dependencies', 'devDependencies', 'peerDependencies', 'bundledDependencies']; async function findPackageJsonDepVersionStr(pkgJson, depName) { let matchedFields = []; const deps = PKG_JSON_DEP_FIELDS.reduce((deps, section) => { const contentSection = pkgJson.content[section]; if (contentSection && contentSection[depName]) { matchedFields.push(section); deps.push(contentSection[depName]); } return deps; }, []); if (deps.length === 0) { return null; } else if (deps.length === 1) { return deps.pop(); } else { throw new Error(`Found ${depName} listed in ${String(deps.length)} places in ` + `${pkgJson.pathStr}!`); } } async function findPackageJsonPath(pathStr) { const pkgJsonPathStr = await (0, _fileUtils.searchUpDirPath)(pathStr, async p => await _node.fs.exists(_node.path.join(p, 'package.json'))); if (pkgJsonPathStr === null) { throw new Error(`Unable to find a package.json for ${pathStr}!`); } return _node.path.join(pkgJsonPathStr, 'package.json'); } function getWorkspacePatterns(cwd, pkgJson) { const pnpmWorkspacePath = _node.path.join(cwd, 'pnpm-workspace.yaml'); const hasPnpmWorkspaces = _node.fs.existsSync(pnpmWorkspacePath); if (hasPnpmWorkspaces) { const doc = (0, _jsYaml.load)(_node.fs.readFileSync(pnpmWorkspacePath, 'utf-8')); if (doc && typeof doc === 'object' && doc.packages) { return doc.packages; } } if (Array.isArray(pkgJson.content.workspaces)) { return pkgJson.content.workspaces; } if (pkgJson.content.workspaces && Array.isArray(pkgJson.content.workspaces.packages)) { return pkgJson.content.workspaces.packages; } return []; } async function findWorkspacesPackagePaths(pkgJson, workspaces) { const tasks = await Promise.all(workspaces.map(pattern => { return new Promise((resolve, reject) => { (0, _glob.default)(`${_node.path.dirname(pkgJson.pathStr)}/${pattern}/package.json`, { absolute: true }, (err, files) => { if (err) { reject(err); } else { resolve(files); } }); }); })); return tasks.flat(); } async function findWorkspacesPackages(cwd, pkgJson, ftConfig) { const paths = await findWorkspacesPackagePaths(pkgJson, getWorkspacePatterns(cwd, pkgJson)); const configPaths = ftConfig.workspaces ? await findWorkspacesPackagePaths(pkgJson, ftConfig.workspaces) : []; return Promise.all([...paths, ...configPaths].map(async pathStr => { const pkgJsonContent = await _node.fs.readJson(pathStr); return { pathStr, content: pkgJsonContent }; })); } // TODO: Write tests for this function getPackageJsonDependencies(pkgJson, /** * dependency groups to ignore * * eg: dev, optional, bundled, peer, etc */ ignoreDeps, /** * dependencies or scopes of dependencies to be ignored */ ignoreDefs) { const depFields = PKG_JSON_DEP_FIELDS.filter(field => { return ignoreDeps.indexOf(field.slice(0, -'Dependencies'.length)) === -1; }); return depFields.reduce((deps, section) => { const contentSection = pkgJson.content[section]; if (contentSection) { Object.keys(contentSection).forEach(pkgName => { if (deps[pkgName]) { console.warn(`Found ${pkgName} listed twice in package.json!`); } const pkgIgnored = ignoreDefs.some(cur => { const ignoreDef = cur.trim(); if (ignoreDef === '') return false; // if we are looking to ignore a scope dir if (ignoreDef.charAt(0) === '@' && (ignoreDef.indexOf('/') === -1 || ignoreDef.indexOf('/') === ignoreDef.length - 1)) { return pkgName.startsWith(ignoreDef); } return pkgName === ignoreDef; }); if (pkgIgnored) return; deps[pkgName] = contentSection[pkgName]; }); } return deps; }, {}); } function mergePackageJsonDependencies(a, b) { const result = { ...a }; for (const dep of Object.keys(b)) { const version = b[dep]; let doesIntersect; try { doesIntersect = (0, _semver.intersects)(result[dep], version); } catch (e) { doesIntersect = result[dep] === version; } if (a[dep] != null && !doesIntersect) { console.log(_safe.default.yellow("\t Conflicting versions for '%s' between '%s' and '%s'"), dep, a[dep], version); } else { result[dep] = version; } } return result; } async function getPackageJsonData(pathStr) { const pkgJsonPath = await findPackageJsonPath(pathStr); const pkgJsonContent = await _node.fs.readJson(pkgJsonPath); return { pathStr: pkgJsonPath, content: pkgJsonContent }; } async function determineFlowVersion(pathStr) { const pkgJsonData = await getPackageJsonData(pathStr); const flowBinVersionStr = await findPackageJsonDepVersionStr(pkgJsonData, 'flow-bin'); if (flowBinVersionStr !== null) { let flowVerStr; if (_semver.default.valid(flowBinVersionStr)) { flowVerStr = flowBinVersionStr; } else { const flowVerRange = new _semver.default.Range(flowBinVersionStr); if (flowVerRange.set[0].length !== 2) { const cliPkgJson = require('../../../package.json'); const cliFlowVer = cliPkgJson.devDependencies['flow-bin']; throw new Error(`Unable to extract flow-bin version from package.json!\n` + `Never use a complex version range with flow-bin. Always use a ` + `specific version (i.e. "${cliFlowVer}").`); } flowVerStr = flowVerRange.set[0][0].semver.version; } return (0, _semver2.stringToVersion)('v' + flowVerStr); } return null; } async function loadPnpResolver(pkgJson) { if (!(pkgJson.content.installConfig && pkgJson.content.installConfig.pnp)) { return null; } const pnpJsFile = _node.path.resolve(pkgJson.pathStr, '..', '.pnp.js'); if (await _node.fs.exists(pnpJsFile)) { // $FlowFixMe[unsupported-syntax] return require(pnpJsFile); } throw new Error('Unable to find Yarn PNP resolver lib: `.pnp.js`! ' + 'Did you forget to run `yarn install` before running `flow-typed install`?'); } async function findFlowSpecificVer(startingPath) { const flowSemver = await determineFlowVersion(startingPath); if (flowSemver === null) { throw new Error('Failed to find a flow-bin dependency in package.json.\n' + 'Please install flow-bin: `npm install --save-dev flow-bin`'); } if (flowSemver.range !== undefined) { throw new Error(`Unable to extract flow-bin version from package.json!\n` + `Never use a complex version range with flow-bin. Always use a ` + `specific major/minor version (i.e. "^0.39").`); } const major = flowSemver.major; if (major === 'x') { throw new Error(`Unable to extract flow-bin version from package.json!\n` + `Never use a wildcard major version with flow-bin!`); } return { major, minor: flowSemver.minor, patch: flowSemver.patch, prerel: flowSemver.prerel == null ? null : flowSemver.prerel }; }