UNPKG

@smushytaco/custompatch

Version:

Tool for patching buggy NPM packages instead of forking them

1 lines 14.4 kB
{"version":3,"file":"cli.mjs","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from 'node:fs';\nimport path from 'pathe';\nimport os from 'node:os';\nimport { program } from 'commander';\nimport pacote from 'pacote';\n\nimport pc from 'picocolors';\nimport ownPackage from '../package.json' with { type: 'json' };\nimport { PatchFile } from './types.js';\nimport { getConfig, comparePackages, readPatch } from './patch-utilities.js';\nimport { npmTarballURL } from './npm-utilities.js';\nimport {\n programOptions,\n currentDirectory,\n patchDirectory\n} from './variables.js';\n\nconst patchFiles: PatchFile[] = [];\n\n// Added array to track missing packages\nconst missingPackages: string[] = [];\n\nfunction addPatchFileIfExists(packageName: string, version: string): void {\n const thePackageName = packageName.replaceAll('+', path.sep);\n const destination = path.join(\n currentDirectory,\n 'node_modules',\n thePackageName\n );\n if (!fs.existsSync(destination)) {\n console.warn(\n `${pc.yellowBright('WARNING:')} Package \"${thePackageName}\" is not installed, skipping this patch.`\n );\n return;\n }\n\n patchFiles.push({ packageName, version });\n}\ntry {\n if (!programOptions.version) {\n console.log(\n `${pc.whiteBright('CustomPatch')} version ${pc.greenBright(ownPackage.version)}!\\n`\n );\n }\n\n if (!fs.existsSync(path.join(currentDirectory, 'node_modules'))) {\n console.error(\n `${pc.redBright('ERROR:')} Missing \"node_modules\" folder.`\n );\n process.exit(1);\n }\n\n // Enforce that -p and -r are not used together\n if (programOptions.patch && programOptions.reverse) {\n console.error(\n `${pc.redBright('ERROR:')} Cannot use -p/--patch and -r/--reverse together.`\n );\n process.exit(1);\n }\n\n if (programOptions.patch || programOptions.reverse) {\n // We are applying or reversing patches\n const action = programOptions.reverse ? 'reverse' : 'apply';\n const packageNames = program.args; // Packages specified\n\n if (!fs.existsSync(patchDirectory)) {\n console.warn(\n `${pc.yellowBright('WARNING:')} Missing \"patches\" folder, nothing to do.`\n );\n process.exit(2);\n }\n\n // Build list of patches to apply/reverse\n const allPatchFiles = fs\n .readdirSync(patchDirectory)\n .filter((item: string) => item.endsWith('.patch'));\n\n let selectedPatchFiles: string[];\n\n if (packageNames.length > 0) {\n // Filter patches for specified packages\n selectedPatchFiles = allPatchFiles.filter((patchFile) => {\n const package_ = patchFile.replace('.patch', '').split('#');\n const packageName = package_[0].replaceAll('+', path.sep);\n return packageNames.includes(packageName);\n });\n\n // Track missing packages\n for (const package_ of packageNames) {\n const found = selectedPatchFiles.some((patchFile) => {\n const packageInFile = patchFile\n .replace('.patch', '')\n .split('#')[0];\n return packageInFile === package_.replaceAll('/', '+');\n });\n if (!found) {\n missingPackages.push(package_);\n }\n }\n\n if (selectedPatchFiles.length === 0 && missingPackages.length > 0) {\n for (const package_ of missingPackages) {\n console.warn(\n `${pc.yellowBright('WARNING:')} No patches found for package \"${package_}\".`\n );\n }\n process.exit(0);\n }\n } else {\n // No package names specified, use all patches\n selectedPatchFiles = allPatchFiles;\n }\n\n // Prepare list of patches to apply/reverse\n for (const patchFile of selectedPatchFiles) {\n const package_ = patchFile.replace('.patch', '').split('#');\n addPatchFileIfExists(package_[0], package_[1]);\n }\n\n // Output specific missing package warnings\n if (missingPackages.length > 0) {\n for (const package_ of missingPackages) {\n console.warn(\n `${pc.yellowBright('WARNING:')} No patches found for package \"${package_}\".`\n );\n }\n }\n\n console.log(\n `${action === 'apply' ? 'Applying' : 'Reversing'} ${pc.cyanBright(patchFiles.length)} patch${patchFiles.length === 1 ? '.' : 'es.'}`\n );\n\n for (const { packageName, version } of patchFiles) {\n try {\n await readPatch(packageName, version, programOptions.reverse);\n } catch (error) {\n console.error(\n `${pc.redBright('ERROR:')} Failed to ${action} patch for ${packageName} - ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n } else if (program.args.length > 0) {\n // Create patch for each of the provided package names\n for (const packageName of program.args) {\n await makePatch(packageName);\n }\n } else {\n // Default behavior: apply all patches\n if (!fs.existsSync(patchDirectory)) {\n console.warn(\n `${pc.yellowBright('WARNING:')} Missing \"patches\" folder, nothing to do.`\n );\n process.exit(2);\n }\n // Apply patches\n for (const item of fs.readdirSync(patchDirectory)) {\n if (!item.endsWith('.patch')) continue;\n const package_ = item.replace('.patch', '').split('#');\n addPatchFileIfExists(package_[0], package_[1]);\n }\n console.log(\n `Found ${pc.cyanBright(patchFiles.length)} ${patchFiles.length === 1 ? 'patch.' : 'patches.'}`\n );\n\n for (const { packageName, version } of patchFiles) {\n try {\n await readPatch(packageName, version);\n } catch (error) {\n console.error(\n `${pc.redBright('ERROR:')} Failed to apply patch for ${packageName} - ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n} catch (error) {\n console.error(\n `${pc.redBright('ERROR:')} Unhandled error: ${error instanceof Error ? error.message : String(error)}`\n );\n process.exit(1);\n}\n\nasync function makePatch(packageName: string): Promise<void> {\n console.log(`Creating patch for: ${pc.magentaBright(packageName)}.`);\n const config = getConfig(packageName);\n if (config) {\n await fetchPackage(\n packageName,\n npmTarballURL(packageName, config.version),\n config.version\n );\n } else {\n console.error(\n `${pc.redBright('ERROR:')} Could not find the URL for tarball.`\n );\n }\n}\n\n// Download the tarball\nasync function fetchPackage(\n packageName: string,\n url: string,\n version: string\n): Promise<void> {\n console.log(\n `Fetching tarball of ${pc.whiteBright(packageName)} from ${pc.green(url)}`\n );\n const destination = path.join(os.tmpdir(), packageName);\n try {\n await pacote.extract(url, destination);\n await comparePackages(packageName, version);\n } catch (error) {\n console.error(\n pc.redBright(error instanceof Error ? error.message : String(error))\n );\n return;\n }\n\n try {\n await fs.promises.rm(destination, { recursive: true, force: true });\n } catch (error) {\n console.error(\n `${pc.redBright('ERROR:')} Could not clean up the TEMP folder - ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n"],"names":[],"mappings":"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"}