/** * 腾讯云智能媒资托管服务API - SMH客户端 * 提供集中管理和网络请求重试功能 * * @class SMHClient */ import { Configuration } from '../configuration'; import { Uploader } from '../loaders/Uploader'; import { Downloader } from '../loaders/Downloader'; import type { UploadOptions } from '../loaders/types'; import type { DownloadOptions, UrlDownloadOptions } from '../loaders/types'; /** * Token 续期回调函数类型 * * 当 API 请求因 accessToken 过期(403 InvalidAccessToken)失败时, * SDK 会调用此回调,等待业务方返回新的 accessToken。 * * @returns 新的 accessToken 字符串,返回后 SDK 会自动更新并重试原请求 * @throws 如果抛出异常或返回空字符串,SDK 不会重试,直接将原始错误抛给调用方 */ export type OnTokenRefresh = () => Promise; type CreateUploadTaskOptions = Omit & { libraryId?: string; spaceId?: string; accessToken?: string; }; type CreateDownloadTaskOptions = Omit & { libraryId?: string; spaceId?: string; accessToken?: string; }; type UrlDownloadClientOptions = Omit & { libraryId?: string; spaceId?: string; accessToken?: string; }; import { BatchApi } from '../apis/batch-api'; import { DirectoryApi } from '../apis/directory-api'; import { FavoriteApi } from '../apis/favorite-api'; import { FileApi } from '../apis/file-api'; import { HistoryApi } from '../apis/history-api'; import { HlsApi } from '../apis/hls-api'; import { QuotaApi } from '../apis/quota-api'; import { RecentApi } from '../apis/recent-api'; import { RecycledApi } from '../apis/recycled-api'; import { SearchApi } from '../apis/search-api'; import { SpaceApi } from '../apis/space-api'; import { TaskApi } from '../apis/task-api'; import { TokenApi } from '../apis/token-api'; import { ShareApi } from '../apis/share-api'; import { UsageApi } from '../apis/usage-api'; export interface SMHClientOptions { basePath?: string; maxRetries?: number; retryDelay?: number; timeout?: number; baseOptions?: any; libraryId?: string; spaceId?: string; accessToken?: string; /** * Token 续期回调(可选) * * 设置后,当 API 请求因 accessToken 过期失败时,SDK 会自动调用此回调获取新 token 并重试。 * 未设置时行为不变:直接抛出错误,由调用方自行处理。 * * @example * ```ts * const client = new SMHClient({ * // ... * onTokenRefresh: async () => { * const res = await myBackend.refreshToken(); * return res.accessToken; * } * }); * ``` */ onTokenRefresh?: OnTokenRefresh; } type MakeOptional = Omit & Partial>; type WrapApiMethods = { [K in keyof T]: T[K] extends (requestParameters: infer P, ...args: infer A) => infer R ? P extends { libraryId: string; spaceId: string; accessToken?: string; } ? (requestParameters: MakeOptional, ...args: A) => R : P extends { libraryId: string; accessToken?: string; } ? (requestParameters: MakeOptional, ...args: A) => R : P extends { libraryId: string; spaceId: string; } ? (requestParameters: MakeOptional, ...args: A) => R : P extends { libraryId: string; } ? (requestParameters: MakeOptional, ...args: A) => R : T[K] : T[K]; }; export declare class SMHClient { private configuration; private axiosInstance; private defaultLibraryId?; private defaultSpaceId?; private defaultAccessToken?; private onTokenRefresh?; private refreshingPromise; private _batch; private _directory; private _favorite; private _file; private _history; private _hls; private _quota; private _recent; private _recycled; private _search; private _share; private _space; private _task; private _token; private _usage; readonly batch: WrapApiMethods; readonly directory: WrapApiMethods; readonly favorite: WrapApiMethods; readonly file: WrapApiMethods; readonly history: WrapApiMethods; readonly hls: WrapApiMethods; readonly quota: WrapApiMethods; readonly recent: WrapApiMethods; readonly recycled: WrapApiMethods; readonly search: WrapApiMethods; readonly share: WrapApiMethods; readonly space: WrapApiMethods; readonly task: WrapApiMethods; readonly token: WrapApiMethods; readonly usage: WrapApiMethods; constructor(options?: SMHClientOptions); /** * 设置重试拦截器 */ private setupRetryInterceptor; /** * 更新配置 */ updateConfig(options: Partial): void; /** * 获取当前配置 */ getConfig(): Configuration; /** * 设置访问令牌 */ setAccessToken(token: string): void; /** * 清除访问令牌 */ clearAccessToken(): void; /** * 更新默认的 libraryId */ setDefaultLibraryId(libraryId: string): void; /** * 更新默认的 spaceId */ setDefaultSpaceId(spaceId: string): void; /** * 更新默认的 accessToken */ setDefaultAccessToken(accessToken: string): void; /** * 获取默认的 libraryId */ getDefaultLibraryId(): string | undefined; /** * 获取默认的 spaceId */ getDefaultSpaceId(): string | undefined; /** * 获取默认的 accessToken */ getDefaultAccessToken(): string | undefined; /** * 包装API实例,自动注入 libraryId 和 accessToken */ private wrapApi; /** * 创建上传任务 * 自动注入 libraryId、spaceId、accessToken 和 configuration * @returns Uploader 实例 */ createUploadTask(options: CreateUploadTaskOptions): Uploader; /** * 创建下载任务 * 自动注入 libraryId、spaceId、accessToken 和 configuration * @returns Downloader 实例 */ createDownloadTask(options: CreateDownloadTaskOptions): Downloader; /** * 通过浏览器 URL 方式下载文件(推荐用于 Web 端) * 获取 cosUrl 后通过 标签触发浏览器原生下载, * 不需要将文件内容加载到内存中,适合任意大小的文件。 * * @example * ```typescript * await client.downloadByUrl({ * filePath: 'docs/file.pdf', * fileName: 'my-file.pdf' // 可选,自定义保存文件名 * }); * ``` */ downloadByUrl(options: UrlDownloadClientOptions): Promise; /** * 设置或更新 Token 续期回调(运行时动态设置) * * @example * ```ts * client.setOnTokenRefresh(async () => { * const res = await myBackend.refreshToken(); * return res.accessToken; * }); * ``` */ setOnTokenRefresh(callback: OnTokenRefresh | undefined): void; /** * 判断错误是否为 token 过期 */ private isTokenExpiredError; /** * 执行 token 续期(带防抖,并发请求只触发一次) */ private doTokenRefresh; } export {};