sessionUrl.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { randomUUID, type UUID } from 'crypto'
  2. import { validateUuid } from './uuid.js'
  3. export type ParsedSessionUrl = {
  4. sessionId: UUID
  5. ingressUrl: string | null
  6. isUrl: boolean
  7. jsonlFile: string | null
  8. isJsonlFile: boolean
  9. }
  10. /**
  11. * Parses a session resume identifier which can be either:
  12. * - A URL containing session ID (e.g., https://api.example.com/v1/session_ingress/session/550e8400-e29b-41d4-a716-446655440000)
  13. * - A plain session ID (UUID)
  14. *
  15. * @param resumeIdentifier - The URL or session ID to parse
  16. * @returns Parsed session information or null if invalid
  17. */
  18. export function parseSessionIdentifier(
  19. resumeIdentifier: string,
  20. ): ParsedSessionUrl | null {
  21. // Check for JSONL file path before URL parsing, since Windows absolute
  22. // paths (e.g., C:\path\file.jsonl) are parsed as valid URLs with C: as protocol
  23. if (resumeIdentifier.toLowerCase().endsWith('.jsonl')) {
  24. return {
  25. sessionId: randomUUID() as UUID,
  26. ingressUrl: null,
  27. isUrl: false,
  28. jsonlFile: resumeIdentifier,
  29. isJsonlFile: true,
  30. }
  31. }
  32. // Check if it's a plain UUID
  33. if (validateUuid(resumeIdentifier)) {
  34. return {
  35. sessionId: resumeIdentifier as UUID,
  36. ingressUrl: null,
  37. isUrl: false,
  38. jsonlFile: null,
  39. isJsonlFile: false,
  40. }
  41. }
  42. // Check if it's a URL
  43. try {
  44. const url = new URL(resumeIdentifier)
  45. // Use the entire URL as the ingress URL
  46. // Always generate a random session ID
  47. return {
  48. sessionId: randomUUID() as UUID,
  49. ingressUrl: url.href,
  50. isUrl: true,
  51. jsonlFile: null,
  52. isJsonlFile: false,
  53. }
  54. } catch {
  55. // Not a valid URL
  56. }
  57. return null
  58. }