index.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { createRequire } from 'module'
  2. import { fileURLToPath } from 'url'
  3. import { dirname, join } from 'path'
  4. type UrlHandlerNapi = {
  5. waitForUrlEvent(timeoutMs: number): string | null
  6. }
  7. let cachedModule: UrlHandlerNapi | null = null
  8. function loadModule(): UrlHandlerNapi | null {
  9. if (cachedModule) {
  10. return cachedModule
  11. }
  12. // Only works on macOS
  13. if (process.platform !== 'darwin') {
  14. return null
  15. }
  16. try {
  17. if (process.env.URL_HANDLER_NODE_PATH) {
  18. // Bundled mode - use the env var path
  19. // eslint-disable-next-line @typescript-eslint/no-require-imports
  20. cachedModule = require(process.env.URL_HANDLER_NODE_PATH) as UrlHandlerNapi
  21. } else {
  22. // Dev mode - load from vendor directory
  23. const modulePath = join(
  24. dirname(fileURLToPath(import.meta.url)),
  25. '..',
  26. 'url-handler',
  27. `${process.arch}-darwin`,
  28. 'url-handler.node',
  29. )
  30. cachedModule = createRequire(import.meta.url)(modulePath) as UrlHandlerNapi
  31. }
  32. return cachedModule
  33. } catch {
  34. return null
  35. }
  36. }
  37. /**
  38. * Wait for a macOS URL event (Apple Event kAEGetURL).
  39. *
  40. * Initializes NSApplication, registers for the URL event, and pumps
  41. * the event loop for up to `timeoutMs` milliseconds.
  42. *
  43. * Returns the URL string if one was received, or null.
  44. * Only functional on macOS — returns null on other platforms.
  45. */
  46. export function waitForUrlEvent(timeoutMs: number): string | null {
  47. const mod = loadModule()
  48. if (!mod) {
  49. return null
  50. }
  51. return mod.waitForUrlEvent(timeoutMs)
  52. }