Compare commits

...

5 Commits

Author SHA1 Message Date
Hippo 8926493a2b Make CSS styles more ereader-friendly
Using tricks from https://friendsofepub.github.io/eBookTricks/
although they don't seem to really work; at least the small caps
aren't becoming small caps :/
2021-04-13 21:17:47 +05:30
Hippo 98ac5a8884 Lowercase titles while rendering
CSS lowercasing doesn't work in ereaders, so we have to do it
manually
2021-04-13 20:58:46 +05:30
Hippo 1ddc5f4e7c Add fonts and styling for articles
Note: Due to nodepub limitations, the fonts are only named, but
not actually embedded. To embed them, you'll have to do something
roundabout like opening the ePub in the Calibre ePub Editor and
embedding them from there. Hopefully this will get resolved at
some point :/
2021-04-03 22:02:21 +05:30
Hippo d475a5bde9 ePub: download and insert article images before rendering
This includes the feature image as well as other inline images.
2021-04-03 22:01:02 +05:30
Hippo d5fd82e421 Allow basic Ghost -> ePub collation!
This doesn't include images and stuff, but hey, at least we've
got the basics covered!
2021-04-02 20:59:22 +05:30
5 changed files with 512 additions and 4 deletions

17
cli.js
View File

@ -187,6 +187,23 @@ program.command('webdav-test <file>')
new seance.uploadDav(dir_path, file);
});
program.command('fetch-epub [postSlugs...]')
.description('fetch posts from Ghost and collate them into a ePub')
.option('-t, --title <title>', 'title of the final book')
.option('-a, --author <author>', 'author of the book')
.option('-g, --genre <genre>', 'genre of the book', 'Unknown')
.option('-c, --cover-image <file>', 'what to use as the epub cover')
.option('-O, --output-folder <path>', 'where to output the file', '.')
.action(async (postSlug, o) => {
await seance.fetchToEpub(postSlug, {
title: o.title,
author: o.author,
genre: o.genre,
coverImage: o.coverImage,
outputFolder: o.outputFolder,
})
})
program.command('check-scissors <file>')
.description('[test command] check if an image matches the set separator')
.action(async (file) => {

View File

@ -20,6 +20,7 @@
"babel-preset-env": "^1.7.0",
"body-parser": "^1.19.0",
"bulma": "^0.8.2",
"cheerio": "^1.0.0-rc.5",
"commander": "^3.0.2",
"convict": "^5.2.0",
"css-loader": "^3.5.3",
@ -31,6 +32,7 @@
"mediumexporter": "github:badrihippo/mediumexporter#seance-latest",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1",
"nodepub": "^3.0.1",
"postcss-loader": "^3.0.0",
"prompt-async": "^0.9.9",
"r2": "^2.0.1",

BIN
random-cover.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

198
seance.js
View File

@ -9,7 +9,10 @@ const readline = require('readline')
const { markdown } = require('markdown')
const GhostAdminAPI = require('@tryghost/admin-api')
const { Canvas, Image } = require('canvas')
const slugify = require('underscore.string/slugify')
const Rembrandt = require('rembrandt')
const nodepub = require('nodepub')
const cheerio = require('cheerio')
const config = require('./config')
@ -116,7 +119,7 @@ class Seance {
* @param {Boolean} options.noUpload Skip uploading of images
* @param {Boolean} options.noPush Skip pushing to Ghost; just generate the file
* @param {Boolean} options.dryRun Combination of noUpload and noPush
* @returns [string] status
* @returns [object] object containing details of the uploaded Ghost post
*/
async pushToGhost (postSlug, options={}) {
this.emit('update', {
@ -710,6 +713,199 @@ class Seance {
return true
}
/**
* function [fetchToEpub]
* @description fetches posts from Ghost and packs them into an epub
* @options.id unique ID for the generated epub
* @options.title title of the generated epub
* @options.author author of the generated epub
* @options.language language of the book
* @genre genre of the book
* @cover cover image to use
* @returns [string] status
*/
async fetchToEpub (postSlugs, options = {}) {
if (!options.title) options.title = 'Seance Collection'
if (!options.author) options.author = 'Seance'
if (!options.language) options.language = 'en'
if (!options.genre) options.genre = 'Unknown'
if (!options.coverImage) options.coverImage = 'random-cover.jpg'
if (!options.outputFolder) options.outputFolder = '.'
console.log(`Fetching: ${postSlugs}`)
let allPosts = []
// first, fetch all the posts
for (let slug of postSlugs) {
console.log(`Fetching: ${slug}`)
let post = await this.ghostAdmin.posts.read({slug: slug}, {formats: ['html']})
allPosts.push(post)
}
// prepare for image downloads, starting with the scissors!
let pics = [path.join(__dirname, 'scissors.png')]
let picFolder = path.join(options.outputFolder, 'seance-images')
if (!fs.existsSync(picFolder)) {
fs.mkdirSync(picFolder, { recursive: true })
}
// prepare array to collect processed posts
let processedPosts = []
for (let post of allPosts) {
// decide a post slug, for future files
let postSlug = slugify(post.title)
// get the cover pic
let featurePicTag
if (!!post.feature_image) {
let imgUrl = post.feature_image
if (/^\/\//i.test(imgUrl)) {
imgUrl = 'https:' + imgUrl
} else if (!/^https?:\/\//i.test(imgUrl)) {
imgUrl = 'https://' + imgUrl
}
let response = await (await r2.get(imgUrl).response).buffer()
let ext = post.feature_image.split('.').pop()
await await fs.promises.writeFile(path.join(picFolder, `${postSlug}.${ext}`), response, 'base64')
featurePicTag = `<img src="../images/${postSlug}.${ext}"/>`
pics.push(`${picFolder}/${postSlug}.${ext}`)
}
let c = cheerio.load(`${featurePicTag}<h1>${post.title.toLowerCase()}</h1>${post.html}`)
// hunt for other pics
// TODO: make asynchronous
let picCounter = 0
c('img').each(async function() {
// skip if it's a local image
if (c(this).attr('src').indexOf('../images') == 0) {
return
}
// first, process the url
let imgUrl = c(this).attr('src')
console.log('Downloading:', imgUrl)
if (/^\/\//i.test(imgUrl)) {
imgUrl = 'https:' + imgUrl
} else if (!/^https?:\/\//i.test(imgUrl)) {
imgUrl = 'https://' + imgUrl
}
// now decide an output name
let ext = c(this).attr('src').split('.').pop()
let imageFile = path.join(picFolder, `${postSlug}-insert-${picCounter}.${ext}`)
// note down our calculations
c(this).attr('src', `../images/${postSlug}-insert-${picCounter}.${ext}`)
pics.push(imageFile)
picCounter = picCounter + 1
// finally, download the images
let response = await (await r2.get(imgUrl).response).buffer()
await fs.promises.writeFile(imageFile, response, 'base64')
console.log('Downloaded to:', imageFile)
})
processedPosts.push({
title: post.title,
body: c.html(),
})
}
// decide metadata
let metadata = {
id: 'seance-test', // FIXME
title: options.title,
author: options.author,
language: options.language,
contents: 'Table of Contents',
genre: options.genre,
cover: options.coverImage,
images: pics,
}
// create the ePub
let epub = nodepub.document(metadata)
// add the documents
for (let post of processedPosts) {
epub.addSection(post.title, post.body)
}
// add the styles
epub.addCSS(`
img {
width: 100%;
height: auto;
object-fit: contain;
}
h1 {
font-family: "Abhaya Libre Extrabold";
text-transform: lowercase;
text-align: center;
font-size: 2em;
line-height: 1em;
margin-bottom: 0;
}
h1 + h2 {
font-family: "Open Sans Light";
font-variant: small-caps;
text-align: center;
font-size: 1.2em;
line-height: 1em;
margin-bottom: 1.2em;
}
@supports not (font-variant-caps: small-caps) {
h1 + h2 {
font-variant: normal;
font-feature-settings: "smcp", "onum", "pnum";
}
}
@supports (font-variant-caps: small-caps) {
h1 + h2 {
font-variant: normal;
font-variant-caps: small-caps;
}
}
p {
font-family: "Crimson Text Regular";
font-size: 1em;
line-height: 1.2em;
}
hr {
display: block;
border: 0px;
height: 1em;
background-image:url('../images/scissors.png');
background-size: contain;
background-repeat: no-repeat;
background-position: 50%;
margin-top: 1.5em;
margin-bottom: 1.5em;
page-break-inside: avoid;
break-inside: avoid;
}
@supports not ((page-break-inside: avoid) and (break-inside: avoid)) {
hr {
-webkit-column-break-inside: avoid;
}
}
`)
// generate it!
await epub.writeEPUB(options.outputFolder, options.title)
}
}
// Make Seance an EventEmitter

299
yarn.lock
View File

@ -299,6 +299,35 @@ aproba@^1.0.3, aproba@^1.1.1:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
archiver-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2"
integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==
dependencies:
glob "^7.1.4"
graceful-fs "^4.2.0"
lazystream "^1.0.0"
lodash.defaults "^4.2.0"
lodash.difference "^4.5.0"
lodash.flatten "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.union "^4.6.0"
normalize-path "^3.0.0"
readable-stream "^2.0.0"
archiver@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.0.tgz#dd3e097624481741df626267564f7dd8640a45ba"
integrity sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==
dependencies:
archiver-utils "^2.1.0"
async "^3.2.0"
buffer-crc32 "^0.2.1"
readable-stream "^3.6.0"
readdir-glob "^1.0.0"
tar-stream "^2.2.0"
zip-stream "^4.1.0"
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@ -400,6 +429,11 @@ async@^2.3.0:
dependencies:
lodash "^4.17.14"
async@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
async@~0.9.0:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
@ -1025,6 +1059,11 @@ base64-js@^1.0.2:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@ -1062,6 +1101,15 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
block-stream@*:
version "0.0.9"
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
@ -1095,6 +1143,11 @@ body-parser@1.19.0, body-parser@^1.19.0:
raw-body "2.4.0"
type-is "~1.6.17"
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@ -1207,6 +1260,11 @@ browserslist@^3.2.6:
caniuse-lite "^1.0.30000844"
electron-to-chromium "^1.3.47"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
@ -1231,6 +1289,14 @@ buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@ -1383,6 +1449,30 @@ chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
cheerio-select-tmp@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646"
integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==
dependencies:
css-select "^3.1.2"
css-what "^4.0.0"
domelementtype "^2.1.0"
domhandler "^4.0.0"
domutils "^2.4.4"
cheerio@^1.0.0-rc.5:
version "1.0.0-rc.5"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f"
integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==
dependencies:
cheerio-select-tmp "^0.1.0"
dom-serializer "~1.2.0"
domhandler "^4.0.0"
entities "~2.1.0"
htmlparser2 "^6.0.0"
parse5 "^6.0.0"
parse5-htmlparser2-tree-adapter "^6.0.0"
chokidar@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
@ -1605,6 +1695,16 @@ component-emitter@^1.2.1:
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
compress-commons@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.0.tgz#25ec7a4528852ccd1d441a7d4353cd0ece11371b"
integrity sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==
dependencies:
buffer-crc32 "^0.2.13"
crc32-stream "^4.0.1"
normalize-path "^3.0.0"
readable-stream "^3.6.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -1719,6 +1819,22 @@ cosmiconfig@^5.0.0:
js-yaml "^3.13.1"
parse-json "^4.0.0"
crc-32@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
dependencies:
exit-on-epipe "~1.0.1"
printj "~1.1.0"
crc32-stream@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007"
integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==
dependencies:
crc-32 "^1.2.0"
readable-stream "^3.4.0"
create-ecdh@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
@ -1829,6 +1945,17 @@ css-loader@^3.5.3:
schema-utils "^2.6.6"
semver "^6.3.0"
css-select@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8"
integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==
dependencies:
boolbase "^1.0.0"
css-what "^4.0.0"
domhandler "^4.0.0"
domutils "^2.4.3"
nth-check "^2.0.0"
css-selector-tokenizer@^0.7.0:
version "0.7.2"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz#11e5e27c9a48d90284f22d45061c303d7a25ad87"
@ -1843,6 +1970,11 @@ css-unit-converter@^1.1.1:
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996"
integrity sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=
css-what@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233"
integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@ -2059,11 +2191,41 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
dom-serializer@^1.0.1, dom-serializer@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.0.0"
entities "^2.0.0"
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
domelementtype@^2.0.1, domelementtype@^2.1.0, domelementtype@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
domhandler@^4.0.0, domhandler@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43"
integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ==
dependencies:
domelementtype "^2.2.0"
domutils@^2.4.3, domutils@^2.4.4:
version "2.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.1.tgz#9b8e84b5d9f788499ae77506ea832e9b4f9aa1c0"
integrity sha512-hO1XwHMGAthA/1KL7c83oip/6UWo3FlUNIuWiWKltoiQ5oCOiqths8KknvY2jpOohUoUgnwa/+Rm7UpwpSbY/Q==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
domhandler "^4.1.0"
dotenv@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
@ -2132,7 +2294,7 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@ -2153,6 +2315,16 @@ entities@^1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
entities@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@ -2255,6 +2427,11 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
exit-on-epipe@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
expand-brackets@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@ -2533,6 +2710,11 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-minipass@^1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
@ -2660,6 +2842,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
graceful-fs@^4.2.0:
version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@ -2797,6 +2984,16 @@ html-comment-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7"
integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==
htmlparser2@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446"
integrity sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.0.0"
domutils "^2.4.4"
entities "^2.0.0"
http-errors@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
@ -2864,6 +3061,11 @@ icss-utils@^4.0.0, icss-utils@^4.1.1:
dependencies:
postcss "^7.0.14"
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
@ -3355,6 +3557,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
lazystream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=
dependencies:
readable-stream "^2.0.5"
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@ -3411,6 +3620,21 @@ lodash.clonedeep@4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.difference@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@ -3471,6 +3695,11 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"
lodash.union@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@ -3807,6 +4036,11 @@ moment@2.24.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
moment@^2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@ -3986,6 +4220,14 @@ node-version@^1.1.3:
resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d"
integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==
nodepub@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/nodepub/-/nodepub-3.0.1.tgz#345a687f28c1852332087329fbc3aac40a049d4c"
integrity sha512-aS38l5pCHKeDajiNoZyiLcJIDnZYfFfmpGLtgYUJ4K22wChVX7gvA86dK5XWjPdj1Em7VSIiQNQzwjxmra0xlg==
dependencies:
archiver "^5.2.0"
moment "^2.29.1"
"nopt@2 || 3":
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
@ -4075,6 +4317,13 @@ npm-packlist@^1.1.6:
gauge "~2.7.3"
set-blocking "~2.0.0"
nth-check@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125"
integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==
dependencies:
boolbase "^1.0.0"
null-loader@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-0.1.1.tgz#17be9abfcd3ff0e1512f6fc4afcb1f5039378fae"
@ -4262,6 +4511,18 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
parse5-htmlparser2-tree-adapter@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
dependencies:
parse5 "^6.0.1"
parse5@^6.0.0, parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@ -5031,6 +5292,11 @@ prettier@^1.18.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
printj@~1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
private@^0.1.6, private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@ -5256,7 +5522,7 @@ read@1.0.x:
dependencies:
mute-stream "~0.0.4"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -5282,7 +5548,7 @@ readable-stream@^2.0.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.6.0:
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@ -5291,6 +5557,13 @@ readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readdir-glob@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.1.tgz#f0e10bb7bf7bfa7e0add8baffdc54c3f7dbee6c4"
integrity sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==
dependencies:
minimatch "^3.0.4"
readdirp@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
@ -6141,6 +6414,17 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar-stream@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^2.0.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40"
@ -6824,3 +7108,12 @@ yargs@^13.3.2:
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.2"
zip-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79"
integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==
dependencies:
archiver-utils "^2.1.0"
compress-commons "^4.1.0"
readable-stream "^3.6.0"