flow-typed
Version:
A repository of high quality flow type definitions
265 lines (206 loc) • 9.15 kB
JavaScript
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
};
}
;