react-native-integrate
Version:
Automate integration of additional code into React Native projects
167 lines (166 loc) • 7.99 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.importPackageJson = importPackageJson;
exports.installModules = installModules;
exports.getInstallCommand = getInstallCommand;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const picocolors_1 = __importDefault(require("picocolors"));
const constants_1 = require("../../../constants");
const prompter_1 = require("../../../prompter");
const applyObjectModification_1 = require("../../applyObjectModification");
const getInstalledPackages_1 = require("../../getInstalledPackages");
const getPackageConfig_1 = require("../../getPackageConfig");
const runCommand_1 = require("../../runCommand");
function importPackageJson(projectPath) {
try {
const packageJson = (0, getInstalledPackages_1.getPackageJson)(projectPath);
// check if it is rn project
if (!packageJson.dependencies ||
!('react-native' in packageJson.dependencies))
return null;
return {
id: 'packageJson',
title: 'Package.json',
value: `${packageJson.name}@${packageJson.version}`,
apply: () => setPackageJson(packageJson),
};
}
catch (_e) {
return null;
}
}
async function setPackageJson(oldPackageJson) {
const packageJson = (0, getInstalledPackages_1.getPackageJson)();
const { deprecatedPackages, deprecatedDevPackages } = await findDeprecatedPackages(oldPackageJson, packageJson);
// process rest
Object.entries(oldPackageJson).forEach(([key, value]) => {
switch (key) {
case 'dependencies':
// append new dependencies only
packageJson.dependencies = (0, applyObjectModification_1.modifyObject)(packageJson.dependencies, value, 'append');
// delete deprecated package
for (const dependency of deprecatedPackages) {
delete packageJson.dependencies[dependency];
}
// sort dependencies
packageJson.dependencies = Object.fromEntries(Object.entries(packageJson.dependencies).sort());
break;
case 'devDependencies':
// append new dev dependencies only
packageJson.devDependencies = (0, applyObjectModification_1.modifyObject)(packageJson.devDependencies || {}, value, 'append');
// delete deprecated package
for (const dependency of deprecatedDevPackages) {
delete packageJson.devDependencies[dependency];
}
// sort devDependencies
packageJson.devDependencies = Object.fromEntries(Object.entries(packageJson.devDependencies).sort());
break;
case 'version':
case 'description':
// import version and description
packageJson[key] = value;
break;
default:
if (typeof value === 'string') {
// import any old string which doesn't exist in new
if (!(key in packageJson))
packageJson[key] = value;
}
else if (typeof value === 'object') {
if (packageJson[key] == null) {
// import any old object which doesn't exist in new
packageJson[key] = value;
}
else if (typeof packageJson[key] === 'object') {
// merge old object with append mode
packageJson[key] = (0, applyObjectModification_1.modifyObject)(packageJson[key], value, 'append');
}
}
break;
}
});
const packageJsonPath = (0, getInstalledPackages_1.getPackageJsonPath)();
fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');
(0, prompter_1.logMessage)(`merged ${picocolors_1.default.yellow('package.json')}`);
}
async function installModules(oldProjectPath) {
const installCommand = await getInstallCommand(oldProjectPath);
const { exitCode } = await (0, runCommand_1.runCommand)(installCommand, {
silent: false,
progressText: `running ${picocolors_1.default.yellow(installCommand)}`,
errorText: `installation using ${picocolors_1.default.yellow(installCommand)} failed`,
completeText: 'installed modules',
});
if (exitCode !== 0) {
await (0, prompter_1.multiselect)('Please complete installation manually and return here to proceed.', {
options: [
{ label: 'completed installation, continue upgrade', value: true },
],
required: true,
});
}
}
async function getInstallCommand(projectPath) {
const isNpmLockPresent = fs_1.default.existsSync(path_1.default.join(projectPath, 'package-lock.json'));
const isYarnLockPresent = fs_1.default.existsSync(path_1.default.join(projectPath, 'yarn.lock'));
const isPnpmLockPresent = fs_1.default.existsSync(path_1.default.join(projectPath, 'pnpm-lock.yaml'));
const isBunLockPresent = fs_1.default.existsSync(path_1.default.join(projectPath, 'bun.lockb')) ||
fs_1.default.existsSync(path_1.default.join(projectPath, 'bun.lock'));
const options = [];
if (isNpmLockPresent)
options.push({ label: 'npm', value: 'npm install' });
if (isYarnLockPresent)
options.push({ label: 'yarn', value: 'yarn install' });
if (isPnpmLockPresent)
options.push({ label: 'pnpm', value: 'pnpm install' });
if (isBunLockPresent)
options.push({ label: 'bun', value: 'bun install' });
let installer;
if (options.length > 1) {
installer = (await (0, prompter_1.select)('Multiple lock files found, please select an installer:', {
options,
}));
}
else if (options.length === 1) {
installer = options[0].value;
}
else {
installer = 'npm install';
}
return installer;
}
async function findDeprecatedPackages(oldPackageJson, packageJson) {
const deprecatedPackages = [];
const deprecatedDevPackages = [];
const oldRNVersion = oldPackageJson.dependencies?.['react-native'];
const newRNVersion = packageJson.dependencies?.['react-native'];
if (oldRNVersion && newRNVersion) {
try {
const oldDiffPackageJsonContent = await (0, getPackageConfig_1.getRemoteFile)(constants_1.Constants.REMOTE_DIFF_PACKAGE_JSON.replace('[version]', oldRNVersion));
const newDiffPackageJsonContent = await (0, getPackageConfig_1.getRemoteFile)(constants_1.Constants.REMOTE_DIFF_PACKAGE_JSON.replace('[version]', newRNVersion));
if (oldDiffPackageJsonContent && newDiffPackageJsonContent) {
const oldDiffPackageJson = JSON.parse(oldDiffPackageJsonContent);
const newDiffPackageJson = JSON.parse(newDiffPackageJsonContent);
for (const dependency in oldDiffPackageJson.dependencies) {
if (!(dependency in newDiffPackageJson.dependencies)) {
deprecatedPackages.push(dependency);
}
}
for (const dependency in oldDiffPackageJson.devDependencies) {
if (!(dependency in (newDiffPackageJson.devDependencies || {}))) {
deprecatedDevPackages.push(dependency);
}
}
}
}
catch (e) {
(0, prompter_1.logWarning)('warning: could not get package.json diff, skipping deprecated package check: ' +
e?.message);
}
}
return { deprecatedPackages, deprecatedDevPackages };
}