85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
export const GIT_SUMMARY_SCOPE = "current_project" as const;
|
|
|
|
export interface GitSummaryCounts {
|
|
changed: number;
|
|
staged: number;
|
|
dirty: number;
|
|
untracked: number;
|
|
conflicts: number;
|
|
}
|
|
|
|
export interface GitSummaryFile {
|
|
path: string;
|
|
repoPath: string;
|
|
status: string;
|
|
staged: boolean;
|
|
dirty: boolean;
|
|
untracked: boolean;
|
|
conflict: boolean;
|
|
}
|
|
|
|
export interface GitSummaryProjectScope {
|
|
scope: typeof GIT_SUMMARY_SCOPE;
|
|
cwd: string;
|
|
repoRoot: string | null;
|
|
repoRelativePath: string | null;
|
|
}
|
|
|
|
export interface GitSummaryRepoResponse {
|
|
kind: "repo";
|
|
project: GitSummaryProjectScope & {
|
|
repoRoot: string;
|
|
};
|
|
branch: string | null;
|
|
mainBranch: string | null;
|
|
hasChanges: boolean;
|
|
hasConflicts: boolean;
|
|
counts: GitSummaryCounts;
|
|
changedFiles: GitSummaryFile[];
|
|
truncatedFileCount: number;
|
|
}
|
|
|
|
export interface GitSummaryNotRepoResponse {
|
|
kind: "not_repo";
|
|
project: GitSummaryProjectScope;
|
|
message: string;
|
|
}
|
|
|
|
export type GitSummaryResponse =
|
|
| GitSummaryRepoResponse
|
|
| GitSummaryNotRepoResponse;
|
|
|
|
export function isGitSummaryResponse(
|
|
value: unknown,
|
|
): value is GitSummaryResponse {
|
|
if (!value || typeof value !== "object") return false;
|
|
|
|
const response = value as Partial<GitSummaryResponse>;
|
|
if (response.kind !== "repo" && response.kind !== "not_repo") return false;
|
|
if (!response.project || typeof response.project !== "object") return false;
|
|
if (response.project.scope !== GIT_SUMMARY_SCOPE) return false;
|
|
if (typeof response.project.cwd !== "string") return false;
|
|
|
|
if (response.kind === "not_repo") {
|
|
return typeof (response as GitSummaryNotRepoResponse).message === "string";
|
|
}
|
|
|
|
const repo = response as Partial<GitSummaryRepoResponse>;
|
|
if (typeof repo.project?.repoRoot !== "string") return false;
|
|
if (
|
|
typeof repo.hasChanges !== "boolean" ||
|
|
typeof repo.hasConflicts !== "boolean"
|
|
)
|
|
return false;
|
|
if (!repo.counts || typeof repo.counts !== "object") return false;
|
|
if (!Array.isArray(repo.changedFiles)) return false;
|
|
if (typeof repo.truncatedFileCount !== "number") return false;
|
|
|
|
return (
|
|
typeof repo.counts.changed === "number" &&
|
|
typeof repo.counts.staged === "number" &&
|
|
typeof repo.counts.dirty === "number" &&
|
|
typeof repo.counts.untracked === "number" &&
|
|
typeof repo.counts.conflicts === "number"
|
|
);
|
|
}
|