wp-epub-gen 0.1.4 → 0.2.1

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/build/index.js CHANGED
@@ -1,128 +1,757 @@
1
1
  "use strict";
2
- /**
3
- * index.ts
4
- * @author: oldj
5
- * @homepage: https://oldj.net
6
- */
7
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
- return new (P || (P = Promise))(function (resolve, reject) {
10
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
- step((generator = generator.apply(thisArg, _arguments || [])).next());
14
- });
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.gen = exports.epubGen = void 0;
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
18
3
  const mime = require("mime");
19
4
  const os = require("os");
20
5
  const path = require("path");
21
- const uuid_1 = require("uuid");
22
- const errors_1 = require("./errors");
23
- const parseContent_1 = require("./parseContent");
24
- const render_1 = require("./render");
25
- const baseDir = path.dirname(__dirname);
26
- function result(success, message, options) {
27
- if (options && options.verbose) {
28
- if (!success) {
29
- console.error(new Error(message));
30
- }
6
+ const uuid = require("uuid");
7
+ const cheerio = require("cheerio");
8
+ const diacritics = require("diacritics");
9
+ const uslug = require("uslug");
10
+ const archiver = require("archiver");
11
+ const fs$1 = require("fs-extra");
12
+ const request = require("superagent");
13
+ const fs = require("fs");
14
+ const util = require("util");
15
+ const ejs = require("ejs");
16
+ const entities = require("entities");
17
+ function _interopNamespaceDefault(e) {
18
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
19
+ if (e) {
20
+ for (const k in e) {
21
+ if (k !== "default") {
22
+ const d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: () => e[k]
26
+ });
27
+ }
31
28
  }
32
- let out = {
33
- success,
34
- };
35
- if (typeof message === 'string') {
36
- out.message = message;
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+ const mime__namespace = /* @__PURE__ */ _interopNamespaceDefault(mime);
34
+ const os__namespace = /* @__PURE__ */ _interopNamespaceDefault(os);
35
+ const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path);
36
+ const fs__namespace$1 = /* @__PURE__ */ _interopNamespaceDefault(fs$1);
37
+ const request__namespace = /* @__PURE__ */ _interopNamespaceDefault(request);
38
+ const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
39
+ const ejs__namespace = /* @__PURE__ */ _interopNamespaceDefault(ejs);
40
+ const entities__namespace = /* @__PURE__ */ _interopNamespaceDefault(entities);
41
+ const errors = {
42
+ no_output_path: "No output path!",
43
+ no_title: "Title is required.",
44
+ no_content: "Content is required."
45
+ };
46
+ function safeFineName(name) {
47
+ return name.replace(/[/\\?%*:|"<>\t\r\n]/g, "_");
48
+ }
49
+ function parseContent(content, index, epubConfigs) {
50
+ let chapter = { ...content };
51
+ let { filename } = chapter;
52
+ if (!filename) {
53
+ let titleSlug = uslug(diacritics.remove(chapter.title || "no title"));
54
+ titleSlug = titleSlug.replace(/[\/\\]/g, "_");
55
+ chapter.href = `${index}_${titleSlug}.xhtml`;
56
+ chapter.filePath = path.join(epubConfigs.dir, "OEBPS", chapter.href);
57
+ } else {
58
+ filename = safeFineName(filename);
59
+ let is_xhtml = filename.endsWith(".xhtml");
60
+ chapter.href = is_xhtml ? filename : `${filename}.xhtml`;
61
+ if (is_xhtml) {
62
+ chapter.filePath = path.join(epubConfigs.dir, "OEBPS", filename);
63
+ } else {
64
+ chapter.filePath = path.join(epubConfigs.dir, "OEBPS", `${filename}.xhtml`);
65
+ }
66
+ }
67
+ chapter.id = `item_${index}`;
68
+ chapter.dir = path.dirname(chapter.filePath);
69
+ chapter.excludeFromToc = chapter.excludeFromToc || false;
70
+ chapter.beforeToc = chapter.beforeToc || false;
71
+ if (chapter.author && typeof chapter.author === "string") {
72
+ chapter.author = [chapter.author];
73
+ } else if (!chapter.author || !Array.isArray(chapter.author)) {
74
+ chapter.author = [];
75
+ }
76
+ let allowedAttributes = [
77
+ "content",
78
+ "alt",
79
+ "id",
80
+ "title",
81
+ "src",
82
+ "href",
83
+ "about",
84
+ "accesskey",
85
+ "aria-activedescendant",
86
+ "aria-atomic",
87
+ "aria-autocomplete",
88
+ "aria-busy",
89
+ "aria-checked",
90
+ "aria-controls",
91
+ "aria-describedat",
92
+ "aria-describedby",
93
+ "aria-disabled",
94
+ "aria-dropeffect",
95
+ "aria-expanded",
96
+ "aria-flowto",
97
+ "aria-grabbed",
98
+ "aria-haspopup",
99
+ "aria-hidden",
100
+ "aria-invalid",
101
+ "aria-label",
102
+ "aria-labelledby",
103
+ "aria-level",
104
+ "aria-live",
105
+ "aria-multiline",
106
+ "aria-multiselectable",
107
+ "aria-orientation",
108
+ "aria-owns",
109
+ "aria-posinset",
110
+ "aria-pressed",
111
+ "aria-readonly",
112
+ "aria-relevant",
113
+ "aria-required",
114
+ "aria-selected",
115
+ "aria-setsize",
116
+ "aria-sort",
117
+ "aria-valuemax",
118
+ "aria-valuemin",
119
+ "aria-valuenow",
120
+ "aria-valuetext",
121
+ "class",
122
+ "content",
123
+ "contenteditable",
124
+ "contextmenu",
125
+ "datatype",
126
+ "dir",
127
+ "draggable",
128
+ "dropzone",
129
+ "hidden",
130
+ "hreflang",
131
+ "id",
132
+ "inlist",
133
+ "itemid",
134
+ "itemref",
135
+ "itemscope",
136
+ "itemtype",
137
+ "lang",
138
+ "media",
139
+ "ns1:type",
140
+ "ns2:alphabet",
141
+ "ns2:ph",
142
+ "onabort",
143
+ "onblur",
144
+ "oncanplay",
145
+ "oncanplaythrough",
146
+ "onchange",
147
+ "onclick",
148
+ "oncontextmenu",
149
+ "ondblclick",
150
+ "ondrag",
151
+ "ondragend",
152
+ "ondragenter",
153
+ "ondragleave",
154
+ "ondragover",
155
+ "ondragstart",
156
+ "ondrop",
157
+ "ondurationchange",
158
+ "onemptied",
159
+ "onended",
160
+ "onerror",
161
+ "onfocus",
162
+ "oninput",
163
+ "oninvalid",
164
+ "onkeydown",
165
+ "onkeypress",
166
+ "onkeyup",
167
+ "onload",
168
+ "onloadeddata",
169
+ "onloadedmetadata",
170
+ "onloadstart",
171
+ "onmousedown",
172
+ "onmousemove",
173
+ "onmouseout",
174
+ "onmouseover",
175
+ "onmouseup",
176
+ "onmousewheel",
177
+ "onpause",
178
+ "onplay",
179
+ "onplaying",
180
+ "onprogress",
181
+ "onratechange",
182
+ "onreadystatechange",
183
+ "onreset",
184
+ "onscroll",
185
+ "onseeked",
186
+ "onseeking",
187
+ "onselect",
188
+ "onshow",
189
+ "onstalled",
190
+ "onsubmit",
191
+ "onsuspend",
192
+ "ontimeupdate",
193
+ "onvolumechange",
194
+ "onwaiting",
195
+ "prefix",
196
+ "property",
197
+ "rel",
198
+ "resource",
199
+ "rev",
200
+ "role",
201
+ "spellcheck",
202
+ "style",
203
+ "tabindex",
204
+ "target",
205
+ "title",
206
+ "type",
207
+ "typeof",
208
+ "vocab",
209
+ "xml:base",
210
+ "xml:lang",
211
+ "xml:space",
212
+ "colspan",
213
+ "rowspan",
214
+ "epub:type",
215
+ "epub:prefix"
216
+ ];
217
+ let allowedXhtml11Tags = [
218
+ "div",
219
+ "p",
220
+ "h1",
221
+ "h2",
222
+ "h3",
223
+ "h4",
224
+ "h5",
225
+ "h6",
226
+ "ul",
227
+ "ol",
228
+ "li",
229
+ "dl",
230
+ "dt",
231
+ "dd",
232
+ "address",
233
+ "hr",
234
+ "pre",
235
+ "blockquote",
236
+ "center",
237
+ "ins",
238
+ "del",
239
+ "a",
240
+ "span",
241
+ "bdo",
242
+ "br",
243
+ "em",
244
+ "strong",
245
+ "dfn",
246
+ "code",
247
+ "samp",
248
+ "kbd",
249
+ "bar",
250
+ "cite",
251
+ "abbr",
252
+ "acronym",
253
+ "q",
254
+ "sub",
255
+ "sup",
256
+ "tt",
257
+ "i",
258
+ "b",
259
+ "big",
260
+ "small",
261
+ "u",
262
+ "s",
263
+ "strike",
264
+ "basefont",
265
+ "font",
266
+ "object",
267
+ "param",
268
+ "img",
269
+ "table",
270
+ "caption",
271
+ "colgroup",
272
+ "col",
273
+ "thead",
274
+ "tfoot",
275
+ "tbody",
276
+ "tr",
277
+ "th",
278
+ "td",
279
+ "embed",
280
+ "applet",
281
+ "iframe",
282
+ "img",
283
+ "map",
284
+ "noscript",
285
+ "ns:svg",
286
+ "object",
287
+ "script",
288
+ "table",
289
+ "tt",
290
+ "var"
291
+ ];
292
+ let $ = cheerio.load(chapter.data, {
293
+ lowerCaseTags: true,
294
+ recognizeSelfClosing: true
295
+ });
296
+ let body = $("body");
297
+ if (body.length) {
298
+ let html = body.html();
299
+ if (html) {
300
+ $ = cheerio.load(html, {
301
+ lowerCaseTags: true,
302
+ recognizeSelfClosing: true
303
+ });
304
+ }
305
+ }
306
+ $($("*").get().reverse()).each(function(elemIndex, elem) {
307
+ let attrs = elem.attribs;
308
+ let that = this;
309
+ let tags = ["img", "br", "hr"];
310
+ if (tags.includes(that.name)) {
311
+ if (that.name === "img" && !$(that).attr("alt")) {
312
+ $(that).attr("alt", "image-placeholder");
313
+ }
314
+ }
315
+ Object.entries(attrs).map(([k, v]) => {
316
+ if (allowedAttributes.includes(k)) {
317
+ if (k === "type" && that.name !== "script") {
318
+ $(that).removeAttr(k);
319
+ }
320
+ } else {
321
+ $(that).removeAttr(k);
322
+ }
323
+ });
324
+ if (epubConfigs.version === 2) {
325
+ if (!allowedXhtml11Tags.includes(that.name)) {
326
+ if (epubConfigs.verbose) {
327
+ console.log(
328
+ "Warning (content[" + index + "]):",
329
+ that.name,
330
+ "tag isn't allowed on EPUB 2/XHTML 1.1 DTD."
331
+ );
332
+ }
333
+ let child = $(that).html();
334
+ $(that).replaceWith($("<div>" + child + "</div>"));
335
+ }
37
336
  }
38
- if (options) {
39
- out.options = options;
337
+ });
338
+ $("img").each((index2, elem) => {
339
+ let url = $(elem).attr("src") || "";
340
+ let image = epubConfigs.images.find((el) => el.url === url);
341
+ let id;
342
+ let extension;
343
+ if (image) {
344
+ id = image.id;
345
+ extension = image.extension;
346
+ } else {
347
+ id = uuid.v4();
348
+ let mediaType = mime.getType(url.replace(/\?.*/, "")) || "";
349
+ extension = mime.getExtension(mediaType) || "";
350
+ let dir = chapter.dir || "";
351
+ let img = { id, url, dir, mediaType, extension };
352
+ epubConfigs.images.push(img);
40
353
  }
41
- return out;
354
+ $(elem).attr("src", `images/${id}.${extension}`);
355
+ });
356
+ chapter.data = $.xml();
357
+ if (Array.isArray(chapter.children)) {
358
+ chapter.children = chapter.children.map(
359
+ (content2, idx) => parseContent(content2, `${index}_${idx}`, epubConfigs)
360
+ );
361
+ }
362
+ return chapter;
42
363
  }
43
- function check(options) {
44
- if (!options.output) {
45
- return result(false, errors_1.errors.no_output_path, options);
364
+ const readFile = util.promisify(fs__namespace.readFile);
365
+ const writeFile = util.promisify(fs__namespace.writeFile);
366
+ 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";
367
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
368
+ async function fileIsStable(filename, max_wait = 3e4) {
369
+ let start_time = new Date().getTime();
370
+ let last_size = fs__namespace.statSync(filename).size;
371
+ while (new Date().getTime() - start_time <= max_wait) {
372
+ await wait(1e3);
373
+ let size = fs__namespace.statSync(filename).size;
374
+ if (size === last_size)
375
+ return true;
376
+ last_size = size;
377
+ }
378
+ return false;
379
+ }
380
+ function simpleMinifier(xhtml) {
381
+ xhtml = xhtml.replace(/\s+<\/a>/gi, "</a>").replace(/\n\s+</g, "\n<").replace(/\n+/g, "\n");
382
+ return xhtml;
383
+ }
384
+ const downloadImage = async (epubData, options) => {
385
+ let { url } = options;
386
+ let { log } = epubData;
387
+ let epub_dir = epubData.dir;
388
+ if (!url) {
389
+ return;
390
+ }
391
+ let image_dir = path__namespace.join(epub_dir, "OEBPS", "images");
392
+ fs__namespace$1.ensureDirSync(image_dir);
393
+ let filename = path__namespace.join(image_dir, options.id + "." + options.extension);
394
+ if (url.startsWith("file://") || url.startsWith("/")) {
395
+ let auxPath = url.replace(/^file:\/\//i, "");
396
+ if (process.platform === "win32") {
397
+ if (auxPath.match(/^\/[a-zA-Z]:/)) {
398
+ auxPath = auxPath.replace(/^\//, "");
399
+ }
46
400
  }
47
- if (!options.title) {
48
- return result(false, errors_1.errors.no_title, options);
401
+ log(`[Copy 1] '${auxPath}' to '${filename}'`);
402
+ if (fs__namespace$1.existsSync(auxPath)) {
403
+ try {
404
+ fs__namespace$1.copySync(auxPath, filename);
405
+ } catch (e) {
406
+ log("[Copy 1 Error] " + e.message);
407
+ }
408
+ } else {
409
+ log(`[Copy 1 Fail] '${url}' not exists!`);
49
410
  }
50
- if (!options.content) {
51
- return result(false, errors_1.errors.no_content, options);
411
+ return;
412
+ }
413
+ let requestAction;
414
+ if (url.startsWith("http")) {
415
+ requestAction = request__namespace.get(url).set({ "User-Agent": USER_AGENT });
416
+ requestAction.pipe(fs__namespace$1.createWriteStream(filename));
417
+ } else {
418
+ log(`[Copy 2] '${url}' to '${filename}'`);
419
+ requestAction = fs__namespace$1.createReadStream(path__namespace.join(options.dir || "", url));
420
+ requestAction.pipe(fs__namespace$1.createWriteStream(filename));
421
+ }
422
+ return new Promise((resolve, reject) => {
423
+ requestAction.on("error", (err) => {
424
+ log("[Download Error] Error while downloading: " + url);
425
+ log(err);
426
+ fs__namespace$1.unlinkSync(filename);
427
+ resolve();
428
+ });
429
+ requestAction.on("end", () => {
430
+ log("[Download Success] " + url);
431
+ resolve();
432
+ });
433
+ });
434
+ };
435
+ const downloadAllImages = async (epubData) => {
436
+ let { images } = epubData;
437
+ if (images.length === 0)
438
+ return;
439
+ fs__namespace$1.ensureDirSync(path__namespace.join(epubData.dir, "OEBPS", "images"));
440
+ for (let image of images) {
441
+ await downloadImage(epubData, image);
442
+ }
443
+ };
444
+ const generateTempFile = async (epubData) => {
445
+ var _a;
446
+ let { log } = epubData;
447
+ let oebps_dir = path__namespace.join(epubData.dir, "OEBPS");
448
+ await fs__namespace$1.ensureDir(oebps_dir);
449
+ const templates_dir = path__namespace.join(epubData.baseDir, "templates");
450
+ epubData.css = epubData.css || await readFile(path__namespace.join(templates_dir, "template.css"), "utf-8");
451
+ await writeFile(path__namespace.join(oebps_dir, "style.css"), epubData.css, "utf-8");
452
+ if ((_a = epubData.fonts) == null ? void 0 : _a.length) {
453
+ let fonts_dir = path__namespace.join(oebps_dir, "fonts");
454
+ await fs__namespace$1.ensureDir(fonts_dir);
455
+ epubData.fonts = epubData.fonts.map((font) => {
456
+ let filename = path__namespace.basename(font);
457
+ if (!fs__namespace$1.existsSync(font)) {
458
+ log(`Custom font not found at '${font}'.`);
459
+ } else {
460
+ fs__namespace$1.copySync(font, path__namespace.join(fonts_dir, filename));
461
+ }
462
+ return filename;
463
+ });
464
+ }
465
+ const isAppendTitle = (global_append, local_append) => {
466
+ if (typeof local_append === "boolean")
467
+ return local_append;
468
+ return !!global_append;
469
+ };
470
+ const saveContentToFile = (content) => {
471
+ var _a2;
472
+ let title = entities__namespace.encodeXML(content.title || "");
473
+ let html = `${epubData.docHeader}
474
+ <head>
475
+ <meta charset="UTF-8" />
476
+ <title>${title}</title>
477
+ <link rel="stylesheet" type="text/css" href="style.css" />
478
+ </head>
479
+ <body>
480
+ `;
481
+ if (content.title && isAppendTitle(epubData.appendChapterTitles, content.appendChapterTitle)) {
482
+ html += `<h1>${title}</h1>`;
483
+ }
484
+ html += content.title && content.author && ((_a2 = content.author) == null ? void 0 : _a2.length) ? `<p class='epub-author'>${entities__namespace.encodeXML(content.author.join(", "))}</p>` : "";
485
+ html += content.title && content.url ? `<p class="epub-link"><a href="${content.url}">${content.url}</a></p>` : "";
486
+ html += `${content.data}`;
487
+ html += "\n</body>\n</html>";
488
+ fs__namespace$1.ensureDirSync(path__namespace.dirname(content.filePath));
489
+ fs__namespace$1.writeFileSync(content.filePath, html, "utf-8");
490
+ if (Array.isArray(content.children)) {
491
+ content.children.map(saveContentToFile);
492
+ }
493
+ };
494
+ epubData.content.map(saveContentToFile);
495
+ let metainf_dir = path__namespace.join(epubData.dir, "META-INF");
496
+ fs__namespace$1.ensureDirSync(metainf_dir);
497
+ fs__namespace$1.writeFileSync(
498
+ path__namespace.join(metainf_dir, "container.xml"),
499
+ `<?xml version="1.0" encoding="UTF-8" ?>
500
+ <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
501
+ <rootfiles><rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/></rootfiles>
502
+ </container>`,
503
+ "utf-8"
504
+ );
505
+ if (epubData.version === 2) {
506
+ let fn = path__namespace.join(metainf_dir, "com.apple.ibooks.display-options.xml");
507
+ fs__namespace$1.writeFileSync(
508
+ fn,
509
+ `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
510
+ <display_options>
511
+ <platform name="*">
512
+ <option name="specified-fonts">true</option>
513
+ </platform>
514
+ </display_options>
515
+ `,
516
+ "utf-8"
517
+ );
518
+ }
519
+ let opfPath = epubData.customOpfTemplatePath || path__namespace.join(templates_dir, `epub${epubData.version}`, "content.opf.ejs");
520
+ if (!fs__namespace$1.existsSync(opfPath)) {
521
+ throw new Error("Custom file to OPF template not found.");
522
+ }
523
+ let ncxTocPath = epubData.customNcxTocTemplatePath || path__namespace.join(templates_dir, `toc.ncx.ejs`);
524
+ if (!fs__namespace$1.existsSync(ncxTocPath)) {
525
+ throw new Error("Custom file the NCX toc template not found.");
526
+ }
527
+ let htmlTocPath = epubData.customHtmlTocTemplatePath || path__namespace.join(templates_dir, `epub${epubData.version}`, "toc.xhtml.ejs");
528
+ if (!fs__namespace$1.existsSync(htmlTocPath)) {
529
+ throw new Error("Custom file to HTML toc template not found.");
530
+ }
531
+ let toc_depth = 1;
532
+ fs__namespace$1.writeFileSync(
533
+ path__namespace.join(oebps_dir, "content.opf"),
534
+ await ejs__namespace.renderFile(opfPath, epubData),
535
+ "utf-8"
536
+ );
537
+ fs__namespace$1.writeFileSync(
538
+ path__namespace.join(oebps_dir, "toc.ncx"),
539
+ await ejs__namespace.renderFile(ncxTocPath, { ...epubData, toc_depth }),
540
+ "utf-8"
541
+ );
542
+ fs__namespace$1.writeFileSync(
543
+ path__namespace.join(oebps_dir, "toc.xhtml"),
544
+ simpleMinifier(await ejs__namespace.renderFile(htmlTocPath, epubData)),
545
+ "utf-8"
546
+ );
547
+ };
548
+ async function makeCover(data) {
549
+ let { cover, _coverExtension, log } = data;
550
+ if (!cover)
551
+ return;
552
+ let destPath = path__namespace.join(data.dir, "OEBPS", `cover.${_coverExtension}`);
553
+ let writeStream = null;
554
+ if (cover.startsWith("http")) {
555
+ writeStream = request__namespace.get(cover).set({ "User-Agent": USER_AGENT });
556
+ writeStream.pipe(fs__namespace$1.createWriteStream(destPath));
557
+ } else {
558
+ if (!fs__namespace$1.existsSync(cover))
559
+ return;
560
+ log("local cover image: " + cover);
561
+ writeStream = fs__namespace$1.createReadStream(cover);
562
+ writeStream.pipe(fs__namespace$1.createWriteStream(destPath));
563
+ }
564
+ return new Promise((resolve) => {
565
+ writeStream.on("end", () => {
566
+ log("[Success] cover image saved.");
567
+ resolve();
568
+ });
569
+ writeStream.on("error", (e) => {
570
+ log("[Error] cover image error: " + e.message);
571
+ log("destPath: " + destPath);
572
+ if (fs__namespace$1.existsSync(destPath)) {
573
+ try {
574
+ fs__namespace$1.unlinkSync(destPath);
575
+ log("destPath removed.");
576
+ } catch (e2) {
577
+ log("[Error] remove cover image error: " + e2.message);
578
+ }
579
+ }
580
+ resolve(e);
581
+ });
582
+ });
583
+ }
584
+ async function render(data) {
585
+ let { log } = data;
586
+ log("Generating Template Files...");
587
+ await generateTempFile(data);
588
+ log("Downloading Images...");
589
+ await downloadAllImages(data);
590
+ log("Making Cover...");
591
+ await makeCover(data);
592
+ log("Generating Epub Files...");
593
+ await genEpub(data);
594
+ if (fs$1.existsSync(data.output)) {
595
+ log("Output: " + data.output);
596
+ log("Done.");
597
+ } else {
598
+ log("Output fail!");
599
+ }
600
+ }
601
+ async function genEpub(epubData) {
602
+ let { log, dir, output } = epubData;
603
+ let archive = archiver("zip", { zlib: { level: 9 } });
604
+ let outputStream = fs$1.createWriteStream(epubData.output);
605
+ log("Zipping temp dir to " + output);
606
+ return new Promise((resolve, reject) => {
607
+ archive.on("end", async () => {
608
+ log("Done zipping, clearing temp dir...");
609
+ let stable = await fileIsStable(epubData.output);
610
+ if (!stable) {
611
+ log("Output epub file is not stable!");
612
+ }
613
+ try {
614
+ fs$1.removeSync(dir);
615
+ resolve();
616
+ } catch (e) {
617
+ log("[Error] " + e.message);
618
+ reject(e);
619
+ }
620
+ });
621
+ archive.on("close", () => {
622
+ log("Zip close..");
623
+ });
624
+ archive.on("finish", () => {
625
+ log("Zip finish..");
626
+ });
627
+ archive.on("error", (err) => {
628
+ log("[Archive Error] " + err.message);
629
+ reject(err);
630
+ });
631
+ archive.pipe(outputStream);
632
+ archive.append("application/epub+zip", { store: true, name: "mimetype" });
633
+ archive.directory(path.join(dir, "META-INF"), "META-INF");
634
+ archive.directory(path.join(dir, "OEBPS"), "OEBPS");
635
+ archive.finalize();
636
+ });
637
+ }
638
+ const baseDir = path__namespace.dirname(__dirname);
639
+ function result(success, message, options) {
640
+ if (options && options.verbose) {
641
+ if (!success) {
642
+ console.error(new Error(message));
52
643
  }
53
- return result(true, undefined, options);
644
+ }
645
+ let out = {
646
+ success
647
+ };
648
+ if (typeof message === "string") {
649
+ out.message = message;
650
+ }
651
+ if (options) {
652
+ out.options = options;
653
+ }
654
+ return out;
655
+ }
656
+ function check(options) {
657
+ if (!options.output) {
658
+ return result(false, errors.no_output_path, options);
659
+ }
660
+ if (!options.title) {
661
+ return result(false, errors.no_title, options);
662
+ }
663
+ if (!options.content) {
664
+ return result(false, errors.no_content, options);
665
+ }
666
+ return result(true, void 0, options);
54
667
  }
55
668
  function parseOptions(options) {
56
- let tmpDir = options.tmpDir || os.tmpdir();
57
- let id = (0, uuid_1.v4)();
58
- let data = Object.assign(Object.assign({ description: options.title, publisher: 'anonymous', author: ['anonymous'], tocTitle: 'Table Of Contents', appendChapterTitles: true, date: new Date().toISOString(), lang: 'en', fonts: [], version: 3, verbose: true, timeoutSeconds: 15 * 60, tocAutoNumber: false }, options), { id,
59
- tmpDir, dir: path.resolve(tmpDir, id), baseDir, docHeader: '', images: [], content: [], log: (msg) => options.verbose && console.log(msg) });
60
- if (data.version === 2) {
61
- data.docHeader = `<?xml version="1.0" encoding="UTF-8"?>
669
+ let tmpDir = options.tmpDir || os__namespace.tmpdir();
670
+ let id = uuid.v4();
671
+ let data = {
672
+ description: options.title,
673
+ publisher: "anonymous",
674
+ author: ["anonymous"],
675
+ tocTitle: "Table Of Contents",
676
+ appendChapterTitles: true,
677
+ date: new Date().toISOString(),
678
+ lang: "en",
679
+ fonts: [],
680
+ version: 3,
681
+ verbose: true,
682
+ timeoutSeconds: 15 * 60,
683
+ tocAutoNumber: false,
684
+ ...options,
685
+ id,
686
+ tmpDir,
687
+ dir: path__namespace.resolve(tmpDir, id),
688
+ baseDir,
689
+ docHeader: "",
690
+ images: [],
691
+ content: [],
692
+ log: (msg) => options.verbose && console.log(msg)
693
+ };
694
+ if (data.version === 2) {
695
+ data.docHeader = `<?xml version="1.0" encoding="UTF-8"?>
62
696
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
63
697
  <html xmlns="http://www.w3.org/1999/xhtml" lang="#{self.options.lang}">
64
698
  `;
65
- }
66
- else {
67
- data.docHeader = `<?xml version="1.0" encoding="UTF-8"?>
699
+ } else {
700
+ data.docHeader = `<?xml version="1.0" encoding="UTF-8"?>
68
701
  <!DOCTYPE html>
69
702
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="#{self.options.lang}">
70
703
  `;
71
- }
72
- if (Array.isArray(data.author) && data.author.length === 0) {
73
- data.author = ['anonymous'];
74
- }
75
- if (typeof data.author === 'string') {
76
- data.author = [data.author];
77
- }
78
- data.content = options.content.map((content, index) => (0, parseContent_1.default)(content, index, data));
79
- if (data.cover) {
80
- data._coverMediaType = mime.getType(data.cover) || '';
81
- data._coverExtension = mime.getExtension(data._coverMediaType) || '';
82
- }
83
- return data;
704
+ }
705
+ if (Array.isArray(data.author) && data.author.length === 0) {
706
+ data.author = ["anonymous"];
707
+ }
708
+ if (typeof data.author === "string") {
709
+ data.author = [data.author];
710
+ }
711
+ data.content = options.content.map((content, index) => parseContent(content, index, data));
712
+ if (data.cover) {
713
+ data._coverMediaType = mime__namespace.getType(data.cover) || "";
714
+ data._coverExtension = mime__namespace.getExtension(data._coverMediaType) || "";
715
+ }
716
+ return data;
84
717
  }
85
- function epubGen(options, output) {
86
- return __awaiter(this, void 0, void 0, function* () {
87
- options = Object.assign({}, options);
88
- if (output) {
89
- options.output = output;
90
- }
91
- let o = check(options);
92
- let verbose = options.verbose !== false;
93
- if (!o.success) {
94
- if (verbose)
95
- console.error(o.message);
96
- return o;
97
- }
98
- let t;
99
- try {
100
- let data = parseOptions(options);
101
- let timeoutSeconds = data.timeoutSeconds || 0;
102
- if (timeoutSeconds > 0) {
103
- if (verbose)
104
- console.log(`TIMEOUT: ${timeoutSeconds}s`);
105
- t = setTimeout(() => {
106
- throw new Error('timeout!');
107
- }, timeoutSeconds * 1000);
108
- }
109
- else {
110
- if (verbose)
111
- console.log(`TIMEOUT: N/A`);
112
- }
113
- yield (0, render_1.render)(data);
114
- return result(true, undefined, data);
115
- }
116
- catch (e) {
117
- if (verbose)
118
- console.error(e);
119
- return result(false, e.message, options);
120
- }
121
- finally {
122
- clearTimeout(t);
123
- }
124
- });
718
+ async function epubGen(options, output) {
719
+ options = { ...options };
720
+ if (output) {
721
+ options.output = output;
722
+ }
723
+ let o = check(options);
724
+ let verbose = options.verbose !== false;
725
+ if (!o.success) {
726
+ if (verbose)
727
+ console.error(o.message);
728
+ return o;
729
+ }
730
+ let t;
731
+ try {
732
+ let data = parseOptions(options);
733
+ let timeoutSeconds = data.timeoutSeconds || 0;
734
+ if (timeoutSeconds > 0) {
735
+ if (verbose)
736
+ console.log(`TIMEOUT: ${timeoutSeconds}s`);
737
+ t = setTimeout(() => {
738
+ throw new Error("timeout!");
739
+ }, timeoutSeconds * 1e3);
740
+ } else {
741
+ if (verbose)
742
+ console.log(`TIMEOUT: N/A`);
743
+ }
744
+ await render(data);
745
+ return result(true, void 0, data);
746
+ } catch (e) {
747
+ if (verbose)
748
+ console.error(e);
749
+ return result(false, e.message, options);
750
+ } finally {
751
+ clearTimeout(t);
752
+ }
125
753
  }
754
+ const gen = epubGen;
126
755
  exports.epubGen = epubGen;
127
- exports.gen = epubGen;
128
- //# sourceMappingURL=index.js.map
756
+ exports.errors = errors;
757
+ exports.gen = gen;