packdir-cli
Version:
Packdir CLI
151 lines • 7.43 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EPub = exports.chapterDefaults = exports.optionsDefaults = void 0;
const tslib_1 = require("tslib");
const ejs_1 = require("ejs");
const jszip_1 = tslib_1.__importDefault(require("jszip"));
const mime_1 = require("mime");
const ow_1 = tslib_1.__importDefault(require("ow"));
const util_1 = require("./util");
Object.defineProperty(exports, "chapterDefaults", { enumerable: true, get: function () { return util_1.chapterDefaults; } });
Object.defineProperty(exports, "optionsDefaults", { enumerable: true, get: function () { return util_1.optionsDefaults; } });
class EPub {
constructor(options, content) {
this.images = [];
this.options = (0, util_1.validateAndNormalizeOptions)(options);
switch (this.options.verbose) {
case true:
this.log = console.log.bind(console);
this.warn = console.warn.bind(console);
break;
case false:
this.log = this.warn = () => { };
break;
default:
this.log = this.options.verbose.bind(null, 'log');
this.warn = this.options.verbose.bind(null, 'warn');
break;
}
this.uuid = (0, util_1.uuid)();
this.content = util_1.validateAndNormalizeChapters.call(this, content);
this.zip = new jszip_1.default();
this.zip.file('mimetype', 'application/epub+zip', { compression: 'STORE' });
if (this.options.cover) {
const mediaType = (0, mime_1.getType)(this.options.cover);
const extension = (0, mime_1.getExtension)(mediaType || '');
if (mediaType && extension)
this.cover = { mediaType, extension };
}
}
async render() {
this.log('Generating Template Files...');
await this.generateTemplateFiles();
this.log('Downloading fonts...');
//await this.downloadAllFonts();
this.log('Downloading images...');
await this.downloadAllImages();
this.log('Making cover...');
await this.makeCover();
this.log('Finishing up...');
return this;
}
async genEpub() {
await this.render();
const content = this.zip.generateAsync({
type: util_1.type,
mimeType: 'application/epub+zip',
compression: 'DEFLATE',
compressionOptions: {
level: 9,
},
});
this.log('Done');
return content;
}
generateAsync(options) {
return this.zip.generateAsync(options);
}
async generateTemplateFiles() {
const oebps = this.zip.folder('OEBPS');
oebps.file('style.css', this.options.css);
this.content.forEach(chapter => {
const rendered = (0, ejs_1.render)(this.options.chapterXHTML, {
lang: this.options.lang,
prependChapterTitles: this.options.prependChapterTitles,
...chapter,
});
oebps.file(chapter.filename, rendered);
});
const metainf = this.zip.folder('META-INF');
metainf.file('container.xml', '<?xml version="1.0" encoding="UTF-8" ?><container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles><rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/></rootfiles></container>');
if (this.options.version === 2) {
// write meta-inf/com.apple.ibooks.display-options.xml [from pedrosanta:xhtml#6]
metainf.file('com.apple.ibooks.display-options.xml', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><display_options><platform name="*"><option name="specified-fonts">true</option></platform></display_options>');
}
const opt = {
...this.options,
id: this.uuid,
images: this.images,
cover: this.cover,
content: this.content,
};
oebps.file('content.opf', (0, ejs_1.render)(this.options.contentOPF, opt));
oebps.file('toc.ncx', (0, ejs_1.render)(this.options.tocNCX, opt));
oebps.file('toc.xhtml', (0, ejs_1.render)(this.options.tocXHTML, opt));
}
async downloadAllFonts() {
if (!this.options.fonts.length)
return this.log('No fonts to download');
const oebps = this.zip.folder('OEBPS');
const fonts = oebps.folder('fonts');
for (let i = 0; i < this.options.fonts.length; i += this.options.batchSize) {
const fontContents = await Promise.all(this.options.fonts.slice(i, i + this.options.batchSize).map(font => {
const d = (0, util_1.retryFetch)(font.url, this.options.fetchTimeout, this.options.retryTimes, this.log)
.then(res => (this.log(`Downloaded font ${font.url}`), { ...font, data: res }));
return this.options.ignoreFailedDownloads
? d.catch(reason => (this.warn(`Warning (font ${font.url}): Download failed`, reason), { ...font, data: '' }))
: d;
}));
fontContents.forEach(font => fonts.file(font.filename, font.data));
}
}
async downloadAllImages() {
if (!this.images.length)
return this.log('No images to download');
const oebps = this.zip.folder('OEBPS');
const images = oebps.folder('images');
for (let i = 0; i < this.images.length; i += this.options.batchSize) {
const imageContents = await Promise.all(this.images.slice(i, i + this.options.batchSize).map(image => {
const d = (0, util_1.retryFetch)(image.url, this.options.fetchTimeout, this.options.retryTimes, this.log)
.then(res => (this.log(`Downloaded image ${image.url}`), { ...image, data: res }));
return this.options.ignoreFailedDownloads
? d.catch(reason => (this.warn(`Warning (image ${image.url}): Download failed`, reason), { ...image, data: '' }))
: d;
}));
imageContents.forEach(image => images.file(`${image.id}.${image.extension}`, image.data));
}
}
async makeCover() {
if (!this.cover)
return this.log('No cover to download');
const oebps = this.zip.folder('OEBPS');
const coverContent = await (0, util_1.retryFetch)(this.options.cover, this.options.fetchTimeout, this.options.retryTimes, this.log)
.catch(reason => (this.warn(`Warning (cover ${this.options.cover}): Download failed`, reason), ''));
oebps.file(`cover.${this.cover.extension}`, coverContent);
}
}
exports.EPub = EPub;
const epub = (optionsOrTitle, content, ...args) => {
(0, ow_1.default)(optionsOrTitle, ow_1.default.any(util_1.optionsPredicate, ow_1.default.string));
const options = ow_1.default.isValid(optionsOrTitle, ow_1.default.string) ? { title: optionsOrTitle } : optionsOrTitle;
(0, ow_1.default)(args, ow_1.default.array.ofType(ow_1.default.any(ow_1.default.boolean, ow_1.default.number)));
args.forEach(arg => {
if (ow_1.default.isValid(arg, ow_1.default.boolean))
options.verbose = arg;
else
options.version = arg;
});
return new EPub(options, content).genEpub();
};
exports.default = epub;
//# sourceMappingURL=index.js.map