UNPKG

react-cosmos

Version:

Sandbox for developing and testing UI components in isolation

60 lines (59 loc) 2.51 kB
import launchEditor from '@skidding/launch-editor'; import fs from 'fs'; import open from 'open'; import path from 'path'; export const openFilePlugin = { name: 'openFile', devServer({ config, app }) { app.get('/_open', (req, res) => { const { filePath, line, column } = getReqQuery(req); if (!filePath) { res.status(400).send(`File path missing`); return; } const absFilePath = resolveFilePath(config.rootDir, filePath); if (!fs.existsSync(absFilePath)) { res.status(404).send(`File not found at path: ${absFilePath}`); return; } new Promise((resolve, reject) => { const file = `${absFilePath}:${line}:${column}`; launchEditor(file, (fileName, errorMsg) => reject(errorMsg)); // If launchEditor doesn't report error within 500ms we assume it worked setTimeout(resolve, 500); }) // Fall back to open in case launchEditor fails. launchEditor only works // when the editor app is already open, but is favorable because it can // open a code file on a specific line & column. .catch(err => open(absFilePath)) .catch(err => { console.log(err); res.status(500).send('Failed to open file'); }) .then(() => res.send()); }); }, }; function getReqQuery(req) { const { filePath, line, column } = req.query; if (typeof filePath !== 'string') throw new Error('filePath missing'); return { filePath, line: typeof line === 'string' ? parseInt(line, 10) : 1, column: typeof column === 'string' ? parseInt(column, 10) : 1, }; } function resolveFilePath(rootDir, filePath) { // This heuristic is needed because the open file endpoint is used for // multiple applications, which provide different file path types: // 1. Open fixture source button: Sends path relative to Cosmos rootDir // 2. react-error-overlay runtime error: Sends absolute path // 3. react-error-overlay compile error: Sends path relative to CWD if (path.isAbsolute(filePath)) { return filePath; } const cosmosRelPath = path.join(rootDir, filePath); const cwdRelPath = path.join(process.cwd(), filePath); return fs.existsSync(cosmosRelPath) ? cosmosRelPath : cwdRelPath; }