export type CNBCoreOptions = { token: string; /** * 对 cnb 界面操作定制模块功能时需要传入 cookie */ cookie?: string; cnb?: CNBCore; } & T; export type RequestOptions = { url?: string; method?: string; data?: Record; body?: any; params?: Record; headers?: Record; 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 { const defaultHeaders: Record = { '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({ url, ...REST }: RequestOptions): Promise { const fullUrl = this.makeUrl(url); return this.request({ url: fullUrl, method: 'GET', ...REST }); } post({ url, ...REST }: RequestOptions): Promise { const fullUrl = this.makeUrl(url); return this.request({ url: fullUrl, method: 'POST', ...REST }); } put({ url, ...REST }: RequestOptions): Promise { const fullUrl = this.makeUrl(url); return this.request({ url: fullUrl, method: 'PUT', ...REST }); } delete({ url, ...REST }: RequestOptions): Promise { const fullUrl = this.makeUrl(url); return this.request({ url: fullUrl, method: 'DELETE', ...REST }); } patch({ url, ...REST }: RequestOptions): Promise { 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 { return this.request({ url: data.url, method: 'PUT', body: data.content, headers: { 'Authorization': `Bearer ${data.token}`, 'Content-Type': 'application/octet-stream' } }); } } export type Result = { code: number; message: string; data: T };