apply-patch-file.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { normalize, type ViewDiff } from "./session-diff"
  2. type Kind = "add" | "update" | "delete" | "move"
  3. type Raw = {
  4. filePath?: string
  5. relativePath?: string
  6. type?: Kind
  7. patch?: string
  8. diff?: string
  9. before?: string
  10. after?: string
  11. additions?: number
  12. deletions?: number
  13. movePath?: string
  14. }
  15. export type ApplyPatchFile = {
  16. filePath: string
  17. relativePath: string
  18. type: Kind
  19. additions: number
  20. deletions: number
  21. movePath?: string
  22. view: ViewDiff
  23. }
  24. function kind(value: unknown) {
  25. if (value === "add" || value === "update" || value === "delete" || value === "move") return value
  26. }
  27. function status(type: Kind): "added" | "deleted" | "modified" {
  28. if (type === "add") return "added"
  29. if (type === "delete") return "deleted"
  30. return "modified"
  31. }
  32. export function patchFile(raw: unknown): ApplyPatchFile | undefined {
  33. if (!raw || typeof raw !== "object") return
  34. const value = raw as Raw
  35. const type = kind(value.type)
  36. const filePath = typeof value.filePath === "string" ? value.filePath : undefined
  37. const relativePath = typeof value.relativePath === "string" ? value.relativePath : filePath
  38. const patch = typeof value.patch === "string" ? value.patch : typeof value.diff === "string" ? value.diff : undefined
  39. const before = typeof value.before === "string" ? value.before : undefined
  40. const after = typeof value.after === "string" ? value.after : undefined
  41. if (!type || !filePath || !relativePath) return
  42. if (!patch && before === undefined && after === undefined) return
  43. const additions = typeof value.additions === "number" ? value.additions : 0
  44. const deletions = typeof value.deletions === "number" ? value.deletions : 0
  45. const movePath = typeof value.movePath === "string" ? value.movePath : undefined
  46. return {
  47. filePath,
  48. relativePath,
  49. type,
  50. additions,
  51. deletions,
  52. movePath,
  53. view: normalize({
  54. file: relativePath,
  55. patch,
  56. before,
  57. after,
  58. additions,
  59. deletions,
  60. status: status(type),
  61. }),
  62. }
  63. }
  64. export function patchFiles(raw: unknown) {
  65. if (!Array.isArray(raw)) return []
  66. return raw.map(patchFile).filter((file): file is ApplyPatchFile => !!file)
  67. }