UNPKG

@mintlify/previewing

Version:

Preview Mintlify docs locally

106 lines (105 loc) 4.29 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { getFileListSync, prebuild } from '@mintlify/prebuild'; import fse, { pathExists } from 'fs-extra'; import isOnline from 'is-online'; import pathUtil from 'path'; import { CLIENT_PATH, DOT_MINTLIFY, CMD_EXEC_PATH, VERSION_PATH, NEXT_PUBLIC_PATH, NEXT_PROPS_PATH, } from '../constants.js'; import { addLog, clearLogs } from '../logging-state.js'; import { ErrorLog, SpinnerLog } from '../logs.js'; import { timeDev, timeDevSync } from './dev-timing.js'; import { run } from './run.js'; import { silentUpdateClient } from './update.js'; const PRUNE_EXEMPT_PREFIXES = ['favicons/', '.mint-content-source']; const prunePublicOrphans = () => { let publicFiles; try { publicFiles = getFileListSync(NEXT_PUBLIC_PATH); } catch { return; } for (const relativePath of publicFiles) { if (PRUNE_EXEMPT_PREFIXES.some((prefix) => relativePath.startsWith(prefix))) { continue; } if (!fse.existsSync(pathUtil.join(CMD_EXEC_PATH, relativePath))) { fse.removeSync(pathUtil.join(NEXT_PUBLIC_PATH, relativePath)); } } }; const dev = async (argv) => { const hasInternet = await timeDev('check internet', () => isOnline()); const localSchema = argv['local-schema']; const clientVersion = argv['client-version']; const localClientVersion = argv['local-client-version']; const packageName = argv.packageName; const groups = argv.groups; const cliVersion = argv.cliVersion; const disableOpenApi = argv.disableOpenapi; await timeDev('ensure .mintlify directory', () => fse.ensureDir(DOT_MINTLIFY)); const versionString = await timeDev('read local client version', async () => { return (await pathExists(VERSION_PATH)) ? fse.readFileSync(VERSION_PATH, 'utf8') : null; }); if (!versionString && !localClientVersion && !hasInternet) { clearLogs(); addLog(_jsx(ErrorLog, { message: `running ${packageName} dev after updating requires an internet connection.` })); await new Promise((resolve) => setTimeout(resolve, 50)); process.exit(1); } addLog(_jsx(SpinnerLog, { message: "preparing local preview..." })); const { needsUpdate, error } = await timeDev('update local client', () => silentUpdateClient({ versionString, clientVersion, localClientVersion, cliVersion, })); if (error) { clearLogs(); addLog(_jsx(ErrorLog, { message: error })); await new Promise((resolve) => setTimeout(resolve, 50)); process.exit(1); } // clear preexisting prebuild files timeDevSync('clear prebuild output', () => { fse.emptyDirSync(NEXT_PROPS_PATH); // only clear public/ when previewing a different docs repo, so unchanged // static files can be skipped on warm starts; on warm starts, prune files // whose source no longer exists so deleted assets stop being served const markerPath = pathUtil.join(NEXT_PUBLIC_PATH, '.mint-content-source'); let previousSource; try { previousSource = fse.readFileSync(markerPath, 'utf8'); } catch { } if (previousSource !== CMD_EXEC_PATH) { fse.emptyDirSync(NEXT_PUBLIC_PATH); fse.outputFileSync(markerPath, CMD_EXEC_PATH); } else { prunePublicOrphans(); } }); timeDevSync('switch to local client directory', () => { process.chdir(CLIENT_PATH); }); let fileImportsMap; try { const result = await timeDev('prebuild content', () => prebuild(CMD_EXEC_PATH, { localSchema, groups, disableOpenApi, allowSourceRefs: true, lazyPages: true, })); fileImportsMap = result?.fileImportsMap; } catch (err) { clearLogs(); const errorText = err instanceof Error && err.message ? err.message : 'prebuild step failed'; addLog(_jsx(ErrorLog, { message: errorText })); await new Promise((resolve) => setTimeout(resolve, 50)); process.exit(1); } await timeDev('start preview runtime', () => run({ ...argv, needsUpdate, fileImportsMap })); }; export default dev;