Skip to content

Instantly share code, notes, and snippets.

@forivall
Created September 17, 2025 00:58
Show Gist options
  • Save forivall/e8af32513580c62d806decc33791675d to your computer and use it in GitHub Desktop.
Save forivall/e8af32513580c62d806decc33791675d to your computer and use it in GitHub Desktop.
helper for a monorepo to improve source navigation
import { exec } from 'child_process';
import { readFile, writeFile } from 'node:fs/promises';
import path from 'node:path';
import { promisify } from 'util';
import * as YAML from 'yaml';
const execAsync = promisify(exec);
// update package.json imports.types path to point to the source file
/**
* @param {string} packagePath
*/
async function updatePackageJson(packagePath) {
const packageJsonPath = path.join(packagePath, 'package.json');
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8'));
let updated = false;
if (packageJson.exports) {
for (const key in packageJson.exports) {
const typesImport = packageJson.exports[key].types;
const replacement =
typesImport &&
typesImport.replace(/\/lib\//, '/src/').replace(/\.d\.ts$/, '.ts');
if (typesImport !== replacement) {
if (!updated) {
console.log(`Updating package.json: ${packageJsonPath}`);
}
console.log(
`Updating import entry for ${key}: ${typesImport} -> ${replacement}`
);
packageJson.exports[key].types = replacement;
updated = true;
}
}
if (!updated) {
return;
}
await writeFile(
packageJsonPath,
JSON.stringify(packageJson, null, 2) + '\n'
);
console.log(`Updated ${packageJsonPath}`);
const patchFilePath = packageJsonPath + '.patch';
try {
const { stdout, stderr } = await execAsync(
`git diff -- ${packageJsonPath}`
);
if (stderr) {
console.error(`Stderr from git diff for ${packageJsonPath}: ${stderr}`);
}
if (stdout) {
await writeFile(patchFilePath, stdout);
console.log(`Generated patch file: ${patchFilePath}`);
} else {
console.log(`No changes to generate patch file for ${packageJsonPath}`);
}
} catch (error) {
console.error(`Error generating patch for ${packageJsonPath}: ${error}`);
}
}
}
async function main() {
const pnpmLock = YAML.parse(await readFile('pnpm-lock.yaml', 'utf-8'));
if (!pnpmLock.importers) {
console.warn('No importers found in pnpm-lock.yaml');
return;
}
for (const importer of Object.keys(pnpmLock.importers)) {
await updatePackageJson(importer);
}
}
main().catch((err) => {
console.error('Failed to update package.json files', err);
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment