wp-epub-gen 0.5.0 → 0.6.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.
package/README.md CHANGED
@@ -122,13 +122,13 @@ epubGen(options).then(result => {
122
122
 
123
123
  ## API 参考
124
124
 
125
- ### epubGen(options, output?)
125
+ ### epubGen(options, configs?)
126
126
 
127
127
  主要的 EPUB 生成函数。
128
128
 
129
129
  **参数:**
130
- - `options: IEpubGenOptions` - 配置选项对象
131
- - `output?: string` - 可选的输出路径,会覆盖 options.output
130
+ - `options: IEpubGenOptions` - 配置选项对象(标题、作者、封面、章节内容等)
131
+ - `configs?: IGenConfigs` - 可选的运行时回调(logger、onProgress、concurrency),见下文 [IGenConfigs](#igenconfigs-运行时回调)
132
132
 
133
133
  **返回值:**
134
134
  - `Promise<IOut>` - 包含生成结果的 Promise
@@ -233,18 +233,83 @@ interface IOut {
233
233
  }
234
234
  ```
235
235
 
236
+ ### IGenConfigs 运行时回调
237
+
238
+ `epubGen` 的第二个参数,用于注入宿主侧的回调和并发配置。所有字段都是可选的。
239
+
240
+ ```typescript
241
+ interface IGenConfigs {
242
+ logger?: ILogger;
243
+ onProgress?: (e: IProgressEvent) => void;
244
+ concurrency?: number;
245
+ }
246
+ ```
247
+
248
+ #### `logger?: ILogger`
249
+
250
+ 注入自定义日志记录器(替代默认 `console`)。常用于 Electron 主进程把日志转发到渲染进程。
251
+
252
+ ```typescript
253
+ interface ILogger {
254
+ log: (msg: any) => void;
255
+ info: (msg: any) => void;
256
+ warn: (msg: any) => void;
257
+ error: (msg: any) => void;
258
+ }
259
+ ```
260
+
261
+ #### `onProgress?: (e: IProgressEvent) => void`
262
+
263
+ 进度回调。生成过程会在 5 个阶段中分别推送事件,宿主可据此渲染进度条或转发 IPC 给 UI。
264
+
265
+ ```typescript
266
+ type ProgressPhase =
267
+ | 'parseContent' // 解析章节 HTML
268
+ | 'writeChapters' // 写章节临时文件
269
+ | 'buildToc' // 渲染 OPF / NCX / TOC
270
+ | 'downloadImage' // 下载图片(仅当存在图片时)
271
+ | 'zip' // 打包 .epub
272
+
273
+ interface IProgressEvent {
274
+ phase: ProgressPhase;
275
+ current: number; // 已完成数量
276
+ total: number; // 总数量
277
+ label?: string; // 当前条目标签(章节标题 / 图片 URL)
278
+ }
279
+ ```
280
+
281
+ 最小用法:
282
+
283
+ ```typescript
284
+ await epubGen(options, {
285
+ onProgress: (e) => {
286
+ console.log(`[${e.phase}] ${e.current}/${e.total}`);
287
+ },
288
+ });
289
+ ```
290
+
291
+ 回调中抛出的异常会被库静默吞掉,不会中断 EPUB 生成。
292
+
293
+ #### `concurrency?: number`
294
+
295
+ 写章节文件和下载图片所共用的并发上限。默认 `16`,机械硬盘或带宽受限场景可调小(如 `4`)。非有限正整数(NaN、负数等)会被自动归一化为默认值。
296
+
236
297
  ## 导出的类型
237
298
 
238
299
  库导出了所有 TypeScript 类型定义:
239
300
 
240
301
  ```typescript
241
- import type {
242
- IEpubGenOptions,
243
- IChapter,
302
+ import type {
303
+ IEpubGenOptions,
304
+ IChapter,
244
305
  IChapterData,
245
306
  IEpubData,
246
307
  IEpubImage,
247
- IOut
308
+ IGenConfigs,
309
+ ILogger,
310
+ IProgressEvent,
311
+ ProgressPhase,
312
+ IOut,
248
313
  } from 'wp-epub-gen';
249
314
  ```
250
315
 
package/build/index.cjs CHANGED
@@ -4,14 +4,14 @@ const os = require("os");
4
4
  const path = require("path");
5
5
  const url = require("url");
6
6
  const uuid = require("uuid");
7
+ const fs = require("fs");
8
+ const util = require("util");
7
9
  const cheerio = require("cheerio");
8
10
  const diacritics = require("diacritics");
9
11
  const uslug = require("uslug");
10
12
  const archiver = require("archiver");
11
13
  const fs$1 = require("fs-extra");
12
14
  const request = require("superagent");
13
- const fs = require("fs");
14
- const util = require("util");
15
15
  const ejs = require("ejs");
16
16
  const entities = require("entities");
17
17
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
@@ -95,6 +95,63 @@ class GlobalLogger {
95
95
  }
96
96
  }
97
97
  const logger = GlobalLogger.getInstance();
98
+ util.promisify(fs.readFile);
99
+ const writeFile = util.promisify(fs.writeFile);
100
+ function normalizeConcurrency(value) {
101
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 1) return void 0;
102
+ return Math.floor(value);
103
+ }
104
+ function pLimit(concurrency) {
105
+ if (!Number.isFinite(concurrency) || concurrency < 1) concurrency = 1;
106
+ else concurrency = Math.floor(concurrency);
107
+ let active = 0;
108
+ const queue = [];
109
+ const next = () => {
110
+ active--;
111
+ if (queue.length) queue.shift()();
112
+ };
113
+ return (fn) => new Promise((resolve, reject) => {
114
+ const run = () => {
115
+ active++;
116
+ fn().then(
117
+ (v) => {
118
+ resolve(v);
119
+ next();
120
+ },
121
+ (e) => {
122
+ reject(e);
123
+ next();
124
+ }
125
+ );
126
+ };
127
+ if (active < concurrency) run();
128
+ else queue.push(run);
129
+ });
130
+ }
131
+ function emitProgress(configs, event) {
132
+ if (!configs?.onProgress) return;
133
+ try {
134
+ configs.onProgress(event);
135
+ } catch {
136
+ }
137
+ }
138
+ const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
139
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
140
+ async function fileIsStable(filename, max_wait = 3e4) {
141
+ const start_time = (/* @__PURE__ */ new Date()).getTime();
142
+ let last_size = fs.statSync(filename).size;
143
+ while ((/* @__PURE__ */ new Date()).getTime() - start_time <= max_wait) {
144
+ await wait(1e3);
145
+ const size = fs.statSync(filename).size;
146
+ if (size === last_size) return true;
147
+ last_size = size;
148
+ }
149
+ return false;
150
+ }
151
+ function simpleMinifier(xhtml) {
152
+ xhtml = xhtml.replace(/\s+<\/a>/gi, "</a>").replace(/\n\s+</g, "\n<").replace(/\n+/g, "\n");
153
+ return xhtml;
154
+ }
98
155
  function safeFineName(name) {
99
156
  return name.replace(/[/\\?%*:|"<>\t\r\n]/g, "_");
100
157
  }
@@ -362,7 +419,7 @@ function loadAndProcessHtml(data) {
362
419
  throw new Error("Invalid HTML data: data cannot be empty or whitespace only");
363
420
  }
364
421
  try {
365
- let $ = cheerio__namespace.load(trimmedData, {
422
+ const $ = cheerio__namespace.load(trimmedData, {
366
423
  xmlMode: true,
367
424
  // @ts-ignore
368
425
  decodeEntities: false,
@@ -372,17 +429,8 @@ function loadAndProcessHtml(data) {
372
429
  });
373
430
  const body = $("body");
374
431
  if (body.length) {
375
- const html = body.html();
376
- if (html) {
377
- $ = cheerio__namespace.load(html, {
378
- xmlMode: true,
379
- // @ts-ignore
380
- decodeEntities: false,
381
- lowerCaseTags: true,
382
- recognizeSelfClosing: true,
383
- lowerCaseAttributeNames: true
384
- });
385
- }
432
+ const bodyContents = body.contents();
433
+ $.root().empty().append(bodyContents);
386
434
  }
387
435
  return $;
388
436
  } catch (error) {
@@ -431,6 +479,10 @@ function processHtmlElements($, allowedAttributes, allowedXhtml11Tags, epubConfi
431
479
  });
432
480
  }
433
481
  function processImages($, chapter, epubConfigs) {
482
+ if (!epubConfigs._imagesByUrl) {
483
+ epubConfigs._imagesByUrl = new Map(epubConfigs.images.map((img) => [img.url, img]));
484
+ }
485
+ const imagesByUrl = epubConfigs._imagesByUrl;
434
486
  $("img").each((index2, elem) => {
435
487
  const url2 = $(elem).attr("src") || "";
436
488
  if (!url2 || url2.trim().length === 0) {
@@ -446,7 +498,7 @@ function processImages($, chapter, epubConfigs) {
446
498
  } catch (error) {
447
499
  logger.error(`Error validating image URL "${trimmedUrl}": ${error}`);
448
500
  }
449
- const image = epubConfigs.images.find((el) => el.url === trimmedUrl);
501
+ const image = imagesByUrl.get(trimmedUrl);
450
502
  let id;
451
503
  let extension;
452
504
  if (image) {
@@ -485,6 +537,7 @@ function processImages($, chapter, epubConfigs) {
485
537
  const dir = chapter.dir || "";
486
538
  const img = { id, url: trimmedUrl, dir, mediaType, extension };
487
539
  epubConfigs.images.push(img);
540
+ imagesByUrl.set(trimmedUrl, img);
488
541
  if (epubConfigs.verbose) {
489
542
  logger.info(`Added image: ${trimmedUrl} -> images/${id}.${extension} (${mediaType})`);
490
543
  }
@@ -549,25 +602,6 @@ function parseContent(content, index2, epubConfigs) {
549
602
  processChildrenChapters(chapter, index2, epubConfigs);
550
603
  return chapter;
551
604
  }
552
- util.promisify(fs.readFile);
553
- const writeFile = util.promisify(fs.writeFile);
554
- const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
555
- const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
556
- async function fileIsStable(filename, max_wait = 3e4) {
557
- const start_time = (/* @__PURE__ */ new Date()).getTime();
558
- let last_size = fs.statSync(filename).size;
559
- while ((/* @__PURE__ */ new Date()).getTime() - start_time <= max_wait) {
560
- await wait(1e3);
561
- const size = fs.statSync(filename).size;
562
- if (size === last_size) return true;
563
- last_size = size;
564
- }
565
- return false;
566
- }
567
- function simpleMinifier(xhtml) {
568
- xhtml = xhtml.replace(/\s+<\/a>/gi, "</a>").replace(/\n\s+</g, "\n<").replace(/\n+/g, "\n");
569
- return xhtml;
570
- }
571
605
  const downloadImage = async (epubData, options) => {
572
606
  const { url: url2 } = options;
573
607
  const { log } = epubData;
@@ -576,7 +610,6 @@ const downloadImage = async (epubData, options) => {
576
610
  return;
577
611
  }
578
612
  const image_dir = path.join(epub_dir, "OEBPS", "images");
579
- fs$1.ensureDirSync(image_dir);
580
613
  const filename = path.join(image_dir, options.id + "." + options.extension);
581
614
  if (url2.startsWith("file://") || url2.startsWith("/")) {
582
615
  let aux_path = url2.replace(/^file:\/\//i, "");
@@ -602,35 +635,75 @@ const downloadImage = async (epubData, options) => {
602
635
  }
603
636
  return;
604
637
  }
638
+ const writeStream = fs$1.createWriteStream(filename);
605
639
  let requestAction;
606
640
  if (url2.startsWith("http")) {
607
641
  requestAction = request.get(url2).set({ "User-Agent": USER_AGENT });
608
- requestAction.pipe(fs$1.createWriteStream(filename));
609
642
  } else {
610
643
  log(`[Copy 2] '${url2}' to '${filename}'`);
611
644
  requestAction = fs$1.createReadStream(path.join(options.dir || "", url2));
612
- requestAction.pipe(fs$1.createWriteStream(filename));
613
645
  }
614
- return new Promise((resolve, _reject) => {
646
+ requestAction.pipe(writeStream);
647
+ return new Promise((resolve) => {
648
+ let settled = false;
649
+ const finalize = () => {
650
+ if (settled) return;
651
+ settled = true;
652
+ resolve();
653
+ };
654
+ const cleanupFile = () => {
655
+ try {
656
+ fs$1.unlinkSync(filename);
657
+ } catch {
658
+ }
659
+ };
660
+ const abortSource = () => {
661
+ if (typeof requestAction.abort === "function") requestAction.abort();
662
+ else if (typeof requestAction.destroy === "function") requestAction.destroy();
663
+ };
615
664
  requestAction.on("error", (err) => {
616
665
  log("[Download Error] Error while downloading: " + url2);
617
666
  log(err);
618
- fs$1.unlinkSync(filename);
619
- resolve();
667
+ writeStream.destroy();
668
+ cleanupFile();
669
+ finalize();
620
670
  });
621
- requestAction.on("end", () => {
671
+ writeStream.on("error", (err) => {
672
+ log("[Write Error] Error while writing: " + filename);
673
+ log(err);
674
+ abortSource();
675
+ cleanupFile();
676
+ finalize();
677
+ });
678
+ writeStream.on("finish", () => {
622
679
  log("[Download Success] " + url2);
623
- resolve();
680
+ finalize();
624
681
  });
625
682
  });
626
683
  };
627
684
  const downloadAllImages = async (epubData) => {
628
685
  const { images } = epubData;
629
686
  if (images.length === 0) return;
630
- fs$1.ensureDirSync(path.join(epubData.dir, "OEBPS", "images"));
631
- for (const image of images) {
632
- await downloadImage(epubData, image);
633
- }
687
+ await fs$1.ensureDir(path.join(epubData.dir, "OEBPS", "images"));
688
+ const concurrency = epubData._configs?.concurrency ?? 16;
689
+ const limit = pLimit(concurrency);
690
+ const total = images.length;
691
+ let done = 0;
692
+ emitProgress(epubData._configs, { phase: "downloadImage", current: 0, total });
693
+ await Promise.all(
694
+ images.map(
695
+ (image) => limit(async () => {
696
+ await downloadImage(epubData, image);
697
+ done++;
698
+ emitProgress(epubData._configs, {
699
+ phase: "downloadImage",
700
+ current: done,
701
+ total,
702
+ label: image.url
703
+ });
704
+ })
705
+ )
706
+ );
634
707
  };
635
708
  const epub2_content_opf_ejs = `<?xml version="1.0" encoding="UTF-8"?>
636
709
  <package xmlns="http://www.idpf.org/2007/opf"
@@ -1029,21 +1102,23 @@ const generateTempFile = async (epubData) => {
1029
1102
  if (epubData.fonts?.length) {
1030
1103
  const fonts_dir = path.join(oebpsDir, "fonts");
1031
1104
  await fs$1.ensureDir(fonts_dir);
1032
- epubData.fonts = epubData.fonts.map((font) => {
1105
+ const fontFilenames = [];
1106
+ for (const font of epubData.fonts) {
1033
1107
  const filename = path.basename(font);
1034
1108
  if (!fs$1.existsSync(font)) {
1035
1109
  log(`Custom font not found at '${font}'.`);
1036
1110
  } else {
1037
- fs$1.copySync(font, path.join(fonts_dir, filename));
1111
+ await fs$1.copy(font, path.join(fonts_dir, filename));
1038
1112
  }
1039
- return filename;
1040
- });
1113
+ fontFilenames.push(filename);
1114
+ }
1115
+ epubData.fonts = fontFilenames;
1041
1116
  }
1042
1117
  const isAppendTitle = (global_append, local_append) => {
1043
1118
  if (typeof local_append === "boolean") return local_append;
1044
1119
  return !!global_append;
1045
1120
  };
1046
- const saveContentToFile = (content) => {
1121
+ const renderChapterHtml = (content) => {
1047
1122
  const title = entities__namespace.encodeXML(content.title || "");
1048
1123
  let html = `${epubData.docHeader}
1049
1124
  <head>
@@ -1060,16 +1135,39 @@ const generateTempFile = async (epubData) => {
1060
1135
  html += content.title && content.url ? `<p class="epub-link"><a href="${content.url}">${content.url}</a></p>` : "";
1061
1136
  html += `${content.data}`;
1062
1137
  html += "\n</body>\n</html>";
1063
- fs$1.ensureDirSync(path.dirname(content.filePath));
1064
- fs$1.writeFileSync(content.filePath, html, "utf-8");
1065
- if (Array.isArray(content.children)) {
1066
- content.children.map(saveContentToFile);
1138
+ return html;
1139
+ };
1140
+ const flattenChapters = (nodes, out = []) => {
1141
+ for (const c of nodes) {
1142
+ out.push(c);
1143
+ if (Array.isArray(c.children) && c.children.length) flattenChapters(c.children, out);
1067
1144
  }
1145
+ return out;
1068
1146
  };
1069
- epubData.content.map(saveContentToFile);
1147
+ const allChapters = flattenChapters(epubData.content);
1148
+ const totalChapters = allChapters.length;
1149
+ const uniqueDirs = Array.from(new Set(allChapters.map((c) => path.dirname(c.filePath))));
1150
+ for (const d of uniqueDirs) await fs$1.ensureDir(d);
1151
+ const concurrency = epubData._configs?.concurrency ?? 16;
1152
+ const limit = pLimit(concurrency);
1153
+ let written = 0;
1154
+ await Promise.all(
1155
+ allChapters.map(
1156
+ (content) => limit(async () => {
1157
+ await fs$1.writeFile(content.filePath, renderChapterHtml(content), "utf-8");
1158
+ written++;
1159
+ emitProgress(epubData._configs, {
1160
+ phase: "writeChapters",
1161
+ current: written,
1162
+ total: totalChapters,
1163
+ label: content.title
1164
+ });
1165
+ })
1166
+ )
1167
+ );
1070
1168
  const metainf_dir = path.join(epubData.dir, "META-INF");
1071
- fs$1.ensureDirSync(metainf_dir);
1072
- fs$1.writeFileSync(
1169
+ await fs$1.ensureDir(metainf_dir);
1170
+ await fs$1.writeFile(
1073
1171
  path.join(metainf_dir, "container.xml"),
1074
1172
  `<?xml version="1.0" encoding="UTF-8" ?>
1075
1173
  <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
@@ -1079,7 +1177,7 @@ const generateTempFile = async (epubData) => {
1079
1177
  );
1080
1178
  if (epubData.version === 2) {
1081
1179
  const fn = path.join(metainf_dir, "com.apple.ibooks.display-options.xml");
1082
- fs$1.writeFileSync(
1180
+ await fs$1.writeFile(
1083
1181
  fn,
1084
1182
  `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
1085
1183
  <display_options>
@@ -1113,17 +1211,25 @@ const generateTempFile = async (epubData) => {
1113
1211
  htmlTocTemplate = epubData.version === 2 ? epub2_toc_xhtml_ejs : epub3_toc_xhtml_ejs;
1114
1212
  }
1115
1213
  const toc_depth = 1;
1116
- fs$1.writeFileSync(path.join(oebpsDir, "content.opf"), ejs.render(opfTemplate, epubData), "utf-8");
1117
- fs$1.writeFileSync(
1118
- path.join(oebpsDir, "toc.ncx"),
1119
- ejs.render(ncxTocTemplate, { ...epubData, toc_depth }),
1120
- "utf-8"
1121
- );
1122
- fs$1.writeFileSync(
1123
- path.join(oebpsDir, "toc.xhtml"),
1124
- simpleMinifier(ejs.render(htmlTocTemplate, epubData)),
1125
- "utf-8"
1126
- );
1214
+ emitProgress(epubData._configs, { phase: "buildToc", current: 0, total: 3 });
1215
+ await Promise.all([
1216
+ fs$1.writeFile(
1217
+ path.join(oebpsDir, "content.opf"),
1218
+ ejs.render(opfTemplate, epubData),
1219
+ "utf-8"
1220
+ ),
1221
+ fs$1.writeFile(
1222
+ path.join(oebpsDir, "toc.ncx"),
1223
+ ejs.render(ncxTocTemplate, { ...epubData, toc_depth }),
1224
+ "utf-8"
1225
+ ),
1226
+ fs$1.writeFile(
1227
+ path.join(oebpsDir, "toc.xhtml"),
1228
+ simpleMinifier(ejs.render(htmlTocTemplate, epubData)),
1229
+ "utf-8"
1230
+ )
1231
+ ]);
1232
+ emitProgress(epubData._configs, { phase: "buildToc", current: 3, total: 3 });
1127
1233
  };
1128
1234
  async function makeCover(data) {
1129
1235
  const { cover, _coverExtension, log } = data;
@@ -1181,6 +1287,7 @@ async function genEpub(epubData) {
1181
1287
  const archive = archiver("zip", { zlib: { level: 9 } });
1182
1288
  const outputStream = fs$1.createWriteStream(epubData.output);
1183
1289
  log("Zipping temp dir to " + output);
1290
+ emitProgress(epubData._configs, { phase: "zip", current: 0, total: 1 });
1184
1291
  return new Promise((resolve, reject) => {
1185
1292
  archive.on("end", async () => {
1186
1293
  log("Done zipping, clearing temp dir...");
@@ -1190,6 +1297,7 @@ async function genEpub(epubData) {
1190
1297
  }
1191
1298
  try {
1192
1299
  fs$1.removeSync(dir);
1300
+ emitProgress(epubData._configs, { phase: "zip", current: 1, total: 1 });
1193
1301
  resolve();
1194
1302
  } catch (e) {
1195
1303
  log("[Error] " + e.message);
@@ -1247,7 +1355,7 @@ function check(options) {
1247
1355
  }
1248
1356
  return result(true, void 0, options);
1249
1357
  }
1250
- function parseOptions(options) {
1358
+ async function parseOptions(options, configs) {
1251
1359
  const tmpDir = options.tmpDir || os.tmpdir();
1252
1360
  const id = uuid.v4();
1253
1361
  const data = {
@@ -1272,7 +1380,8 @@ function parseOptions(options) {
1272
1380
  docHeader: "",
1273
1381
  images: [],
1274
1382
  content: [],
1275
- log: (msg) => options.verbose && logger.log(msg)
1383
+ log: (msg) => options.verbose && logger.log(msg),
1384
+ _configs: configs
1276
1385
  };
1277
1386
  if (data.version === 2) {
1278
1387
  data.docHeader = `<?xml version="1.0" encoding="UTF-8"?>
@@ -1291,7 +1400,17 @@ function parseOptions(options) {
1291
1400
  if (typeof data.author === "string") {
1292
1401
  data.author = [data.author];
1293
1402
  }
1294
- data.content = options.content.map((content, index2) => parseContent(content, index2, data));
1403
+ const total = options.content.length;
1404
+ const parsed = [];
1405
+ for (let i = 0; i < total; i++) {
1406
+ parsed.push(parseContent(options.content[i], i, data));
1407
+ if ((i & 31) === 31) {
1408
+ await new Promise((r) => setImmediate(r));
1409
+ emitProgress(configs, { phase: "parseContent", current: i + 1, total });
1410
+ }
1411
+ }
1412
+ emitProgress(configs, { phase: "parseContent", current: total, total });
1413
+ data.content = parsed;
1295
1414
  if (data.cover) {
1296
1415
  data._coverMediaType = mime.getType(data.cover) || "";
1297
1416
  data._coverExtension = mime.getExtension(data._coverMediaType) || "";
@@ -1299,6 +1418,9 @@ function parseOptions(options) {
1299
1418
  return data;
1300
1419
  }
1301
1420
  async function epubGen(options, configs) {
1421
+ if (configs) {
1422
+ configs = { ...configs, concurrency: normalizeConcurrency(configs.concurrency) };
1423
+ }
1302
1424
  if (configs?.logger) {
1303
1425
  logger.setLogger(configs.logger);
1304
1426
  }
@@ -1312,7 +1434,7 @@ async function epubGen(options, configs) {
1312
1434
  }
1313
1435
  let t;
1314
1436
  try {
1315
- const data = parseOptions(options);
1437
+ const data = await parseOptions(options, configs);
1316
1438
  const timeoutSeconds = data.timeoutSeconds || 0;
1317
1439
  if (timeoutSeconds > 0) {
1318
1440
  if (verbose) logger.log(`TIMEOUT: ${timeoutSeconds}s`);
package/build/index.d.ts CHANGED
@@ -12,4 +12,4 @@ declare const _default: {
12
12
  };
13
13
  };
14
14
  export default _default;
15
- export type { IChapter, IChapterData, IEpubData, IEpubGenOptions, IEpubImage, IOut } from './types';
15
+ export type { IChapter, IChapterData, IEpubData, IEpubGenOptions, IEpubImage, IGenConfigs, ILogger, IOut, IProgressEvent, ProgressPhase, } from './types';