bun 多文件上传会有问题

This commit is contained in:
2025-05-11 21:57:54 +08:00
parent cdbebe92d0
commit 4aec2bc231
9 changed files with 510 additions and 691 deletions

View File

@@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs';
import { storage } from '../query.ts';
import { storage, baseURL } from '../query.ts';
import { chalk } from '../chalk.ts';
type DownloadTask = {
@@ -20,6 +20,40 @@ export type Package = {
key?: string;
[key: string]: any;
};
type Options = {
check?: boolean;
returnContent?: boolean;
[key: string]: any;
};
export const fetchLink = async (url: string, opts?: Options) => {
const token = process.env.KEVISUAL_TOKEN || storage.getItem('token');
const fetchURL = new URL(url);
const check = opts?.check ?? false;
if (check) {
if (!url.startsWith(baseURL)) {
throw new Error('url must start with ' + baseURL);
}
}
if (token) {
fetchURL.searchParams.set('token', token);
}
fetchURL.searchParams.set('download', 'true');
const res = await fetch(fetchURL.toString());
const blob = await res.blob();
const type = blob.type;
let content: Buffer | undefined;
if (opts?.returnContent) {
content = Buffer.from(await blob.arrayBuffer());
}
const pathname = fetchURL.pathname;
const filename = pathname.split('/').pop();
return {
filename,
blob,
type,
content,
};
};
type InstallAppOpts = {
appDir?: string;
kevisualUrl?: string;
@@ -65,20 +99,12 @@ export const installApp = async (app: Package, opts: InstallAppOpts = {}) => {
fs.mkdirSync(dir, { recursive: true });
}
console.log('downloadUrwl', downloadUrl);
const token = process.env.KEVISUAL_TOKEN || storage.getItem('token');
const fetchURL = new URL(downloadUrl);
if (token) {
fetchURL.searchParams.set('token', token);
}
fetchURL.searchParams.set('download', 'true');
const res = await fetch(fetchURL.toString());
const blob = await res.blob();
const type = blob.type;
const { blob, type } = await fetchLink(downloadUrl);
if (type.includes('text/html')) {
const html = await blob.text();
if (html === 'fetchRes is error') {
console.log(chalk.red('fetchRes is error'));
break;
console.log(chalk.red('fetchRes is error'), '下载失败', downloadUrl);
throw new Error('fetchRes is error');
}
}
fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer()));

View File

@@ -0,0 +1,63 @@
import FormData from 'form-data';
export const handleResponse = async (err: any, res: any) => {
return new Promise((resolve) => {
if (err) {
console.error('Upload failed:', err);
resolve({ code: 500, message: err });
return;
}
// 处理服务器响应
let body = '';
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
try {
const res = JSON.parse(body);
resolve(res);
} catch (e) {
resolve({ code: 500, message: body });
}
});
});
};
export const getFormParams = (opts: UploadOptions, headers: any): FormData.SubmitOptions => {
const url = new URL(opts.url);
if (opts.token) {
// url.searchParams.append('token', opts.token);
}
const value: FormData.SubmitOptions = {
path: url.pathname + url.search,
host: url.hostname,
method: 'POST',
protocol: url.protocol === 'https:' ? 'https:' : 'http:',
port: url.port || (url.protocol === 'https:' ? 443 : 80),
headers: {
Authorization: 'Bearer ' + opts.token,
...headers,
},
};
return value;
};
type UploadOptions = {
url: string | URL;
file?: string | Buffer | File;
token?: string;
form?: FormData;
};
export const upload = (opts: UploadOptions): Promise<{ code?: number; message?: string; [key: string]: any }> => {
const form = opts?.form || new FormData();
if (!opts.form) {
if (typeof opts.file === 'string') {
form.append('file', Buffer.from(opts.file));
} else {
form.append('file', opts.file);
}
}
const headers = form.getHeaders();
return new Promise((resolve) => {
form.submit(getFormParams(opts, headers), (err, res) => {
handleResponse(err, res).then(resolve);
});
});
};