koishi-plugin-aka-ai-generator 0.7.6 → 0.7.8

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.
package/lib/index.js CHANGED
@@ -914,7 +914,7 @@ var YunwuVideoProvider = class {
914
914
  } else {
915
915
  duration = 25;
916
916
  }
917
- const requestBody = {
917
+ const buildRequestBody = /* @__PURE__ */ __name((watermark) => ({
918
918
  images: [`data:${mimeType};base64,${imageBase64}`],
919
919
  model: this.config.modelId,
920
920
  orientation,
@@ -922,29 +922,42 @@ var YunwuVideoProvider = class {
922
922
  size: "large",
923
923
  // 高清1080p
924
924
  duration,
925
- watermark: true,
926
- // 默认优先无水印,出错会兜底到有水印
925
+ watermark,
926
+ // 优先无水印;若接口不允许则降级有水印
927
927
  private: false
928
928
  // 默认视频会发布
929
- };
929
+ }), "buildRequestBody");
930
930
  logger?.info("提交视频生成任务", {
931
931
  model: this.config.modelId,
932
932
  promptLength: prompt.length,
933
- duration: requestBody.duration,
934
- orientation: requestBody.orientation
933
+ duration,
934
+ orientation
935
935
  });
936
- const response = await ctx.http.post(
937
- `${this.config.apiBase}/v1/video/create`,
938
- requestBody,
939
- {
940
- headers: {
941
- "Authorization": `Bearer ${this.config.apiKey}`,
942
- "Content-Type": "application/json",
943
- "Accept": "application/json"
944
- },
945
- timeout: this.config.apiTimeout * 1e3
946
- }
947
- );
936
+ const doCreate = /* @__PURE__ */ __name(async (watermark) => {
937
+ return await ctx.http.post(
938
+ `${this.config.apiBase}/v1/video/create`,
939
+ buildRequestBody(watermark),
940
+ {
941
+ headers: {
942
+ "Authorization": `Bearer ${this.config.apiKey}`,
943
+ "Content-Type": "application/json",
944
+ "Accept": "application/json"
945
+ },
946
+ timeout: this.config.apiTimeout * 1e3
947
+ }
948
+ );
949
+ }, "doCreate");
950
+ let response;
951
+ try {
952
+ response = await doCreate(false);
953
+ } catch (e) {
954
+ logger?.warn("无水印创建任务失败,尝试有水印", { error: sanitizeError(e) });
955
+ response = await doCreate(true);
956
+ }
957
+ if (response?.error || response?.status && response.status >= 400) {
958
+ logger?.warn("无水印创建任务返回错误,尝试有水印", { status: response?.status, error: response?.error, response: response?.data });
959
+ response = await doCreate(true);
960
+ }
948
961
  if (response.error) {
949
962
  const errorMsg = response.error.message || response.error.type || "创建任务失败";
950
963
  throw new Error(sanitizeString(errorMsg));
@@ -1172,7 +1185,9 @@ var UserManager = class {
1172
1185
  usersCache = null;
1173
1186
  pendingVideoCache = null;
1174
1187
  activeTasks = /* @__PURE__ */ new Map();
1175
- // userId -> requestId
1188
+ // userId -> requestId (图像任务锁)
1189
+ activeVideoTasks = /* @__PURE__ */ new Map();
1190
+ // userId -> requestId (视频任务锁,独立于图像任务)
1176
1191
  rateLimitMap = /* @__PURE__ */ new Map();
1177
1192
  // userId -> timestamps
1178
1193
  securityBlockMap = /* @__PURE__ */ new Map();
@@ -1191,6 +1206,7 @@ var UserManager = class {
1191
1206
  }
1192
1207
  }
1193
1208
  // --- 任务管理 ---
1209
+ // 图像任务锁(原有逻辑保持不变)
1194
1210
  startTask(userId) {
1195
1211
  if (this.activeTasks.has(userId)) return false;
1196
1212
  this.activeTasks.set(userId, "processing");
@@ -1202,6 +1218,18 @@ var UserManager = class {
1202
1218
  isTaskActive(userId) {
1203
1219
  return this.activeTasks.has(userId);
1204
1220
  }
1221
+ // 视频任务锁(独立于图像任务,不影响图像生成)
1222
+ startVideoTask(userId) {
1223
+ if (this.activeVideoTasks.has(userId)) return false;
1224
+ this.activeVideoTasks.set(userId, "processing");
1225
+ return true;
1226
+ }
1227
+ endVideoTask(userId) {
1228
+ this.activeVideoTasks.delete(userId);
1229
+ }
1230
+ isVideoTaskActive(userId) {
1231
+ return this.activeVideoTasks.has(userId);
1232
+ }
1205
1233
  // --- 权限管理 ---
1206
1234
  isAdmin(userId, config) {
1207
1235
  return config.adminUsers && config.adminUsers.includes(userId);
@@ -1324,6 +1352,61 @@ var UserManager = class {
1324
1352
  await this.savePendingVideoTasksInternal();
1325
1353
  });
1326
1354
  }
1355
+ /**
1356
+ * 获取某个用户最近一次未扣费的待结算视频任务
1357
+ */
1358
+ async getLatestPendingVideoTaskForUser(userId) {
1359
+ const data = await this.loadPendingVideoTasks();
1360
+ const tasks = Object.values(data.tasks).filter((t) => t.userId === userId && !t.charged).sort((a, b) => {
1361
+ const ta = Date.parse(a.createdAt || "") || 0;
1362
+ const tb = Date.parse(b.createdAt || "") || 0;
1363
+ return tb - ta;
1364
+ });
1365
+ return tasks[0] || null;
1366
+ }
1367
+ /**
1368
+ * 统计某个用户未扣费的待结算视频任务数量
1369
+ */
1370
+ async countPendingVideoTasksForUser(userId) {
1371
+ const data = await this.loadPendingVideoTasks();
1372
+ return Object.values(data.tasks).filter((t) => t.userId === userId && !t.charged).length;
1373
+ }
1374
+ /**
1375
+ * 列出某个用户所有未扣费的待结算视频任务
1376
+ */
1377
+ async listPendingVideoTasksForUser(userId) {
1378
+ const data = await this.loadPendingVideoTasks();
1379
+ return Object.values(data.tasks).filter((t) => t.userId === userId && !t.charged).sort((a, b) => {
1380
+ const ta = Date.parse(a.createdAt || "") || 0;
1381
+ const tb = Date.parse(b.createdAt || "") || 0;
1382
+ return tb - ta;
1383
+ });
1384
+ }
1385
+ /**
1386
+ * 添加待结算视频任务,并检查上限(默认max=1)
1387
+ * @returns {Promise<{success: boolean, message?: string}>} 成功返回 {success: true},失败返回 {success: false, message: '错误信息'}
1388
+ */
1389
+ async addPendingVideoTaskWithLimit(task, max = 1) {
1390
+ await this.loadPendingVideoTasks();
1391
+ return await this.pendingLock.acquire(async () => {
1392
+ if (!this.pendingVideoCache) {
1393
+ this.pendingVideoCache = { version: "1.0.0", lastUpdate: (/* @__PURE__ */ new Date()).toISOString(), tasks: {} };
1394
+ }
1395
+ const currentCount = Object.values(this.pendingVideoCache.tasks).filter((t) => t.userId === task.userId && !t.charged).length;
1396
+ if (currentCount >= max) {
1397
+ return {
1398
+ success: false,
1399
+ message: `您当前已有 ${currentCount} 个视频正在生成中(最多允许 ${max} 个),请先使用"查询视频"查看进度或等待完成`
1400
+ };
1401
+ }
1402
+ if (this.pendingVideoCache.tasks[task.taskId]) {
1403
+ return { success: true };
1404
+ }
1405
+ this.pendingVideoCache.tasks[task.taskId] = task;
1406
+ await this.savePendingVideoTasksInternal();
1407
+ return { success: true };
1408
+ });
1409
+ }
1327
1410
  // 获取特定用户数据
1328
1411
  async getUserData(userId, userName) {
1329
1412
  await this.loadUsersData();
@@ -2314,8 +2397,8 @@ ${infoParts.join("\n")}`;
2314
2397
  if (!limitCheck.allowed) {
2315
2398
  return limitCheck.message;
2316
2399
  }
2317
- if (!userManager.startTask(userId)) {
2318
- return "您有一个任务正在进行中,请等待完成";
2400
+ if (!userManager.startVideoTask(userId)) {
2401
+ return "您有一个视频任务正在进行中,请等待完成";
2319
2402
  }
2320
2403
  let createdTaskId = null;
2321
2404
  try {
@@ -2350,15 +2433,6 @@ ${infoParts.join("\n")}`;
2350
2433
  if (!validRatios.includes(ratio)) {
2351
2434
  return `宽高比必须是以下之一: ${validRatios.join(", ")}`;
2352
2435
  }
2353
- await session.send(
2354
- `🎬 开始生成视频...
2355
- 📝 描述:${prompt}
2356
- ⏱️ 时长:${duration}秒
2357
- 📐 宽高比:${ratio}
2358
- ⚠️ 预计需要 1-3 分钟,请耐心等待
2359
- 💡 提示:生成过程中可继续使用其他功能`
2360
- );
2361
- const startTime = Date.now();
2362
2436
  const taskId = await videoProvider.createVideoTask(
2363
2437
  prompt,
2364
2438
  imageUrls[0],
@@ -2368,7 +2442,7 @@ ${infoParts.join("\n")}`;
2368
2442
  }
2369
2443
  );
2370
2444
  createdTaskId = taskId;
2371
- await userManager.addPendingVideoTask({
2445
+ const addResult = await userManager.addPendingVideoTaskWithLimit({
2372
2446
  taskId,
2373
2447
  userId,
2374
2448
  userName,
@@ -2376,64 +2450,119 @@ ${infoParts.join("\n")}`;
2376
2450
  credits: videoCredits,
2377
2451
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2378
2452
  charged: false
2379
- });
2380
- await new Promise((resolve) => setTimeout(resolve, 3e3));
2381
- const videoUrl = await videoProvider.waitForVideo(taskId, config.videoMaxWaitTime);
2382
- await session.send(import_koishi2.h.video(videoUrl));
2383
- await recordUserUsage(session, "图生视频", videoCredits, false);
2384
- await userManager.markPendingVideoTaskCharged(taskId);
2385
- await userManager.deletePendingVideoTask(taskId);
2386
- const totalTime = Math.floor((Date.now() - startTime) / 1e3);
2387
- await session.send(`✅ 视频生成完成!(耗时 ${totalTime} 秒)`);
2388
- } catch (error) {
2389
- logger.error("视频生成失败", { userId, error: sanitizeError(error) });
2390
- const errorMsg = error.message || "";
2391
- if (errorMsg.includes("任务ID:")) {
2392
- return errorMsg;
2453
+ }, 1);
2454
+ if (!addResult.success) {
2455
+ try {
2456
+ await userManager.deletePendingVideoTask(taskId);
2457
+ } catch {
2458
+ }
2459
+ return addResult.message || "队列已满,请先查询已有任务";
2393
2460
  }
2394
- try {
2395
- if (createdTaskId) await userManager.deletePendingVideoTask(createdTaskId);
2396
- } catch {
2461
+ await session.send("开始生成视频...");
2462
+ } catch (error) {
2463
+ logger.error("视频生成任务提交失败", { userId, error: sanitizeError(error) });
2464
+ if (createdTaskId) {
2465
+ try {
2466
+ await userManager.deletePendingVideoTask(createdTaskId);
2467
+ } catch {
2468
+ }
2397
2469
  }
2398
- return `视频生成失败:${sanitizeString(errorMsg)}`;
2470
+ const errorMsg = error.message || "";
2471
+ return `视频生成任务提交失败:${sanitizeString(errorMsg)}`;
2399
2472
  } finally {
2400
- userManager.endTask(userId);
2473
+ userManager.endVideoTask(userId);
2401
2474
  }
2402
2475
  });
2403
2476
  }
2404
2477
  if (config.enableVideoGeneration && videoProvider) {
2405
- ctx.command("查询视频 <taskId:string>", "根据任务ID查询视频生成状态").action(async ({ session }, taskId) => {
2478
+ ctx.command("查询视频 [taskId:string]", "查询视频生成状态(不传任务ID则查询自己所有待生成任务)").action(async ({ session }, taskId) => {
2406
2479
  if (!session?.userId) return "会话无效";
2407
- if (!taskId || !taskId.trim()) {
2408
- return "请提供任务ID,格式:查询视频 <任务ID>";
2409
- }
2410
- try {
2411
- await session.send("🔍 正在查询视频生成状态...");
2412
- const status = await videoProvider.queryTaskStatus(taskId.trim());
2413
- if (status.status === "completed" && status.videoUrl) {
2414
- const trimmedTaskId = taskId.trim();
2480
+ const trimmedTaskId = (taskId || "").trim();
2481
+ if (trimmedTaskId) {
2482
+ try {
2483
+ await session.send("正在查询视频生成状态...");
2484
+ const status = await videoProvider.queryTaskStatus(trimmedTaskId);
2415
2485
  const pending = await userManager.getPendingVideoTask(trimmedTaskId);
2416
2486
  if (pending && pending.userId && pending.userId !== session.userId) {
2417
2487
  return "该任务ID不属于当前用户,无法查询";
2418
2488
  }
2419
- await session.send(import_koishi2.h.video(status.videoUrl));
2420
- if (pending && !pending.charged) {
2421
- await recordUserUsage(session, pending.commandName, pending.credits, false);
2422
- await userManager.markPendingVideoTaskCharged(trimmedTaskId);
2423
- await userManager.deletePendingVideoTask(trimmedTaskId);
2489
+ if (status.status === "completed" && status.videoUrl) {
2490
+ await session.send(import_koishi2.h.video(status.videoUrl));
2491
+ if (pending && !pending.charged) {
2492
+ await recordUserUsage(session, pending.commandName, pending.credits, false);
2493
+ await userManager.markPendingVideoTaskCharged(trimmedTaskId);
2494
+ await userManager.deletePendingVideoTask(trimmedTaskId);
2495
+ }
2496
+ return "视频生成完成!";
2497
+ } else if (status.status === "processing" || status.status === "pending") {
2498
+ const progressText = status.progress ? `(进度:${status.progress}%)` : "";
2499
+ return `视频正在生成中${progressText},请稍后再次查询`;
2500
+ } else if (status.status === "failed") {
2501
+ if (pending && !pending.charged) {
2502
+ await userManager.deletePendingVideoTask(trimmedTaskId);
2503
+ }
2504
+ return `视频生成失败:${status.error || "未知错误"}`;
2505
+ } else {
2506
+ return `❓ 未知状态:${status.status}`;
2507
+ }
2508
+ } catch (error) {
2509
+ logger.error("查询视频任务失败", { taskId: trimmedTaskId, error: sanitizeError(error) });
2510
+ return `查询失败:${sanitizeString(error.message)}`;
2511
+ }
2512
+ }
2513
+ try {
2514
+ const pendingTasks = await userManager.listPendingVideoTasksForUser(session.userId);
2515
+ if (pendingTasks.length === 0) {
2516
+ return "你当前没有可查询的待生成视频任务";
2517
+ }
2518
+ await session.send(`正在查询 ${pendingTasks.length} 个视频任务状态...`);
2519
+ let completedCount = 0;
2520
+ let processingCount = 0;
2521
+ let failedCount = 0;
2522
+ const messages = [];
2523
+ for (const task of pendingTasks) {
2524
+ try {
2525
+ const status = await videoProvider.queryTaskStatus(task.taskId);
2526
+ if (status.status === "completed" && status.videoUrl) {
2527
+ await session.send(import_koishi2.h.video(status.videoUrl));
2528
+ if (!task.charged) {
2529
+ await recordUserUsage(session, task.commandName, task.credits, false);
2530
+ await userManager.markPendingVideoTaskCharged(task.taskId);
2531
+ await userManager.deletePendingVideoTask(task.taskId);
2532
+ }
2533
+ completedCount++;
2534
+ messages.push(`任务 ${task.taskId.substring(0, 20)}... 已完成`);
2535
+ } else if (status.status === "processing" || status.status === "pending") {
2536
+ processingCount++;
2537
+ const progressText = status.progress ? `(进度:${status.progress}%)` : "";
2538
+ messages.push(`任务 ${task.taskId.substring(0, 20)}... 生成中${progressText}`);
2539
+ } else if (status.status === "failed") {
2540
+ if (!task.charged) {
2541
+ await userManager.deletePendingVideoTask(task.taskId);
2542
+ }
2543
+ failedCount++;
2544
+ messages.push(`任务 ${task.taskId.substring(0, 20)}... 失败:${status.error || "未知错误"}`);
2545
+ } else {
2546
+ messages.push(`❓ 任务 ${task.taskId.substring(0, 20)}... 状态:${status.status}`);
2547
+ }
2548
+ } catch (error) {
2549
+ logger.error("查询单个视频任务失败", { taskId: task.taskId, error: sanitizeError(error) });
2550
+ messages.push(`⚠️ 任务 ${task.taskId.substring(0, 20)}... 查询失败:${sanitizeString(error.message)}`);
2424
2551
  }
2425
- return "✅ 视频已生成完成!";
2426
- } else if (status.status === "processing" || status.status === "pending") {
2427
- const progressText = status.progress ? `(进度:${status.progress}%)` : "";
2428
- return `⏳ 视频正在生成中${progressText},请稍后再次查询
2429
- 任务ID:${taskId}`;
2430
- } else if (status.status === "failed") {
2431
- return `❌ 视频生成失败:${status.error || "未知错误"}`;
2432
- } else {
2433
- return `❓ 未知状态:${status.status}`;
2434
2552
  }
2553
+ let summary = `查询结果汇总:
2554
+ `;
2555
+ if (completedCount > 0) summary += `已完成:${completedCount} 个
2556
+ `;
2557
+ if (processingCount > 0) summary += `生成中:${processingCount} 个
2558
+ `;
2559
+ if (failedCount > 0) summary += `失败:${failedCount} 个
2560
+ `;
2561
+ summary += `
2562
+ ${messages.join("\n")}`;
2563
+ return summary;
2435
2564
  } catch (error) {
2436
- logger.error("查询视频任务失败", { taskId, error: sanitizeError(error) });
2565
+ logger.error("查询视频任务列表失败", { userId: session.userId, error: sanitizeError(error) });
2437
2566
  return `查询失败:${sanitizeString(error.message)}`;
2438
2567
  }
2439
2568
  });
@@ -2455,8 +2584,8 @@ ${infoParts.join("\n")}`;
2455
2584
  if (!limitCheck.allowed) {
2456
2585
  return limitCheck.message;
2457
2586
  }
2458
- if (!userManager.startTask(userId)) {
2459
- return "您有一个任务正在进行中,请等待完成";
2587
+ if (!userManager.startVideoTask(userId)) {
2588
+ return "您有一个视频任务正在进行中,请等待完成";
2460
2589
  }
2461
2590
  let createdTaskId = null;
2462
2591
  try {
@@ -2472,11 +2601,6 @@ ${infoParts.join("\n")}`;
2472
2601
  if (extraText) {
2473
2602
  finalPrompt += " - " + extraText;
2474
2603
  }
2475
- await session.send(
2476
- `🎬 开始生成视频(${style.commandName})...
2477
- 📝 描述:${finalPrompt}
2478
- ⏱️ 预计需要 1-3 分钟`
2479
- );
2480
2604
  const taskId = await videoProvider.createVideoTask(
2481
2605
  finalPrompt,
2482
2606
  imageUrls[0],
@@ -2486,7 +2610,7 @@ ${infoParts.join("\n")}`;
2486
2610
  }
2487
2611
  );
2488
2612
  createdTaskId = taskId;
2489
- await userManager.addPendingVideoTask({
2613
+ const addResult = await userManager.addPendingVideoTaskWithLimit({
2490
2614
  taskId,
2491
2615
  userId,
2492
2616
  userName,
@@ -2494,27 +2618,27 @@ ${infoParts.join("\n")}`;
2494
2618
  credits: videoCredits,
2495
2619
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2496
2620
  charged: false
2497
- });
2498
- await new Promise((resolve) => setTimeout(resolve, 3e3));
2499
- const videoUrl = await videoProvider.waitForVideo(taskId, config.videoMaxWaitTime);
2500
- await session.send(import_koishi2.h.video(videoUrl));
2501
- await recordUserUsage(session, style.commandName, videoCredits, false);
2502
- await userManager.markPendingVideoTaskCharged(taskId);
2503
- await userManager.deletePendingVideoTask(taskId);
2504
- await session.send(`✅ 视频生成完成!`);
2505
- } catch (error) {
2506
- logger.error("视频风格转换失败", { userId, style: style.commandName, error: sanitizeError(error) });
2507
- const errorMsg = error.message || "";
2508
- if (errorMsg.includes("任务ID:")) {
2509
- return errorMsg;
2621
+ }, 1);
2622
+ if (!addResult.success) {
2623
+ try {
2624
+ await userManager.deletePendingVideoTask(taskId);
2625
+ } catch {
2626
+ }
2627
+ return addResult.message || "队列已满,请先查询已有任务";
2510
2628
  }
2511
- try {
2512
- if (createdTaskId) await userManager.deletePendingVideoTask(createdTaskId);
2513
- } catch {
2629
+ await session.send(`开始生成视频(${style.commandName})...`);
2630
+ } catch (error) {
2631
+ logger.error("视频风格转换任务提交失败", { userId, style: style.commandName, error: sanitizeError(error) });
2632
+ if (createdTaskId) {
2633
+ try {
2634
+ await userManager.deletePendingVideoTask(createdTaskId);
2635
+ } catch {
2636
+ }
2514
2637
  }
2515
- return `视频生成失败:${sanitizeString(errorMsg)}`;
2638
+ const errorMsg = error.message || "";
2639
+ return `视频生成任务提交失败:${sanitizeString(errorMsg)}`;
2516
2640
  } finally {
2517
- userManager.endTask(userId);
2641
+ userManager.endVideoTask(userId);
2518
2642
  }
2519
2643
  });
2520
2644
  logger.info(`已注册视频风格命令: ${style.commandName}`);
@@ -67,6 +67,7 @@ export declare class UserManager {
67
67
  private usersCache;
68
68
  private pendingVideoCache;
69
69
  private activeTasks;
70
+ private activeVideoTasks;
70
71
  private rateLimitMap;
71
72
  private securityBlockMap;
72
73
  private securityWarningMap;
@@ -74,6 +75,9 @@ export declare class UserManager {
74
75
  startTask(userId: string): boolean;
75
76
  endTask(userId: string): void;
76
77
  isTaskActive(userId: string): boolean;
78
+ startVideoTask(userId: string): boolean;
79
+ endVideoTask(userId: string): void;
80
+ isVideoTaskActive(userId: string): boolean;
77
81
  isAdmin(userId: string, config: Config): boolean;
78
82
  private loadUsersData;
79
83
  private saveUsersDataInternal;
@@ -86,6 +90,26 @@ export declare class UserManager {
86
90
  getPendingVideoTask(taskId: string): Promise<PendingVideoTask | null>;
87
91
  markPendingVideoTaskCharged(taskId: string): Promise<PendingVideoTask | null>;
88
92
  deletePendingVideoTask(taskId: string): Promise<void>;
93
+ /**
94
+ * 获取某个用户最近一次未扣费的待结算视频任务
95
+ */
96
+ getLatestPendingVideoTaskForUser(userId: string): Promise<PendingVideoTask | null>;
97
+ /**
98
+ * 统计某个用户未扣费的待结算视频任务数量
99
+ */
100
+ countPendingVideoTasksForUser(userId: string): Promise<number>;
101
+ /**
102
+ * 列出某个用户所有未扣费的待结算视频任务
103
+ */
104
+ listPendingVideoTasksForUser(userId: string): Promise<PendingVideoTask[]>;
105
+ /**
106
+ * 添加待结算视频任务,并检查上限(默认max=1)
107
+ * @returns {Promise<{success: boolean, message?: string}>} 成功返回 {success: true},失败返回 {success: false, message: '错误信息'}
108
+ */
109
+ addPendingVideoTaskWithLimit(task: PendingVideoTask, max?: number): Promise<{
110
+ success: boolean;
111
+ message?: string;
112
+ }>;
89
113
  getUserData(userId: string, userName: string): Promise<UserData>;
90
114
  getAllUsers(): Promise<UsersData>;
91
115
  updateUsersBatch(updates: (data: UsersData) => void): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-aka-ai-generator",
3
3
  "description": "自用AI生成插件(GPTGod & Yunwu)",
4
- "version": "0.7.6",
4
+ "version": "0.7.8",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [