| 293 | } |
| 294 | |
| 295 | async function editMode( |
| 296 | theme: string, |
| 297 | variables: string, |
| 298 | filePath: string |
| 299 | ): Promise<void> { |
| 300 | const nonce = token() |
| 301 | const port = await getPort({ |
| 302 | portRange: [5480, 5550], |
| 303 | host: 'localhost', |
| 304 | }) |
| 305 | const url = `${DEFAULT_THEME_EDITOR}/editor/?theme=${theme}&variables=${variables}&n=${nonce}&p=${port}` |
| 306 | const shortUrl = await shorten(url) |
| 307 | info(`Open the theme editor at: ${shortUrl}`) |
| 308 | const spinner = ora(`Edit in your browser.`).start() |
| 309 | await open(url) |
| 310 | let heartBeatTimeout: NodeJS.Timeout | undefined |
| 311 | let server: http.Server | undefined |
| 312 | let completedSuccessfully = false |
| 313 | let savedAt = 0 |
| 314 | await new Promise<void>((resolve) => { |
| 315 | server = http |
| 316 | .createServer(async (req, res) => { |
| 317 | const urlObj = parseUrl(req.url!, true) |
| 318 | const path = urlObj.pathname as string |
| 319 | const theme = urlObj.query.theme as string | undefined |
| 320 | const variables = urlObj.query.variables as string | undefined |
| 321 | const resData: ServerResponse = { |
| 322 | status: 'failed', |
| 323 | message: 'Incorrect token.', |
| 324 | } |
| 325 | if (path === `/${nonce}`) { |
| 326 | clearTimeout(heartBeatTimeout) |
| 327 | resData.status = 'success' |
| 328 | if (theme && typeof variables !== 'undefined') { |
| 329 | resData.message = 'updated' |
| 330 | const themeCode = await apiTheme( |
| 331 | theme, |
| 332 | DEFAULT_THEME_API, |
| 333 | variables, |
| 334 | filePath.endsWith('.ts'), |
| 335 | false, |
| 336 | spinner |
| 337 | ) |
| 338 | await writeFile(filePath, themeCode) |
| 339 | spinner.text = `⚡️ theme updated.` |
| 340 | savedAt = Date.now() |
| 341 | } else { |
| 342 | resData.message = 'listening' |
| 343 | if (Date.now() - savedAt > 5000) { |
| 344 | spinner.text = `waiting for${savedAt ? ' more' : ''} changes...` |
| 345 | } |
| 346 | heartBeatTimeout = setTimeout(() => { |
| 347 | completedSuccessfully = true |
| 348 | resolve() |
| 349 | }, 3000) |
| 350 | } |
| 351 | } |
| 352 | res.writeHead(resData.status === 'success' ? 200 : 400, { |