ScriptRunner.mjs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { ScriptLog } from '../../app/src/models/ScriptLog.mjs'
  2. import Settings from '@overleaf/settings'
  3. const UNKNOWN = 'unknown'
  4. async function beforeScriptExecution(canonicalName, vars, scriptPath) {
  5. let log = new ScriptLog({
  6. canonicalName,
  7. filePathAtVersion: scriptPath,
  8. podName: process.env.OL_POD_NAME ?? UNKNOWN,
  9. username: process.env.OL_USERNAME ?? UNKNOWN,
  10. imageVersion: process.env.OL_IMAGE_VERSION ?? UNKNOWN,
  11. vars,
  12. })
  13. log = await log.save()
  14. // Print Script Log link if ran by a user
  15. if (process.env.OL_USERNAME) {
  16. console.log(
  17. '\n==================================' +
  18. '\n✨ Your script is running!' +
  19. '\n📊 Track progress at:' +
  20. `\n${Settings.adminUrl}/admin/script-log/${log._id}` +
  21. '\n==================================\n'
  22. )
  23. }
  24. return log._id
  25. }
  26. async function afterScriptExecution(logId, status) {
  27. await ScriptLog.findByIdAndUpdate(logId, { status, endTime: new Date() })
  28. }
  29. /**
  30. * @param {(trackProgress: (progress: string) => Promise<void>) => Promise<any>} main - Main function for the script
  31. * @param {Object} vars - Variables to be used in the script
  32. * @param {string} canonicalName - The canonical name of the script, default to filename
  33. * @param {string} scriptPath - The file path of the script, default to process.argv[1]
  34. * @returns {Promise<void>}
  35. * @async
  36. */
  37. export async function scriptRunner(
  38. main,
  39. vars = {},
  40. canonicalName = process.argv[1].split('/').pop().split('.')[0],
  41. scriptPath = process.argv[1]
  42. ) {
  43. const isSaaS = Boolean(Settings.overleaf)
  44. if (!isSaaS) {
  45. await main(async message => {
  46. console.warn(message)
  47. })
  48. return
  49. }
  50. const logId = await beforeScriptExecution(canonicalName, vars, scriptPath)
  51. async function trackProgress(message) {
  52. try {
  53. console.warn(message)
  54. await ScriptLog.findByIdAndUpdate(logId, {
  55. $push: {
  56. progressLogs: {
  57. timestamp: new Date(),
  58. message,
  59. },
  60. },
  61. })
  62. } catch (error) {
  63. console.error('Error tracking progress:', error)
  64. }
  65. }
  66. try {
  67. await main(trackProgress)
  68. } catch (error) {
  69. await afterScriptExecution(logId, 'error')
  70. throw error
  71. }
  72. await afterScriptExecution(logId, 'success')
  73. }