UNPKG

@reliverse/rse

Version:

@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power

212 lines (211 loc) 7.11 kB
import { relinka } from "@reliverse/relinka"; import { confirmPrompt, multiselectPrompt } from "@reliverse/rempts"; import { cliConfigJsonc } from "../../constants.js"; import { convertCjsToEsm } from "../codemods/convertCjsToEsm.js"; import { convertTypeDefinitions } from "../codemods/convertDefinitions.js"; import { convertImportStyle } from "../codemods/convertImportStyle.js"; import { convertJsToTs } from "../codemods/convertJsToTs.js"; import { convertQuoteStyle } from "../codemods/convertQuoteStyle.js"; import { convertRuntime } from "../codemods/convertRuntime.js"; import { convertToMonorepo } from "../codemods/convertToMonorepo.js"; import { replaceImportSymbol } from "../codemods/replaceImportSymbol.js"; import { replaceWithModern } from "../codemods/replaceWithModern.js"; export async function handleCodemods(rules, cwd) { if (!rules.codeStyle || !rules.preferredLibraries) { relinka("error", `Missing required configuration in ${cliConfigJsonc}`); return; } const availableCodemods = []; if (rules.codeStyle?.importSymbol?.length) { availableCodemods.push({ label: "Replace Import Symbols", value: "import-symbols", hint: `${rules.codeStyle.importSymbol.length} symbol(s) to replace` }); } availableCodemods.push({ label: "Convert Quote Style", value: "quote-style", hint: `Convert all quotes to ${rules.codeStyle.quoteMark}` }); const importStyle = rules.codeStyle?.importOrRequire; if (importStyle && importStyle !== "mixed") { availableCodemods.push({ label: "Convert Import Style", value: "import-style", hint: `Convert all imports to ${importStyle} style` }); } const typeStyle = rules.codeStyle?.typeOrInterface; if (typeStyle && typeStyle !== "mixed") { availableCodemods.push({ label: "Convert Type Definitions", value: "type-definitions", hint: `Convert all declarations to ${typeStyle}s` }); } if (rules.codeStyle?.cjsToEsm) { availableCodemods.push({ label: "Convert CommonJS to ESM", value: "cjs-to-esm", hint: "Convert require/exports to import/export" }); } if (rules.projectRuntime === "node") { availableCodemods.push( { label: "Convert to Bun", value: "nodejs-to-bun", hint: "Convert Node.js APIs to Bun APIs" }, { label: "Convert to Deno", value: "nodejs-to-deno", hint: "Convert Node.js APIs to Deno APIs" } ); } if (rules.monorepo?.type) { availableCodemods.push({ label: "Convert to Monorepo", value: "single-to-monorepo", hint: `Convert to ${rules.monorepo.type} monorepo` }); } if (rules.codeStyle?.modernize && Object.values(rules.codeStyle.modernize).some(Boolean)) { availableCodemods.push({ label: "Modernize Code", value: "modernize", hint: "Replace Node.js APIs with modern alternatives" }); } if (rules.codeStyle?.jsToTs) { availableCodemods.push({ label: "Convert JavaScript to TypeScript", value: "js-to-ts", hint: "Add TypeScript types to JavaScript files" }); } if (availableCodemods.length === 0) { relinka("info", `No codemods available in ${cliConfigJsonc}`); return; } const selectedCodemods = await multiselectPrompt({ title: "Select codemods to run", options: availableCodemods }); for (const codemod of selectedCodemods) { if (codemod === "import-symbols") { const targetSymbol = rules.codeStyle?.importSymbol; if (!targetSymbol) { continue; } const shouldReplace = await confirmPrompt({ title: `Replace current import symbol with "${targetSymbol}"?`, content: "The current symbol will be automatically detected.", defaultValue: true }); if (shouldReplace) { await replaceImportSymbol(cwd, targetSymbol); relinka( "success", `Replaced detected import symbol with "${targetSymbol}"` ); } } else if (codemod === "quote-style" && rules.codeStyle?.quoteMark) { const shouldConvert = await confirmPrompt({ title: `Convert all quotes to ${rules.codeStyle.quoteMark}?`, defaultValue: true }); if (shouldConvert) { await convertQuoteStyle(cwd, rules.codeStyle.quoteMark); } } else if (codemod === "import-style") { const style = rules.codeStyle?.importOrRequire; if (style && style !== "mixed") { const shouldConvert = await confirmPrompt({ title: `Convert to ${style} style?`, defaultValue: true }); if (shouldConvert) { await convertImportStyle(cwd, style); } } } else if (codemod === "type-definitions") { const style = rules.codeStyle?.typeOrInterface; if (style && style !== "mixed") { const shouldConvert = await confirmPrompt({ title: `Convert TS definitions to ${style} style?`, defaultValue: true }); if (shouldConvert) { await convertTypeDefinitions(cwd, style); } } } else if (codemod === "cjs-to-esm") { const shouldConvert = await confirmPrompt({ title: "Convert CommonJS to ESM?", defaultValue: true }); if (shouldConvert) { await convertCjsToEsm(cwd); } } else if (codemod === "nodejs-to-bun") { const shouldConvert = await confirmPrompt({ title: "Convert Node.js code to Bun?", defaultValue: true }); if (shouldConvert) { await convertRuntime(cwd, "bun"); } } else if (codemod === "nodejs-to-deno") { const shouldConvert = await confirmPrompt({ title: "Convert Node.js code to Deno?", defaultValue: true }); if (shouldConvert) { await convertRuntime(cwd, "deno"); } } else if (codemod === "single-to-monorepo" && rules.monorepo?.type) { const monorepoType = rules.monorepo.type; if (isValidMonorepoType(monorepoType)) { const shouldConvert = await confirmPrompt({ title: `Convert to ${monorepoType} monorepo?`, defaultValue: true }); if (shouldConvert) { await convertToMonorepo( cwd, monorepoType, rules.monorepo.packages, rules.monorepo.sharedPackages ); } } } else if (codemod === "modernize") { const shouldModernize = await confirmPrompt({ title: "Replace Node.js APIs with modern alternatives?", defaultValue: true }); if (shouldModernize) { await replaceWithModern(cwd); } } else if (codemod === "js-to-ts") { const shouldConvert = await confirmPrompt({ title: "Convert JavaScript files to TypeScript?", defaultValue: true }); if (shouldConvert) { await convertJsToTs(cwd); } } } } function isValidMonorepoType(type) { return [ "turborepo", "moonrepo", "bun-workspaces", "pnpm-workspaces" ].includes(type); }