File size: 2,991 Bytes
21dd449
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import type { CredentialsParams, RepoDesignation } from "../types/public";
import { checkCredentials } from "../utils/checkCredentials";
import { toRepoId } from "../utils/toRepoId";
import { HUB_URL } from "../consts";
import { createApiError } from "../error";

export interface LfsPathInfo {
	oid: string;
	size: number;
	pointerSize: number;
}

export interface CommitInfo {
	id: string;
	title: string;
	date: Date;
}

export interface SecurityFileStatus {
	status: string;
}

export interface PathInfo {
	path: string;
	type: string;
	oid: string;
	size: number;
	/**
	 * Only defined when path is LFS pointer
	 */
	lfs?: LfsPathInfo;
	lastCommit?: CommitInfo;
	securityFileStatus?: SecurityFileStatus;
}

// Define the overloaded signatures
export function pathsInfo(
	params: {
		repo: RepoDesignation;
		paths: string[];
		expand: true; // if expand true
		revision?: string;
		hubUrl?: string;
		/**
		 * Custom fetch function to use instead of the default one, for example to use a proxy or edit headers.
		 */
		fetch?: typeof fetch;
	} & Partial<CredentialsParams>
): Promise<(PathInfo & { lastCommit: CommitInfo; securityFileStatus: SecurityFileStatus })[]>;
export function pathsInfo(
	params: {
		repo: RepoDesignation;
		paths: string[];
		expand?: boolean;
		revision?: string;
		hubUrl?: string;
		/**
		 * Custom fetch function to use instead of the default one, for example to use a proxy or edit headers.
		 */
		fetch?: typeof fetch;
	} & Partial<CredentialsParams>
): Promise<PathInfo[]>;

export async function pathsInfo(
	params: {
		repo: RepoDesignation;
		paths: string[];
		expand?: boolean;
		revision?: string;
		hubUrl?: string;
		/**
		 * Custom fetch function to use instead of the default one, for example to use a proxy or edit headers.
		 */
		fetch?: typeof fetch;
	} & Partial<CredentialsParams>
): Promise<PathInfo[]> {
	const accessToken = checkCredentials(params);
	const repoId = toRepoId(params.repo);

	const hubUrl = params.hubUrl ?? HUB_URL;

	const url = `${hubUrl}/api/${repoId.type}s/${repoId.name}/paths-info/${encodeURIComponent(
		params.revision ?? "main"
	)}`;

	const resp = await (params.fetch ?? fetch)(url, {
		method: "POST",
		headers: {
			...(accessToken && {
				Authorization: `Bearer ${accessToken}`,
			}),
			Accept: "application/json",
			"Content-Type": "application/json",
		},
		body: JSON.stringify({
			paths: params.paths,
			expand: params.expand,
		}),
	});

	if (!resp.ok) {
		throw await createApiError(resp);
	}

	const json: unknown = await resp.json();
	if (!Array.isArray(json)) throw new Error("malformed response: expected array");

	return json.map((item: PathInfo) => ({
		path: item.path,
		lfs: item.lfs,
		type: item.type,
		oid: item.oid,
		size: item.size,
		// expand fields
		securityFileStatus: item.securityFileStatus,
		lastCommit: item.lastCommit
			? {
					date: new Date(item.lastCommit.date),
					title: item.lastCommit.title,
					id: item.lastCommit.id,
			  }
			: undefined,
	}));
}