diff --git a/packages/api/session.mts b/packages/api/session.mts index 21560ca0..b4220491 100644 --- a/packages/api/session.mts +++ b/packages/api/session.mts @@ -30,6 +30,7 @@ import { fileExists } from './fs-utils.mjs'; import { validFilename } from '@srcbook/shared'; import { pathToCodeFile } from './srcbook/path.mjs'; import { exec } from 'node:child_process'; +import { npmInstall } from './exec.mjs'; const sessions: Record = {}; @@ -297,10 +298,42 @@ export function updateCell(session: SessionType, cell: CellType, updates: CellUp return updateCodeCell(session, cell, updates); } } - -export async function formatCode(filePath: string) { +async function ensurePrettierInstalled(dir: string): Promise { + const prettierPath = Path.join(dir, 'node_modules', 'prettier'); try { - const command = `npx prettier ${filePath}`; + // check if prettier is installed + await fs.access(prettierPath); + return true; + } catch (error) { + return new Promise((resolve) => { + try { + npmInstall({ + cwd: dir, + packages: ['prettier'], + stdout: () => {}, + stderr: (err) => console.error(err), + onExit: (exitCode) => { + if (exitCode === 0) { + resolve(true); + } else { + console.error('Failed to install Prettier:', exitCode); + resolve(false); + } + }, + }); + } catch (installError) { + console.error('Failed to initiate Prettier installation:', installError); + resolve(false); + } + }); + } +} +export async function formatCode(dir: string, fileName: string) { + try { + await ensurePrettierInstalled(dir); + + const codeFilePath = pathToCodeFile(dir, fileName); + const command = `npx prettier ${codeFilePath}`; return new Promise((resolve, reject) => { exec(command, async (error, stdout) => { @@ -319,7 +352,7 @@ export async function formatCode(filePath: string) { } export async function formatAndUpdateCodeCell(session: SessionType, cell: CodeCellType) { try { - const formattedCode = await formatCode(pathToCodeFile(session.dir, cell.filename)); + const formattedCode = await formatCode(session.dir, cell.filename); return updateCodeCell(session, cell, { source: formattedCode } as { source: string }); } catch (error) { return Promise.resolve({ diff --git a/packages/api/srcbook/config.mts b/packages/api/srcbook/config.mts index d1141158..5ad9d778 100644 --- a/packages/api/srcbook/config.mts +++ b/packages/api/srcbook/config.mts @@ -1,14 +1,12 @@ export function buildJSPackageJson() { return { type: 'module', - dependencies: { + devDependencies: { prettier: 'latest', }, prettier: { - tabWidth: 2, semi: true, singleQuote: true, - printWidth: 100, }, }; } @@ -20,13 +18,13 @@ export function buildTSPackageJson() { tsx: 'latest', typescript: 'latest', '@types/node': 'latest', + }, + devDependencies: { prettier: 'latest', }, prettier: { - tabWidth: 2, semi: true, singleQuote: true, - printWidth: 100, }, }; }