import type { z } from "zod"; export type { Commit, CommitHeader, Commits, Diff, DiffContent, DiffFile, ChangesetWithDiff, ChangesetWithoutDiff, HunkLine, Hunks, }; import { array, boolean, discriminatedUnion, literal, number, object, record, string, union, } from "zod"; export { commitBlobSchema, commitHeaderSchema, commitSchema, commitsSchema, diffBlobSchema, diffSchema, }; const gitPersonSchema = object({ name: string(), email: string(), }); type CommitHeader = z.infer; const commitHeaderSchema = object({ id: string(), author: gitPersonSchema, summary: string(), description: string(), parents: array(string()), committer: gitPersonSchema.merge(object({ time: number() })), }); const diffBlobSchema = object({ binary: boolean(), content: string(), id: string(), }); export type DiffBlob = z.infer; const commitBlobSchema = object({ binary: boolean(), content: string(), }); export type CommitBlob = z.infer; type AdditionHunkLine = z.infer; const additionHunkLineSchema = object({ line: string(), lineNo: number(), type: literal("addition"), }); type DeletionHunkLine = z.infer; const deletionHunkLineSchema = object({ line: string(), lineNo: number(), type: literal("deletion"), }); type DiffFile = z.infer; const diffFileSchema = object({ oid: string(), mode: union([ literal("blob"), literal("blobExecutable"), literal("tree"), literal("link"), literal("commit"), ]), }); type ContextHunkLine = z.infer; const contextHunkLineSchema = object({ line: string(), lineNoNew: number(), lineNoOld: number(), type: literal("context"), }); type HunkLine = AdditionHunkLine | DeletionHunkLine | ContextHunkLine; const hunkLineSchema = union([ additionHunkLineSchema, deletionHunkLineSchema, contextHunkLineSchema, ]); type Hunks = z.infer; const changesetHunkSchema = object({ header: string(), lines: array(hunkLineSchema), }); type DiffContent = z.infer; const diffContentSchema = discriminatedUnion("type", [ object({ type: literal("plain"), stats: object({ additions: number(), deletions: number(), }), hunks: array(changesetHunkSchema), eof: union([ literal("noneMissing"), literal("oldMissing"), literal("newMissing"), literal("bothMissing"), ]), }), object({ type: literal("binary") }), object({ type: literal("empty") }), ]); const diffChangesetSchema = object({ path: string(), diff: diffContentSchema, }); const diffAddedChangesetSchema = diffChangesetSchema.merge( object({ state: literal("added"), new: diffFileSchema }), ); const diffDeletedChangesetSchema = diffChangesetSchema.merge( object({ state: literal("deleted"), old: diffFileSchema }), ); const diffModifiedChangesetSchema = diffChangesetSchema.merge( object({ state: literal("modified"), new: diffFileSchema, old: diffFileSchema, }), ); const diffCopiedChangesetSchema = object({ state: literal("copied"), newPath: string(), oldPath: string(), }); const diffCopiedWithModificationsChangesetSchema = diffCopiedChangesetSchema.merge( object({ old: diffFileSchema, new: diffFileSchema, diff: diffContentSchema, }), ); const diffMovedChangesetSchema = object({ state: literal("moved"), newPath: string(), oldPath: string(), current: diffFileSchema, }); const diffMovedWithModificationsChangesetSchema = diffMovedChangesetSchema .omit({ current: true }) .merge( object({ old: diffFileSchema, new: diffFileSchema, diff: diffContentSchema, }), ); type Diff = z.infer; type ChangesetWithDiff = z.infer; type ChangesetWithoutDiff = z.infer; const changesetWithDiffSchema = union([ diffAddedChangesetSchema, diffDeletedChangesetSchema, diffModifiedChangesetSchema, diffMovedWithModificationsChangesetSchema, diffCopiedWithModificationsChangesetSchema, ]); const changesetWithoutDiffSchema = union([ diffMovedChangesetSchema, diffCopiedChangesetSchema, ]); const diffSchema = object({ files: array( union([ diffAddedChangesetSchema, diffDeletedChangesetSchema, diffModifiedChangesetSchema, diffMovedChangesetSchema, diffMovedWithModificationsChangesetSchema, diffCopiedChangesetSchema, diffCopiedWithModificationsChangesetSchema, ]), ), stats: object({ filesChanged: number(), insertions: number(), deletions: number(), }), }); type Commit = z.infer; const commitSchema = object({ commit: commitHeaderSchema, diff: diffSchema, branches: array(string()), files: record(string(), commitBlobSchema), }); type Commits = z.infer; const commitsSchema = array(commitHeaderSchema);