@seaverse/utils-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Type definitions for SeaVerse Utils SDK
3
+ */
4
+ /**
5
+ * Utils SDK 配置选项
6
+ */
7
+ export interface UtilsClientOptions {
8
+ /**
9
+ * Bearer Token(必需)
10
+ */
11
+ token: string;
12
+ /**
13
+ * API 基础 URL(可选)
14
+ * @default 'https://resource.seaverse.ai'
15
+ */
16
+ baseURL?: string;
17
+ /**
18
+ * 请求超时时间(毫秒)
19
+ * @default 60000
20
+ */
21
+ timeout?: number;
22
+ /**
23
+ * 图片压缩配置(可选)
24
+ */
25
+ compress?: CompressionConfig;
26
+ }
27
+ /**
28
+ * 图片压缩配置
29
+ */
30
+ export interface CompressionConfig {
31
+ /**
32
+ * 是否启用压缩
33
+ * @default true
34
+ */
35
+ enabled?: boolean;
36
+ /**
37
+ * 最大宽度(像素)
38
+ * @default 1080
39
+ */
40
+ maxWidth?: number;
41
+ /**
42
+ * 最大高度(像素)
43
+ * @default 1080
44
+ */
45
+ maxHeight?: number;
46
+ /**
47
+ * 压缩质量 (0-1)
48
+ * @default 0.8
49
+ */
50
+ quality?: number;
51
+ }
52
+ /**
53
+ * 上传选项
54
+ */
55
+ export interface UploadOptions {
56
+ /**
57
+ * 进度回调函数
58
+ */
59
+ onProgress?: (progress: UploadProgress) => void;
60
+ /**
61
+ * 是否压缩(覆盖全局配置)
62
+ */
63
+ compress?: boolean;
64
+ }
65
+ /**
66
+ * 上传进度信息
67
+ */
68
+ export interface UploadProgress {
69
+ /**
70
+ * 已上传字节数
71
+ */
72
+ loaded: number;
73
+ /**
74
+ * 总字节数
75
+ */
76
+ total: number;
77
+ /**
78
+ * 上传进度百分比 (0-100)
79
+ */
80
+ percent: number;
81
+ /**
82
+ * 当前上传阶段
83
+ */
84
+ stage: 'preparing' | 'compressing' | 'uploading' | 'complete';
85
+ /**
86
+ * 上传速度(字节/秒)
87
+ */
88
+ speed?: number;
89
+ /**
90
+ * 预计剩余时间(秒)
91
+ */
92
+ remainingTime?: number;
93
+ }
94
+ /**
95
+ * 预签名 URL 请求
96
+ */
97
+ export interface PresignUploadRequest {
98
+ /**
99
+ * 文件 MIME 类型
100
+ */
101
+ content_type: string;
102
+ }
103
+ /**
104
+ * 预签名 URL 响应数据
105
+ */
106
+ export interface PresignUploadData {
107
+ /**
108
+ * 上传 URL(用于 PUT 文件)
109
+ */
110
+ upload_url: string;
111
+ /**
112
+ * 文件存储路径
113
+ */
114
+ object_path: string;
115
+ /**
116
+ * CDN 访问 URL
117
+ */
118
+ cdn_url: string;
119
+ /**
120
+ * 过期时间(RFC3339 格式)
121
+ */
122
+ expires_at: string;
123
+ }
124
+ /**
125
+ * 预签名 URL 响应
126
+ */
127
+ export interface PresignUploadResponse {
128
+ /**
129
+ * 状态码
130
+ */
131
+ code: number;
132
+ /**
133
+ * 消息
134
+ */
135
+ message: string;
136
+ /**
137
+ * 数据
138
+ */
139
+ data: PresignUploadData;
140
+ }
141
+ /**
142
+ * 上传结果
143
+ */
144
+ export interface UploadResult {
145
+ /**
146
+ * 文件名
147
+ */
148
+ fileName: string;
149
+ /**
150
+ * 原始文件名
151
+ */
152
+ originalFileName: string;
153
+ /**
154
+ * CDN 访问 URL
155
+ */
156
+ cdnUrl: string;
157
+ /**
158
+ * 存储路径
159
+ */
160
+ objectPath: string;
161
+ /**
162
+ * 文件大小(字节)
163
+ */
164
+ fileSize: number;
165
+ /**
166
+ * 原始文件大小(字节)
167
+ */
168
+ originalSize: number;
169
+ /**
170
+ * 是否被压缩
171
+ */
172
+ compressed: boolean;
173
+ /**
174
+ * MIME 类型
175
+ */
176
+ contentType: string;
177
+ /**
178
+ * 上传耗时(毫秒)
179
+ */
180
+ duration: number;
181
+ /**
182
+ * 过期时间
183
+ */
184
+ expiresAt: string;
185
+ }
186
+ /**
187
+ * 验证结果
188
+ */
189
+ export interface ValidationResult {
190
+ /**
191
+ * 是否有效
192
+ */
193
+ valid: boolean;
194
+ /**
195
+ * 错误信息列表
196
+ */
197
+ errors: string[];
198
+ }
199
+ /**
200
+ * 验证规则
201
+ */
202
+ export interface ValidationRules {
203
+ /**
204
+ * 最大文件大小(字节)
205
+ * @default 100 * 1024 * 1024 (100MB)
206
+ */
207
+ maxSize?: number;
208
+ /**
209
+ * 允许的 MIME 类型列表
210
+ * @example ['image/jpeg', 'image/png', 'application/pdf']
211
+ */
212
+ allowedTypes?: string[];
213
+ }
214
+ /**
215
+ * 上传错误类
216
+ */
217
+ export declare class UtilsAPIError extends Error {
218
+ code: string;
219
+ statusCode?: number | undefined;
220
+ response?: any | undefined;
221
+ constructor(message: string, code: string, statusCode?: number | undefined, response?: any | undefined);
222
+ }
223
+ /**
224
+ * 错误码枚举
225
+ */
226
+ export declare const ErrorCode: {
227
+ readonly FILE_TOO_LARGE: "FILE_TOO_LARGE";
228
+ readonly INVALID_FILE_TYPE: "INVALID_FILE_TYPE";
229
+ readonly PRESIGNED_URL_FAILED: "PRESIGNED_URL_FAILED";
230
+ readonly UPLOAD_FAILED: "UPLOAD_FAILED";
231
+ readonly COMPRESSION_FAILED: "COMPRESSION_FAILED";
232
+ readonly NETWORK_ERROR: "NETWORK_ERROR";
233
+ readonly TIMEOUT: "TIMEOUT";
234
+ readonly VALIDATION_FAILED: "VALIDATION_FAILED";
235
+ };
236
+ export type ErrorCodeType = typeof ErrorCode[keyof typeof ErrorCode];
237
+ /**
238
+ * 压缩结果
239
+ */
240
+ export interface CompressionResult {
241
+ /**
242
+ * 原始文件
243
+ */
244
+ originalFile: File;
245
+ /**
246
+ * 压缩后的文件
247
+ */
248
+ compressedFile: File;
249
+ /**
250
+ * 原始大小(字节)
251
+ */
252
+ originalSize: number;
253
+ /**
254
+ * 压缩后大小(字节)
255
+ */
256
+ compressedSize: number;
257
+ /**
258
+ * 压缩率 (0-1)
259
+ */
260
+ compressionRatio: number;
261
+ /**
262
+ * 图片宽度
263
+ */
264
+ width: number;
265
+ /**
266
+ * 图片高度
267
+ */
268
+ height: number;
269
+ }
270
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
package/dist/models.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Type definitions for SeaVerse Utils SDK
3
+ */
4
+ // ============ Errors ============
5
+ /**
6
+ * 上传错误类
7
+ */
8
+ export class UtilsAPIError extends Error {
9
+ constructor(message, code, statusCode, response) {
10
+ super(message);
11
+ this.code = code;
12
+ this.statusCode = statusCode;
13
+ this.response = response;
14
+ this.name = 'UtilsAPIError';
15
+ }
16
+ }
17
+ /**
18
+ * 错误码枚举
19
+ */
20
+ export const ErrorCode = {
21
+ FILE_TOO_LARGE: 'FILE_TOO_LARGE',
22
+ INVALID_FILE_TYPE: 'INVALID_FILE_TYPE',
23
+ PRESIGNED_URL_FAILED: 'PRESIGNED_URL_FAILED',
24
+ UPLOAD_FAILED: 'UPLOAD_FAILED',
25
+ COMPRESSION_FAILED: 'COMPRESSION_FAILED',
26
+ NETWORK_ERROR: 'NETWORK_ERROR',
27
+ TIMEOUT: 'TIMEOUT',
28
+ VALIDATION_FAILED: 'VALIDATION_FAILED',
29
+ };
30
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkQH,mCAAmC;AAEnC;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YACE,OAAe,EACR,IAAY,EACZ,UAAmB,EACnB,QAAc;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAS;QACnB,aAAQ,GAAR,QAAQ,CAAM;QAGrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,cAAc,EAAE,gBAAgB;IAChC,iBAAiB,EAAE,mBAAmB;IACtC,oBAAoB,EAAE,sBAAsB;IAC5C,aAAa,EAAE,eAAe;IAC9B,kBAAkB,EAAE,oBAAoB;IACxC,aAAa,EAAE,eAAe;IAC9B,OAAO,EAAE,SAAS;IAClB,iBAAiB,EAAE,mBAAmB;CAC9B,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Utility functions for SeaVerse Utils SDK
3
+ */
4
+ import { ValidationResult, ValidationRules, UtilsAPIError } from './models.js';
5
+ /**
6
+ * 验证文件
7
+ * @param file - 要验证的文件
8
+ * @param rules - 验证规则
9
+ * @returns 验证结果
10
+ */
11
+ export declare function validateFile(file: File, rules?: ValidationRules): ValidationResult;
12
+ /**
13
+ * 格式化字节数为可读字符串
14
+ * @param bytes - 字节数
15
+ * @param decimals - 小数位数
16
+ * @returns 格式化后的字符串
17
+ */
18
+ export declare function formatBytes(bytes: number, decimals?: number): string;
19
+ /**
20
+ * 检查文件是否为图片
21
+ * @param file - 文件对象
22
+ * @returns 是否为图片
23
+ */
24
+ export declare function isImageFile(file: File): boolean;
25
+ /**
26
+ * 获取文件扩展名
27
+ * @param fileName - 文件名
28
+ * @returns 扩展名(不包含点)
29
+ */
30
+ export declare function getFileExtension(fileName: string): string;
31
+ /**
32
+ * 生成唯一 ID
33
+ * @returns 唯一 ID
34
+ */
35
+ export declare function generateId(): string;
36
+ /**
37
+ * 创建上传错误
38
+ * @param code - 错误码
39
+ * @param message - 错误消息
40
+ * @param statusCode - HTTP 状态码
41
+ * @param response - 响应数据
42
+ * @returns UtilsAPIError 实例
43
+ */
44
+ export declare function createUploadError(code: string, message: string, statusCode?: number, response?: any): UtilsAPIError;
45
+ /**
46
+ * 处理 Axios 错误
47
+ * @param error - Axios 错误对象
48
+ * @returns UtilsAPIError 实例
49
+ */
50
+ export declare function handleAxiosError(error: any): UtilsAPIError;
51
+ /**
52
+ * 进度追踪器
53
+ */
54
+ export declare class ProgressTracker {
55
+ private startTime;
56
+ private lastUpdateTime;
57
+ private lastLoadedBytes;
58
+ constructor();
59
+ /**
60
+ * 计算上传速度和剩余时间
61
+ * @param loaded - 已上传字节数
62
+ * @param total - 总字节数
63
+ * @returns 速度和剩余时间
64
+ */
65
+ calculate(loaded: number, total: number): {
66
+ speed: number;
67
+ remainingTime: number;
68
+ };
69
+ /**
70
+ * 获取总耗时(毫秒)
71
+ */
72
+ getTotalDuration(): number;
73
+ }
74
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,aAAa,EAEd,MAAM,aAAa,CAAC;AAIrB;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,KAAK,CAAC,EAAE,eAAe,GACtB,gBAAgB,CA+BlB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,MAAM,CAUvE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,GAAG,GACb,aAAa,CAEf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,aAAa,CA6B1D;AAID;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAS;;IAQhC;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAoBlF;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG3B"}
package/dist/utils.js ADDED
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Utility functions for SeaVerse Utils SDK
3
+ */
4
+ import { UtilsAPIError, ErrorCode, } from './models.js';
5
+ // ============ File Validation ============
6
+ /**
7
+ * 验证文件
8
+ * @param file - 要验证的文件
9
+ * @param rules - 验证规则
10
+ * @returns 验证结果
11
+ */
12
+ export function validateFile(file, rules) {
13
+ const errors = [];
14
+ // 默认规则
15
+ const defaultRules = {
16
+ maxSize: 100 * 1024 * 1024, // 100MB
17
+ allowedTypes: undefined,
18
+ };
19
+ const finalRules = { ...defaultRules, ...rules };
20
+ // 验证文件大小
21
+ if (finalRules.maxSize && file.size > finalRules.maxSize) {
22
+ errors.push(`文件大小超过限制: ${formatBytes(file.size)} > ${formatBytes(finalRules.maxSize)}`);
23
+ }
24
+ // 验证文件类型
25
+ if (finalRules.allowedTypes && finalRules.allowedTypes.length > 0) {
26
+ if (!finalRules.allowedTypes.includes(file.type)) {
27
+ errors.push(`不支持的文件类型: ${file.type}。允许的类型: ${finalRules.allowedTypes.join(', ')}`);
28
+ }
29
+ }
30
+ return {
31
+ valid: errors.length === 0,
32
+ errors,
33
+ };
34
+ }
35
+ /**
36
+ * 格式化字节数为可读字符串
37
+ * @param bytes - 字节数
38
+ * @param decimals - 小数位数
39
+ * @returns 格式化后的字符串
40
+ */
41
+ export function formatBytes(bytes, decimals = 2) {
42
+ if (bytes === 0)
43
+ return '0 Bytes';
44
+ const k = 1024;
45
+ const dm = decimals < 0 ? 0 : decimals;
46
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
47
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
48
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
49
+ }
50
+ /**
51
+ * 检查文件是否为图片
52
+ * @param file - 文件对象
53
+ * @returns 是否为图片
54
+ */
55
+ export function isImageFile(file) {
56
+ return file.type.startsWith('image/');
57
+ }
58
+ /**
59
+ * 获取文件扩展名
60
+ * @param fileName - 文件名
61
+ * @returns 扩展名(不包含点)
62
+ */
63
+ export function getFileExtension(fileName) {
64
+ const parts = fileName.split('.');
65
+ return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : '';
66
+ }
67
+ /**
68
+ * 生成唯一 ID
69
+ * @returns 唯一 ID
70
+ */
71
+ export function generateId() {
72
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
73
+ }
74
+ // ============ Error Handling ============
75
+ /**
76
+ * 创建上传错误
77
+ * @param code - 错误码
78
+ * @param message - 错误消息
79
+ * @param statusCode - HTTP 状态码
80
+ * @param response - 响应数据
81
+ * @returns UtilsAPIError 实例
82
+ */
83
+ export function createUploadError(code, message, statusCode, response) {
84
+ return new UtilsAPIError(message, code, statusCode, response);
85
+ }
86
+ /**
87
+ * 处理 Axios 错误
88
+ * @param error - Axios 错误对象
89
+ * @returns UtilsAPIError 实例
90
+ */
91
+ export function handleAxiosError(error) {
92
+ if (error.response) {
93
+ // 服务器返回错误响应
94
+ const data = error.response.data;
95
+ const message = data?.message || error.message;
96
+ const code = data?.code || error.response.status;
97
+ return createUploadError(`HTTP_${code}`, message, error.response.status, data);
98
+ }
99
+ else if (error.request) {
100
+ // 请求已发送但没有收到响应
101
+ return createUploadError(ErrorCode.NETWORK_ERROR, '网络错误,请检查网络连接', 0, error.request);
102
+ }
103
+ else {
104
+ // 其他错误
105
+ return createUploadError('UNKNOWN_ERROR', error.message || '未知错误', 0);
106
+ }
107
+ }
108
+ // ============ Progress Calculation ============
109
+ /**
110
+ * 进度追踪器
111
+ */
112
+ export class ProgressTracker {
113
+ constructor() {
114
+ this.startTime = Date.now();
115
+ this.lastUpdateTime = this.startTime;
116
+ this.lastLoadedBytes = 0;
117
+ }
118
+ /**
119
+ * 计算上传速度和剩余时间
120
+ * @param loaded - 已上传字节数
121
+ * @param total - 总字节数
122
+ * @returns 速度和剩余时间
123
+ */
124
+ calculate(loaded, total) {
125
+ const now = Date.now();
126
+ const timeDelta = now - this.lastUpdateTime;
127
+ if (timeDelta === 0) {
128
+ return { speed: 0, remainingTime: 0 };
129
+ }
130
+ const bytesDelta = loaded - this.lastLoadedBytes;
131
+ const speed = (bytesDelta / timeDelta) * 1000; // 字节/秒
132
+ const remainingBytes = total - loaded;
133
+ const remainingTime = speed > 0 ? remainingBytes / speed : 0;
134
+ this.lastUpdateTime = now;
135
+ this.lastLoadedBytes = loaded;
136
+ return { speed, remainingTime };
137
+ }
138
+ /**
139
+ * 获取总耗时(毫秒)
140
+ */
141
+ getTotalDuration() {
142
+ return Date.now() - this.startTime;
143
+ }
144
+ }
145
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@seaverse/utils-sdk",
3
+ "version": "0.1.0",
4
+ "description": "SeaVerse Utils SDK - 通用工具集合,包含文件上传、图片压缩等功能",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs",
13
+ "types": "./dist/index.d.ts"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "dev": "tsc --watch",
23
+ "clean": "rm -rf dist",
24
+ "typecheck": "tsc --noEmit",
25
+ "prepublishOnly": "npm run clean && npm run build"
26
+ },
27
+ "keywords": [
28
+ "seaverse",
29
+ "utils",
30
+ "upload",
31
+ "sdk",
32
+ "api",
33
+ "image-compression"
34
+ ],
35
+ "author": "SeaVerse Team <support@seaverse.com>",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/seaverseai/sv-sdk.git",
40
+ "directory": "packages/utils-sdk"
41
+ },
42
+ "dependencies": {
43
+ "axios": "^1.6.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^20.0.0",
47
+ "typescript": "^5.3.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }