158 lines
4.4 KiB
TypeScript
158 lines
4.4 KiB
TypeScript
/*
|
|
* Copyright 2025 coze-dev Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import {
|
|
uploadFileV2,
|
|
type EventPayloadMaps as BaseEventPayloadMap,
|
|
type UploaderInstance,
|
|
type UploadFileV2Param,
|
|
type FileItem,
|
|
} from '@coze-arch/bot-utils/upload-file-v2';
|
|
import { GetImageScene } from '@coze-arch/bot-api/playground_api';
|
|
import { PlaygroundApi } from '@coze-arch/bot-api';
|
|
|
|
export type EventPayloadMap = BaseEventPayloadMap & {
|
|
ready: boolean;
|
|
};
|
|
|
|
export interface UploadControllerProps {
|
|
controllerId: string;
|
|
fileList: File[];
|
|
userId: string;
|
|
onProgress?: (
|
|
event: EventPayloadMap['progress'],
|
|
controllerId: string,
|
|
) => void;
|
|
onComplete?: (
|
|
event: {
|
|
url: string;
|
|
uri: string;
|
|
}[],
|
|
controllerId: string,
|
|
) => void;
|
|
onUploadError?: (event: Error, controllerId: string) => void;
|
|
onUploaderReady?: (
|
|
event: EventPayloadMap['ready'],
|
|
controllerId: string,
|
|
) => void;
|
|
onStartUpload?: (
|
|
param: Parameters<Required<UploadFileV2Param>['onStartUpload']>[number],
|
|
controllerId: string,
|
|
) => void;
|
|
onGetUploadInstanceError?: (error: Error, controllerId: string) => void;
|
|
onGetTokenError?: (error: Error, controllerId: string) => void;
|
|
onAuditFailed?: (controllerId: string) => void;
|
|
}
|
|
|
|
const isImage = (file: File) => file.type.startsWith('image/');
|
|
|
|
export class UploadController {
|
|
controllerId: string;
|
|
abortController: AbortController;
|
|
uploader: UploaderInstance | null;
|
|
fileItemList: FileItem[];
|
|
|
|
constructor({
|
|
controllerId,
|
|
fileList,
|
|
userId,
|
|
onProgress,
|
|
onComplete,
|
|
onUploadError,
|
|
onUploaderReady,
|
|
onStartUpload,
|
|
onGetTokenError,
|
|
onGetUploadInstanceError,
|
|
onAuditFailed,
|
|
}: UploadControllerProps) {
|
|
this.fileItemList = fileList.map(file => ({
|
|
file,
|
|
fileType: isImage(file) ? 'image' : 'object',
|
|
}));
|
|
this.controllerId = controllerId;
|
|
this.abortController = new AbortController();
|
|
this.uploader = null;
|
|
|
|
uploadFileV2({
|
|
fileItemList: this.fileItemList,
|
|
userId,
|
|
signal: this.abortController.signal,
|
|
timeout: undefined,
|
|
onUploaderReady: uploader => {
|
|
this.uploader = uploader;
|
|
onUploaderReady?.(true, controllerId);
|
|
},
|
|
onProgress: event => onProgress?.(event, controllerId),
|
|
onUploadAllSuccess: async event => {
|
|
const uris = event.map(item => {
|
|
const uri = item.uploadResult.Uri;
|
|
if (!uri) {
|
|
throw new Error(`failed to get uri, item: ${item}`);
|
|
}
|
|
return uri;
|
|
});
|
|
try {
|
|
if (!uris || !uris.length) {
|
|
throw new Error(`upload success without uri, uploadID ${event}`);
|
|
}
|
|
|
|
const result = await PlaygroundApi.GetImagexShortUrl({
|
|
uris,
|
|
scene: GetImageScene.BackgroundImage,
|
|
});
|
|
|
|
const list = uris.map(item => {
|
|
if (!item) {
|
|
throw new Error(`failed to get url, uri: ${item}`);
|
|
}
|
|
return {
|
|
url: result.data?.url_info?.[item].url as string,
|
|
uri: item,
|
|
};
|
|
});
|
|
|
|
if (!list) {
|
|
throw new Error(`failed to get urls, list: ${list}`);
|
|
}
|
|
if (!list.some(i => i.url)) {
|
|
onAuditFailed?.(controllerId);
|
|
} else {
|
|
onComplete?.(list, controllerId);
|
|
}
|
|
} catch (e) {
|
|
onUploadError?.(
|
|
e instanceof Error ? e : new Error(String(e)),
|
|
controllerId,
|
|
);
|
|
}
|
|
},
|
|
onUploadError: event => onUploadError?.(event.extra.error, controllerId),
|
|
onStartUpload: event => onStartUpload?.(event, controllerId),
|
|
onGetUploadInstanceError: error =>
|
|
onGetUploadInstanceError?.(error, controllerId),
|
|
onGetTokenError: error => onGetTokenError?.(error, controllerId),
|
|
});
|
|
}
|
|
|
|
cancel = () => {
|
|
this.abortController.abort();
|
|
};
|
|
|
|
pause = () => {
|
|
this.uploader?.pause();
|
|
};
|
|
}
|