import { promises as fs, existsSync, readFileSync } from "fs"; import { resolve, dirname } from "path"; import { formatWithPrettier } from "./utils/prettier.js"; interface PackageJson { sealgen?: { controllerDirs?: string[]; styleDirs?: string[]; [key: string]: unknown; }; [key: string]: unknown; } function findParentProjectWithSealgen(): string { let currentDir = process.cwd(); while (currentDir !== dirname(currentDir)) { const packageJsonPath = resolve(currentDir, "package.json"); if (existsSync(packageJsonPath)) { try { const packageJsonContent = readFileSync( packageJsonPath, "utf-8" ); const packageJson = JSON.parse( packageJsonContent ) as PackageJson; // Check if this package.json has a sealgen configuration if (packageJson.sealgen) { return currentDir; } } catch (error) { // If we can't read or parse the package.json, continue to parent console.warn( `Warning: Could not read package.json at ${packageJsonPath}:`, error ); } } currentDir = dirname(currentDir); } throw new Error( "Could not find a parent project with sealgen configuration" ); } async function updatePackageJson( projectDir: string, moduleName: string, subdirectory: string, type: "controllerDirs" | "styleDirs" ): Promise { const packageJsonPath = resolve(projectDir, "package.json"); const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8"); const packageJson = JSON.parse(packageJsonContent) as PackageJson; // Initialize sealgen configuration if it doesn't exist if (!packageJson.sealgen) { packageJson.sealgen = {}; } // Initialize the specific array if it doesn't exist if (!packageJson.sealgen[type]) { packageJson.sealgen[type] = []; } const pathToAdd = `node_modules/${moduleName}/${subdirectory}`; const existingPaths = packageJson.sealgen[type]; // Check if the path is already present if (existingPaths.includes(pathToAdd)) { console.warn(`${type} already contains: ${pathToAdd}`); return; } // Add the new path existingPaths.push(pathToAdd); // Write back the updated package.json with proper formatting const updatedContent = await formatWithPrettier( JSON.stringify(packageJson, null, 2), "json" ); await fs.writeFile(packageJsonPath, updatedContent); console.info(`Added ${pathToAdd} to ${type} in ${packageJsonPath}`); } export async function registerExternalControllers( _args: Record ): Promise { // Extract positional arguments from process.argv since yargs doesn't handle them for these commands const moduleName = process.argv.at(3); const subdirectory = process.argv.at(4); if (!moduleName || !subdirectory) { console.error( "Usage: npx sealgen register-external-controllers " ); process.exit(1); } try { const projectDir = findParentProjectWithSealgen(); await updatePackageJson( projectDir, moduleName, subdirectory, "controllerDirs" ); } catch (error) { console.error("Error:", error instanceof Error ? error.message : error); process.exit(1); } } export async function registerExternalStyles( _args: Record ): Promise { // Extract positional arguments from process.argv since yargs doesn't handle them for these commands const moduleName = process.argv.at(3); const subdirectory = process.argv.at(4); if (!moduleName || !subdirectory) { console.error( "Usage: npx sealgen register-external-styles " ); process.exit(1); } try { const projectDir = findParentProjectWithSealgen(); await updatePackageJson( projectDir, moduleName, subdirectory, "styleDirs" ); } catch (error) { console.error("Error:", error instanceof Error ? error.message : error); process.exit(1); } }