add yandex disk pro
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
//////////////////////////////////////////////
|
||||
// all types
|
||||
// https://yandex.com/dev/disk-api/doc/en/reference/response-objects
|
||||
//////////////////////////////////////////////
|
||||
|
||||
export interface Link {
|
||||
href: string;
|
||||
method: string;
|
||||
templated: boolean;
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
antivirus_status?: string;
|
||||
public_key?: string;
|
||||
_embedded?: ResourceList;
|
||||
name?: string;
|
||||
created?: string;
|
||||
custom_properties?: Record<string, string>;
|
||||
public_url?: string;
|
||||
origin_path?: string;
|
||||
modified?: string;
|
||||
path?: string;
|
||||
md5?: string;
|
||||
sha256?: string;
|
||||
file?: string;
|
||||
type?: "dir" | "file";
|
||||
mime_type?: string;
|
||||
size?: number;
|
||||
exif?: Record<any, any>;
|
||||
}
|
||||
|
||||
type SortType = string;
|
||||
|
||||
export interface ResourceList {
|
||||
sort?: SortType;
|
||||
public_key?: string;
|
||||
items?: Resource[];
|
||||
path?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
total?: number;
|
||||
}
|
||||
|
||||
export interface FilesResourceList {
|
||||
items: Resource[];
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface LastUploadedResourceList {
|
||||
items: Resource[];
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface PublicResourcesList {
|
||||
items: Resource[];
|
||||
type: "dir" | "file";
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export interface Disk {
|
||||
trash_size: number;
|
||||
total_space: number;
|
||||
used_space: number;
|
||||
system_folders: {
|
||||
applications: string;
|
||||
downloads: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Operation {
|
||||
status: "success" | "failed" | "in-progress";
|
||||
}
|
||||
|
||||
export interface ErrorResponse {
|
||||
error: string;
|
||||
description: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// api
|
||||
// https://yandex.com/dev/disk-api/doc/en/
|
||||
//////////////////////////////////////////////
|
||||
|
||||
export class YandexApi {
|
||||
accessToken: string;
|
||||
apiVersion: number;
|
||||
host: string;
|
||||
constructor(accessToken: string) {
|
||||
this.accessToken = accessToken;
|
||||
this.apiVersion = 1;
|
||||
this.host = `https://cloud-api.yandex.net`;
|
||||
}
|
||||
|
||||
async _api(
|
||||
method: string,
|
||||
endPoint: string,
|
||||
returnType: "json" | "arrayBuffer" | "raw",
|
||||
queryParams?: Record<string, string>,
|
||||
body?: any,
|
||||
requestContentType?: string
|
||||
) {
|
||||
let p = "";
|
||||
if (queryParams !== undefined) {
|
||||
p = `?${new URLSearchParams(queryParams)}`;
|
||||
}
|
||||
|
||||
const fullUrl = `${this.host}/v${this.apiVersion}/${endPoint}${p}`;
|
||||
// console.debug(`method: ${method}, fullUrl: ${fullUrl}`)
|
||||
const headers: HeadersInit = {
|
||||
Authorization: `OAuth ${this.accessToken}`,
|
||||
};
|
||||
if (requestContentType !== undefined) {
|
||||
headers["Content-Type"] = requestContentType;
|
||||
}
|
||||
const r = await fetch(fullUrl, {
|
||||
method: method,
|
||||
headers: headers,
|
||||
body: body,
|
||||
});
|
||||
// console.debug(r)
|
||||
|
||||
if (r.status >= 200 && r.status < 300) {
|
||||
if (returnType === "json") {
|
||||
return await r.json();
|
||||
}
|
||||
if (returnType === "arrayBuffer") {
|
||||
return await r.arrayBuffer();
|
||||
}
|
||||
if (returnType === "raw") {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
throw Error(JSON.stringify((await r.json()) as ErrorResponse));
|
||||
}
|
||||
}
|
||||
|
||||
async disk() {
|
||||
return (await this._api("GET", "disk/", "json")) as Disk;
|
||||
}
|
||||
|
||||
async diskResources(
|
||||
path: string,
|
||||
fields?: string[],
|
||||
limit?: number,
|
||||
offset?: number
|
||||
) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
};
|
||||
if (fields !== undefined) {
|
||||
params["fields"] = fields.join(",");
|
||||
}
|
||||
if (limit !== undefined) {
|
||||
params["limit"] = `${limit}`;
|
||||
}
|
||||
if (offset !== undefined) {
|
||||
params["offset"] = `${offset}`;
|
||||
}
|
||||
|
||||
return (await this._api(
|
||||
"GET",
|
||||
"disk/resources",
|
||||
"json",
|
||||
params
|
||||
)) as Resource;
|
||||
}
|
||||
|
||||
async diskResourcesFiles(fields?: string[], limit?: number, offset?: number) {
|
||||
const params: Record<string, string> = {};
|
||||
if (fields !== undefined) {
|
||||
params["fields"] = fields.join(",");
|
||||
}
|
||||
if (limit !== undefined) {
|
||||
params["limit"] = `${limit}`;
|
||||
}
|
||||
if (offset !== undefined) {
|
||||
params["offset"] = `${offset}`;
|
||||
}
|
||||
return (await this._api(
|
||||
"GET",
|
||||
"disk/resources/files",
|
||||
"json",
|
||||
params
|
||||
)) as FilesResourceList;
|
||||
}
|
||||
|
||||
async diskResourcesPatch(
|
||||
path: string,
|
||||
custom_properties: Record<string, string | null>,
|
||||
fields?: string[]
|
||||
) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
};
|
||||
if (fields !== undefined) {
|
||||
params["fields"] = fields.join(",");
|
||||
}
|
||||
return (await this._api(
|
||||
"PATCH",
|
||||
"disk/resources",
|
||||
"json",
|
||||
params,
|
||||
JSON.stringify({
|
||||
custom_properties: custom_properties,
|
||||
}),
|
||||
"application/json"
|
||||
)) as Resource;
|
||||
}
|
||||
|
||||
async diskResoucesUpload(
|
||||
path: string,
|
||||
content: ArrayBuffer,
|
||||
overwrite?: boolean
|
||||
) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
overwrite: `${overwrite ?? false}`,
|
||||
};
|
||||
const link = (await this._api(
|
||||
"GET",
|
||||
"disk/resources/upload",
|
||||
"json",
|
||||
params
|
||||
)) as Link;
|
||||
|
||||
if (link.templated) {
|
||||
throw Error(
|
||||
`do not know how to deal with upload link with templated: ${JSON.stringify(
|
||||
link
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
const rsp = await fetch(link.href, {
|
||||
method: link.method,
|
||||
body: content,
|
||||
});
|
||||
if (rsp.status === 200 || rsp.status === 201 || rsp.status === 202) {
|
||||
return true;
|
||||
} else {
|
||||
throw Error(`upload failed. status=${rsp.status}, link=${link.href}`);
|
||||
}
|
||||
}
|
||||
|
||||
async diskResoucesDownload(path: string) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
};
|
||||
const link = (await this._api(
|
||||
"GET",
|
||||
"disk/resources/download",
|
||||
"json",
|
||||
params
|
||||
)) as Link;
|
||||
|
||||
if (link.templated) {
|
||||
throw Error(
|
||||
`do not know how to deal with download link with templated: ${JSON.stringify(
|
||||
link
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
const rsp = await fetch(link.href, {
|
||||
method: link.method,
|
||||
});
|
||||
if (rsp.status === 200 || rsp.status === 201 || rsp.status === 202) {
|
||||
return await rsp.arrayBuffer();
|
||||
} else {
|
||||
throw Error(`download failed. status=${rsp.status}, link=${link.href}`);
|
||||
}
|
||||
}
|
||||
|
||||
async diskResourcesDelete(path: string, permanently?: boolean) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
permanently: `${permanently ?? false}`,
|
||||
};
|
||||
const rsp = (await this._api(
|
||||
"DELETE",
|
||||
"disk/resources",
|
||||
"raw",
|
||||
params
|
||||
)) as Response;
|
||||
|
||||
if (rsp.status === 204) {
|
||||
return;
|
||||
}
|
||||
if (rsp.status === 202) {
|
||||
return (await rsp.json()) as Link;
|
||||
}
|
||||
throw Error(`do not know how to deal with delete response ${rsp}`);
|
||||
}
|
||||
|
||||
async diskResourcesPut(path: string, fields?: string[]) {
|
||||
const params: Record<string, string> = {
|
||||
path: path,
|
||||
};
|
||||
if (fields !== undefined) {
|
||||
params["fields"] = fields.join(",");
|
||||
}
|
||||
return (await this._api("PUT", "disk/resources", "json", params)) as Link;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user