Files
cnb/src/cnb-core.ts
xiongxiao cedf3236b0 update
2026-01-13 17:04:43 +08:00

146 lines
4.3 KiB
TypeScript

export type CNBCoreOptions<T = {}> = {
token: string;
/**
* 对 cnb 界面操作定制模块功能时需要传入 cookie
*/
cookie?: string;
cnb?: CNBCore;
} & T;
export type RequestOptions = {
url?: string;
method?: string;
data?: Record<string, any>;
body?: any;
params?: Record<string, any>;
headers?: Record<string, any>;
useCookie?: boolean;
useOrigin?: boolean;
};
export class CNBCore {
baseURL = 'https://api.cnb.cool';
public token: string;
public cookie?: string;
constructor(options: CNBCoreOptions) {
this.token = options.token;
this.cookie = options.cookie;
if (options?.cnb) {
if (!options.token) {
this.token = options.cnb.token;
}
if (!options.cookie) {
this.cookie = options.cnb.cookie;
}
}
}
async request({ url, method = 'GET', data, params, headers, body, useCookie, useOrigin }: RequestOptions): Promise<any> {
const defaultHeaders: Record<string, string> = {
'Content-Type': 'application/json',
// 'Accept': 'application/json, application/vnd.cnb.api+json, application/vnd.cnb.web+json',
'Accept': 'application/json',
};
if (this.token) {
defaultHeaders['Authorization'] = `Bearer ${this.token}`;
}
if (params) {
const queryString = new URLSearchParams(params).toString();
url += `?${queryString}`;
defaultHeaders['Accept'] = 'application/json';
}
const _headers = { ...defaultHeaders, ...headers };
let _body = undefined;
if (data) {
_body = JSON.stringify(data);
}
if (body) {
_body = body;
}
if (!_headers.Authorization) {
delete _headers.Authorization;
}
if (useCookie) {
_headers['Cookie'] = this.cookie || "";
delete _headers.Authorization;
}
// console.log('Request URL:', url, data, _headers);
const response = await fetch(url || '', {
method,
headers: _headers,
body: _body,
});
const res = (data: any, message?: string, code?: number) => {
if (useOrigin) {
return data;
}
return {
code: code ?? 200,
message: message || 'success',
data,
};
}
if (!response.ok) {
const errorText = await response.text();
if (useOrigin)
throw new Error(`Request failed with status ${response.status}: ${errorText}`);
return res(null, `Request failed with status ${response.status}: ${errorText}`, response.status);
}
const contentType = response.headers.get('Content-Type');
if (contentType && contentType.includes('application/json')) {
const values = await response.json();
return res(values);
} else {
const text = await response.text();
return res(text);
}
}
makeUrl(url?: string): string {
if (url && url.startsWith('http')) {
return url;
}
return new URL(url || '', this.baseURL).toString();
}
get<T = any>({ url, ...REST }: RequestOptions): Promise<T> {
const fullUrl = this.makeUrl(url);
return this.request({ url: fullUrl, method: 'GET', ...REST });
}
post<T = any>({ url, ...REST }: RequestOptions): Promise<T> {
const fullUrl = this.makeUrl(url);
return this.request({ url: fullUrl, method: 'POST', ...REST });
}
put<T = any>({ url, ...REST }: RequestOptions): Promise<T> {
const fullUrl = this.makeUrl(url);
return this.request({ url: fullUrl, method: 'PUT', ...REST });
}
delete<T = any>({ url, ...REST }: RequestOptions): Promise<T> {
const fullUrl = this.makeUrl(url);
return this.request({ url: fullUrl, method: 'DELETE', ...REST });
}
patch<T = any>({ url, ...REST }: RequestOptions): Promise<T> {
const fullUrl = this.makeUrl(url);
return this.request({ url: fullUrl, method: 'PATCH', ...REST });
}
/**
* 通过 PUT 请求上传文件内容
* @param data 包含 URL、token 和文件内容
* @returns 上传结果
*/
async putFile(data: { url: string, token: string, content: string | Buffer }): Promise<any> {
return this.request({
url: data.url,
method: 'PUT',
body: data.content,
headers: {
'Authorization': `Bearer ${data.token}`,
'Content-Type': 'application/octet-stream'
}
});
}
}
export type Result<T = any> = {
code: number;
message: string;
data: T
};